2011-01-30 4 views
0
#include <stdio.h> 

struct abc{ 
    int a; 
    int b; 
} xyz; 

int main() 
{ 
    xyz.a = 10; 
    xyz.b = 20; 
    printf("%d %d", xyz, xyz.a); 
} 

上記のプログラムの出力は10 20です。このCコードの出力について説明しますか?

私は

printf("%d %d %d", xyz, xyz.a, xyz.b); 

として別のprintfのステートメントを追加した場合、出力は10 20 10が来ます。

これはどのような説明ですか? printfへのコールスタックと(この場合)、その構造上全体構造xyzを推進しているためにです

+0

マインは '10 10'を返します。未定義の振る舞いに頼るのは良い考えではありません。 :) – sarnold

+9

@sarnold、あなたの返品は10 10です。あなたは幸運だった、私の妻、二人の子供、犬、そして私のメインマシンを飲み込んだミニチュアブラックホールを作りました。私はこのコメントを私の古い386クランカーに入力しなければならない。さあ、私はその犬が恋しくなるつもりです:-) – paxdiablo

+4

@paxdiabloあなたの犬についてお詫び申し上げます。 – sarnold

答えて

2

未定義の動作が呼び出されました。 結果は許可されます。

7.19.6.1 The fprintf function
...
9 If a conversion specification is invalid, the behavior is undefined. 248) If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

強調鉱山。 xyzのタイプはstruct abcですが、printfはその引数がタイプintであると想定しています。

paxdiabloの回答は、このような結果がどのように起こったのかの相違はありません。が発生しますが、それはあなたの特定の状況にのみ該当します。コード、翻訳環境、実行環境について何かを変更すると、結果が異なる可能性があります。

15

は二つの整数から成ります。その場合のxyz.aは無視されます。なぜなら、それはprintfが気にするスタック領域を超えているからです。

動作は未定義ですが(a)のprintf("%d %d",xyz,xyz.a);文は、おそらくのようなスタック何かに上xyzxyz.aをプッシュしているためので何かが起こることができることを、この特定のケースを説明することができます。

xyz.a | 10 | | 
xyz | 20 | | Stack grows downward. 
     | 10 | V 

printfコード自体には、%dの2つが与えられているため、下部に10が印刷され、20が印刷されます。つまり、フォーマット文字列とパラメータの不一致です。

%dを追加すると、上の図の3番目の引数(実際には2番目の値)と思われるものが印刷されます。

この動作に依存することはお勧めできません。

pax$ cat qq.c 
#include<stdio.h> 
struct abc { int a; int b; } xyz; 
int main (void) { 
    xyz.a=10; 
    xyz.b=20; 
    printf("%d %d",xyz,xyz.a); 
    return 0; 
} 

pax$ gcc -Wall -o qq qq.c 
qq.c: In function 'main': 
qq.c:6: warning: format '%d' expects type 'int', 
     but argument 2 has type 'struct abc' 
qq.c:6: warning: format '%d' expects type 'int', 
     but argument 2 has type 'struct abc' 
:あなたが潜在的なエラーとしてこれをキャッチするために、実際に printf引数の中を見

良いコンパイラgccのような:-)でも、奇数日には、おそらくコンパイラ、コンパイラのバージョン、またはを切り替えるとき、それは変更される可能性がありC99から


(A)、セクション7.19.6.1/9任意の引数は、対応する変換仕様の正しいタイプでない場合、動作は未定義です。

+0

華麗です。 –

+0

厳密に言えば、動作は**未定義**です。 *任意の*結果が許可されます。 –

+0

申し訳ありませんが、ジョン、私は_dependent_を実装しました。私はそれが実装_定義_(ISO Cの下では非常に明確な意味を持つ)であることを示すつもりではありませんでしたが、混乱の可能性を取り除くために明確にしました。 – paxdiablo

関連する問題