int main(){
int a[3]={1,10,20};
int *p=a;
printf("%d %d " ,*++p,*p);
return 0;
}
gccコンパイラでは、上記のコードへの出力は10 1です。printfの* ++ pの使用に疑問がある
私は* ++ pがpをインクリメントして新しい値を逆参照することを理解します。しかし、pがインクリメントされているので、なぜ* pは10ではなく1を返しますか?
int main(){
int a[3]={1,10,20};
int *p=a;
printf("%d %d " ,*++p,*p);
return 0;
}
gccコンパイラでは、上記のコードへの出力は10 1です。printfの* ++ pの使用に疑問がある
私は* ++ pがpをインクリメントして新しい値を逆参照することを理解します。しかし、pがインクリメントされているので、なぜ* pは10ではなく1を返しますか?
関数の引数式がどのような順序で評価されるかは不特定の動作です。いくつかのコンパイラは、左から右へ、右から左へ、そしていくつかは最適化のために状況に応じて異なる評価順序を使用するかもしれません。だからあなたのケースでは、は「奇妙な出力」をもたらす*++p
の前に評価されます。 *++p
と*p
カンマないはsequence pointを意味し、これは
未定義
不特定の動作です。コンパイラは、 を*p
と評価すると、*++p
の前に自由になります。
@Damon:動作は__not__未定義です。それは不特定です。 http://stackoverflow.com/questions/621542/compilers-and-argument-order-of-evaluation-in-c/621548#621548を参照してください。 – orlp
@jimルイス:私はcの初心者ですが、私の教師はC言語で表現が右から左に評価されると言いました。つまり、最初に* pが評価されます。 – Aravindhan
@ user618541:先生は間違っています。 1つのコンパイラでは、標準Cではそうではないかもしれません。 – orlp
未定義の動作で、異なるコンパイラで出力が異なる場合があります。
あなたの引数は逆順(最後まで)評価されていますので、*p
が最初に評価され、1
が返されます。
他の人が指摘しているように、標準では引数の評価順序が決まっていないため、この動作は他のコンパイラでも同じに見える場合もあります。
このコードには未定義の動作があります。 '* ++ p'が何を行うのかはっきりしていますが(最初のインクリメント、逆参照)、これまたは後続の' * p'が最初に評価されるかどうかは不明です。そのため、あなたのプログラムの出力はランダムなもの(またはより具体的にはコンパイラ固有)です。したがって、コードを「理解する」ことはできません。 – Damon
@Damon:動作は__not__が未定義です。それは不特定です。 http://stackoverflow.com/questions/621542/compilers-and-argument-order-of-evaluation-in-c/621548#621548を参照してください。 – orlp