0

楽しみのために、次のコード スニペットを用意しました。

#include <stdio.h>
main()
{
 int i;
 int a;
 i = 17;
 //scanf("%d", &i);
 a = (i+=5) * (i-=3);
 printf("a is %d, i is %d\n", a, i);
}

C 仕様では、オペランド評価の順序がundefinedと書かれているため、22 * 19 または 19 * 14 のいずれかが表示されると予想していました。しかし、結果は 19 * 19 です。

~ $ gcc a.c
~ $ ./a.out
a is 361, i is 19

私が思いついた唯一の説明は、コンパイラが の値に対して「遅延」評価を行い、の値は単に i の値である(i+=5)と考えたということです。(i+=5)についても同じです(i-=3)

ただし、次のコメントを外すとscanf():

#include <stdio.h>
main()
{
 int i;
 int a;
 i = 17;
 scanf("%d", &i);
 a = (i+=5) * (i-=3);
 printf("a is %d, i is %d\n", a, i);
}

プロンプトで 17 を入力します。

~ $ gcc a.c
~ $ ./a.out
17
a is 418, i is 19

異なる動作を示すのはなぜですか?

4

2 に答える 2

5

それは未定義の動作です。iC 標準では、2 つのシーケンス ポイント (この場合はステートメントの前後のセミコロン) の間で同じオブジェクト (この場合) を複数回変更することは許可されていません。

未定義の動作とは、何でも起こり得ることを意味します。正しく動作しているように見える場合があります。それは間違った答えを与えることができます。プロセスがクラッシュする可能性があります。ハードドライブを消去できます。または、CPU に火をつけることさえできます。これらはすべて、言語標準に従って許可されている動作です。

于 2013-03-07T02:25:38.600 に答える