int x; float *p;
p = (float*)&x;
*p = 2.35;
printf("x:%f\n",x); //0.0000
printf("x:%d\n",x); //1075209830
printf("p:%f\n",*p); //2.350000
これはc未定義の動作になりますか?IntとFloatポインタ。誰かが出力を説明することができます
int x; float *p;
p = (float*)&x;
*p = 2.35;
printf("x:%f\n",x); //0.0000
printf("x:%d\n",x); //1075209830
printf("p:%f\n",*p); //2.350000
これはc未定義の動作になりますか?IntとFloatポインタ。誰かが出力を説明することができます
まあ、あなたはx
を指すアドレスと同様にp
を指している&x
を持っています。
次に、p
の値を変更します。 x
を指すように変更してください。逆参照すると、p
バイトがfloatとして解釈されます。 (おそらく)sizeof(int) != sizeof(float)
であっても、前にもそうでもなくても、いくつかのバイトが評価されることさえあります。
メモリにアクセスするので、C標準には定義がありません。 UB。
さらに、*p
に新しい浮動小数点値を割り当てて、このスペースに書いてもint
だったとします。
最初にprintf()
を評価するとき、コンパイラが混乱していることは驚くことではありません。とにかくUBです。
番目のステートメント少なくとも彼に非矛盾した指示を与える:(float
としてint
を解釈しようとしない)int
からint
を印刷します。
前にも触れたように、float
はint
に収まらない可能性があります。したがって、値はいつでも上書きされたり、SEGFAULTが発生する可能性があります。
はい、それはUBです。どのようなアウトプットを期待しましたか? –
2つの理由から、1)厳密なエイリアシングルールを壊してしまった。2) 'int'に間違った書式指定子'%f'を使う。 –
私は最初のprintfの説明が必要だと仮定しますが、コンパイラのモードとバージョンに依存する関数への引数の受け渡し方法によってまったく異なります。 vs2015が誤った引数が使用されたという警告を出すことさえあることに気付くかもしれません。 –