7

多肢選択式テストで質問がありました: 次のプログラムの出力はどうなるでしょうか:

#include <stdio.h>

int main(void)
{
    int a = 10, b = 5, c = 2;

    printf("%d %d %d\n");

    return 0;
}

選択肢は 10、5、および 2 のさまざまな順列でした。何らかの理由で、大学で使用している Turbo C++ で動作します。ただし、gcc (-Wall が有効な場合に警告が表示される) または clang (-Wformat が有効で、デフォルトで警告が表示される) または Visual C++ でコンパイルされた場合はそうではありません。出力は、予想どおり、ガベージ値です。私の推測では、Turbo C++ が 16 ビットであり、32 ビットの Windows XP で実行されているか、標準に関しては TCC がひどいという事実と関係があると思います。

4

5 に答える 5

20

コードには未定義の動作があります。

printf()Turbo C++ では、たまたま 3 つの変数が、不足している引数があるスタック上の正確な位置に存在します。これにより、「正しい」値が出力されることにより、未定義の動作が明らかになります。

ただし、これが事実であると合理的に信頼することはできません。ビルド環境にわずかな変更を加えるだけでも (たとえば、コンパイラ オプションを変更するなど)、恣意的な方法で問題が発生する可能性があります。

于 2013-08-22T19:30:47.353 に答える
4

ですundefined behaviour。だから何とでもなる。

使ってみて

printf("%d %d%d", a,b,c)

理由:-ローカル変数はスタックで呼び出され、Turbo C++ の printf は、スタックで割り当てられたのと同じ順序でそれらを参照します。

提案(コメントから):-

特定のコンパイラで特定の方法で動作する理由を理解することは、問題の診断に役立ちますが、その情報を他の用途に使用しないでください。

于 2013-08-22T19:29:39.340 に答える
4

ここでの答えは、プログラムは何でもできるということです。これは未定義の動作です。sのドキュメントによるとprintf()(強調は私のものです):

デフォルトでは、引数は指定された順序で使用されます。各 '*' および各変換指定子は次の引数を要求します(引数の数が不十分な場合はエラーになります)

多肢選択式テストに「未定義の動作」の選択肢がない場合、それは欠陥のあるテストです。未定義の動作の影響下では、このような多肢選択式の試験問題に対する解答は技術的に正しいものです

于 2013-08-22T19:30:01.970 に答える
3

実際に何が起こっているかというと、通常、引数はコール スタックで渡されます。ローカル変数コールスタックに渡されるprintf()ため、コンパイラがそれらをそこに格納することを決定した順序でそれらの値が表示されます。

この動作は、他の多くの動作と同様に、未定義の動作の傘下で許可されています

于 2013-08-22T19:31:17.517 に答える
2

いいえ、建築とは関係ありません。これは、TurboC++ がスタックを処理する方法に関連しています。変数ab、およびcはローカル変数であり、スタックに割り当てられます。 printfスタック内の値も必要です。どうやら、TurboC++ はローカルの後にスタックに何も追加せず、printfそれらをパラメーターとして受け取ることができます。ただの偶然。

于 2013-08-22T19:34:24.460 に答える