11

printfタイプの値を出力する関数を使用しているときに問題が発生しましたunsigned long long int

何が悪いのかわかりません。Windows 7 Professional 64ビットでDev-Cpp 4.9.9.2とVisual Studio 2010 Professionalを使用しています(Cコンパイラではないことは知っていますが、とにかく試してみたいと思いました)。表示するために、%llu修飾子を使用しました(How do you printf an unsigned long long int(the format specifier for unsigned long long int)?に従って)が、I64dも効果なしで試しました...


まず、( fromunsigned long long intを使用して)の最小値と最大値を出力したかっただけですULONG_MAXlimits.h

printf("unsigned long long int: \n%llu to %llu \n\n", 0, ULONG_MAX);

戻り値:

unsigned long long int: 18446744069414584320 ~ 1580552164021 (Dev-Cpp)

unsigned long long int: 18446744069414584320 から 0 (Visual Studio)


次に、printf2つのゼロを印刷するために使用しようとしました

printf("unsigned long long int: \n%llu to %llu \n\n", 0, 0);

戻り値:

unsigned long long int: 0 ~ 1580552164021 (Dev-Cpp)

unsigned long long int: 0 から 0 (Visual Studio)


ULONG_MAX2つの値も試しました

printf("unsigned long long int: \n%llu to %llu \n\n", ULONG_MAX, ULONG_MAX);

戻り値:

unsigned long long int: 18446744073709551615 ~ 1580552164021 (Dev-Cpp)

unsigned long long int: 18446744073709551615 から 0 (Visual Studio)


なぜそのように振る舞うのですか?説明していただけますか?

4

4 に答える 4

12

これは間違っています:

printf("unsigned long long int: \n%llu to %llu \n\n", 0, ULONG_MAX);

unsigned long long書式指定子を使用していますが、intおよびunsigned long値を渡しています。プロモーション ルールは、 に適用されないint、 のサイズ以下のすべてに対してずさんになる可能性があることを意味します。long long

キャストを使用する:

printf("unsigned long long int: \n%llu to %llu \n\n",
       0ULL, (unsigned long long) ULONG_MAX);

説明:に引数を渡す場合printf、 に収まる型intは に昇格されint、次に に収まる型unsigned intは に昇格されunsigned intます。渡された値が書式指定子によって指定された型を使用して表現できる限り、符号なしの型を符号付きの書式指定子に渡したり、その逆を行ったりすることもできます。

したがって、 と には注意する必要がありますが、 、 、およびにlongは注意が必要です。long longintshortchar

ほとんどのコンパイラには、このタイプのエラーについて警告する設定があります。これは、コンパイル時に非常に簡単に検出できるためです。GCC と Clang-Wformatには、次の警告が表示される結果があります。

test.c:5: 警告: フォーマット '%llu' はタイプ 'long long unsigned int' を想定していますが、引数 2 のタイプは 'int' です
test.c:5: 警告: フォーマット '%llu' はタイプ 'long long unsigned int' を想定していますが、引数 3 のタイプは 'long unsigned int' です
于 2012-05-19T09:58:53.113 に答える
10

あなたは合格していませんunsigned long longsint(0) とunsigned long(ULONG_MAX)を渡しています。printf()フォーマット文字列で渡すと約束したものを正確に渡す必要があります。

代わりにこれを試してください:

printf("unsigned long long int: \n%llu to %llu \n\n", 0ULL, (unsigned long long)ULONG_MAX);
于 2012-05-19T09:58:08.260 に答える
4

ULONG_MAXを参照しunsigned long、 を参照しませんunsigned long long。後者の場合は、使用しますULLONG_MAX(余分な に注意してくださいL)。

printf()次のように呼び出しを変更する必要があります。

printf("unsigned long long int: \n%llu to %llu \n\n", 0ULL, ULLONG_MAX);
printf("unsigned long long int: \n%llu to %llu \n\n", ULLONG_MAX, ULLONG_MAX);

これにより、引数がprintf()フォーマット指定子と一致することが保証されます。

于 2012-05-19T09:58:15.810 に答える
0

long long intはC99標準のタイプであり、MSVCはこれをサポートしていません。C99をサポートするコンパイラ(Windows用のMinGWなど)を使用すると、動作します。

于 2012-05-19T11:31:24.710 に答える