5

私は周りを見回して式を見つけましa = (a + b) - (b = a)た.2つの変数(または場合によってはオブジェクト)を交換することになっています。ただし、C++ と php でテストしたところ、異なる結果が得られました。

php:

$a = 10;
$b = 20;
$a = ($a + $b) - ($b = $a);
echo $a, " ", $b;

これは印刷します20 10

C++

int a = 10;
int b = 20;
a = (a + b) - (b = a);
std::cout << a << " " << b;

これは印刷します10 10

コードは同じように見えますが、出力が異なります。私は 2 つの理由について考えてきました。

  1. C++ コードはコンパイル中で、php は解釈中です。
  2. この式は、未定義の動作につながるため役に立ちません。

この状況で C++ と php の出力が異なる理由を誰かが説明できますか?

4

3 に答える 3

14

PHP での規則がどのようなものかはわかりませんが、C++ では、個々の部分式の順序が厳密に定義されていないか、専門用語のように「未指定」です。つまり、コンパイラは許可されています。するb = a前後に計算しa + bます。限り、減算の前にa + bb = a「指定されていない」動作を使用すると、コンパイラは場合によってはより効率的なコードを生成できます。または、単に一部のアーキテクチャ用のコンパイラを構築することが可能です。

また、式自体に値を「再計算」する式があり、それを式の他の場所で使用すると、未定義の動作 (略して UB) が発生することも意味します。UB は、動作が定義されていないことを意味します-表示されているものや他の多くの代替手段を含め、ほとんどすべてが発生する可能性があります(たとえば、ロジックが答えがないと言っている場合でも、コンパイラーは結果として 42 を生成することも許可されています)この場合は 42 [これは間違った質問です!])。

PHP で 2 つの値を交換する場合は、次のようにすることもお勧めします。

 $t = $a;
 $a = $b;
 $b = $t;

および C++ の場合:

 #include <algorithm>

 std::swap(a, b); 

または、自分で書きたい場合:

 int t = a;
 a = b;
 b = t; 

賢く「一時変数なし」で実行しようとすると、ほぼ確実に一時変数を使用するよりも遅くなるでしょう - 確かに C++ のようなコンパイル言語では - PHP のようなインタープリター言語では、新しい変数を作成すると少し追加されるかもしれません余分なオーバーヘッドが発生しますが、必要なロジックでの余分な労力と比較すると、それほど大きくはありません。

于 2013-08-04T08:01:59.403 に答える
3

未定義の動作のため、 C++ コードは完全に壊れています。b( 1 つのシーケンス ポイントで読み取りと書き込みを行います)。

于 2013-08-04T08:17:08.977 に答える
2

PHP の場合:

$a = 10;
$b = 20;
$a = ($a + $b) - ($b = $a);
//executes like thus
$a = (30) - ($b = $a);
$a = (30) - ($b = $a = 10); //new $a still not computed, using older $a
$a = (30) - (10);
$a = 20;
//then, $a=20 and $b = 10

これはOperator Precedenceに完全に関連しています。これは C でも同じかもしれませんし、そうでないかもしれません。予期しない動作が発生しない場合は、優先順位に依存します。

于 2013-08-04T08:13:02.733 に答える