7

私はこのコードを試していました。

#include <stdio.h>
#include <stdlib.h>
#define LOWER 0
#define UPPER 300

int main()
{
    printf("%d %f",LOWER,UPPER);
    return 0;
}

いくつかの答えを読みましたが、定義された定数には型がなく、メモリが割り当てられていないと書かれています。それでは、printf()で異なる型指定子を指定すると、なぜエラーが発生するのですか?

4

4 に答える 4

4

あなたの例では、両方がint値としてprintfの可変個引数パラメータリストにプッシュされます。これにより、のフォーマット文字列のフォーマットフラグがprintf()基になるタイプと一致しないという問題が発生する可能性があります。未定義の動作が発生する理由については、この投稿を参照してください。

恐ろしいように思えますが、これで探しているものを取得できることを知る1つの方法は、次のことをprintf行うことです。

#include <stdio.h>
#include <stdlib.h>
#define LOWER 0
#define UPPER 300

int main()
{
    printf("%d %f", (int)LOWER, (float)UPPER);
    return 0;
}

どちらの場合も、これらはコンパイル前に置き換えられるプリプロセッサマクロです。UPPERをに昇格できない場合floatは、コンパイラエラーが発生することに注意してください。これは良いことです。可能であれば、そうなり、printf()必要なものを印刷するために必要なバイトが検出されます。int同じことがそれぞれとLOWERにも当てはまります。上記のprintfは、前処理後にこれに縮退します。

printf("%d %f", (int)0, (float)300);

ここで、マクロが代わりにそのように宣言されたと想像してください。

#define LOWER 100.0
#define UPPER 300.0

オリジナルprintf()は、前処理後にこのように表示されます。

printf("%d %f", 100.0, 300.0);

これは正しいように見えるかもしれませんが、100.0 floatは実際に%dフォーマット文字列ハンドラーによって適切に削除されるのprintf()でしょうか?確実に。以前に行ったことを行う:

printf("%d %f", (int)LOWER, (float)UPPER);

現在、次のように前処理されます。

printf("%d %f", (int)100.0, (float)300.0);

floatからintへのキャストでコンパイラの警告が表示される場合がありますが、表示されない場合があります。渡すものがバイトサイズのサイコロを振る必要がない限り、printf()すべてが一致していることを確認してください。これは、フォーマット指定子が1つのことを期待し、別の何かが渡される場合に特にイライラする可能性がありますが、それでもすべて正常に機能しているように見えますが、一部のプラットフォームでのみ不思議なことになります。

printf("%ld\n", UPPER);

これは「機能する」可能性がありますが、機能する場合は、a long int とa int がプラットフォーム上で同じサイズであるためです。このコードを、ビット幅とUBが完全に異なるプラットフォームに移動しますlong intint

結論:プリプロセッサマクロをprintf()、プッシュされるデータのサイズが期待されるようなもの(たとえば、フォーマット文字列で指定される)の可変個引数パラメータリストに渡す場合は、プッシュするものが期待されるものであることを確認する方が適切です。

于 2012-10-31T16:38:32.303 に答える
3

この場合、型はリテラル定数の型です。0とは両方とも300に適合する整数定数であるintため、それらの型はintです。

于 2012-10-31T16:30:42.030 に答える
1

タイプされていません。ソースのテキストによる置換として見てください。

printf("%d %f", 0, 300);
于 2012-10-31T16:30:27.473 に答える
1

#defineプリプロセッサディレクティブです。コンパイル後は存在しません。代わりに、対応する値がコードで置き換えられます。この場合、マクロ展開後にコンパイルされる実際のコードは

//header stdio.h
//header stdlib.h


int main()
{
    printf("%d %f",0,300);
    return 0;
}

そして、はい、この場合、0,300は両方とも整数です。!

于 2012-10-31T16:33:14.733 に答える