Printing unsigned long long int Value Type Returns Strange Results
我在使用printf函数打印unsigned long long int类型的值时遇到问题。
我不知道怎么了。我在64位Windows7Professional上使用了dev cpp 4.9.9.2和VisualStudio2010专业版(我知道它不是C编译器,但无论如何,我都想尝试)。为了显示,我使用了%llu修饰符(根据如何打印无符号长整型int(无符号长整型int的格式说明符))。但我也尝试过i64d,但没有效果…
首先,我只想打印unsigned long long int的最小值和最大值(使用limits.h的ULONG_MAX)。
1 2 3 4
| printf("unsigned long long int:
%llu to %llu
", 0, ULONG_MAX ); |
返回:
unsigned long long int: 18446744069414584320 to 1580552164021 (Dev-Cpp)
unsigned long long int: 18446744069414584320 to 0 (Visual Studio)
然后我试着用printf打印两个零
1 2 3 4
| printf("unsigned long long int:
%llu to %llu
", 0, 0); |
返回:
unsigned long long int:
0 to 1580552164021 (Dev-Cpp)
unsigned long long int: 0 to 0 (Visual Studio)
还尝试了两个ULONG_MAX值
1 2 3 4
| printf("unsigned long long int:
%llu to %llu
", ULONG_MAX , ULONG_MAX ); |
返回:
unsigned long long int: 18446744073709551615 to 1580552164021 (Dev-Cpp)
unsigned long long int:
18446744073709551615 to 0 (Visual Studio)
为什么会这样?你能给我解释一下吗?
这是错误的:
1 2 3 4
| printf("unsigned long long int:
%llu to %llu
", 0, ULONG_MAX ); |
使用unsigned long long格式说明符,但传递int和unsigned long值。晋升规则意味着你可以对任何尺寸或更小的int的东西马虎,这不适用于long long。
使用铸件:
1 2 3 4 5
| printf("unsigned long long int:
%llu to %llu
",
0ULL , (unsigned long long) ULONG_MAX ); |
说明:当把参数传递给printf时,任何适合int的类型都被提升为int,然后任何适合unsigned int的类型都被提升为unsigned int。也可以将无符号类型传递给有符号格式说明符,反之亦然,只要传递的值可以使用格式说明符指定的类型表示。
因此,你必须小心使用long和long long,但是你可以随意使用int、short和char。
大多数编译器都有设置,使它们对这种类型的错误发出警告,因为它在编译时很容易被检测到;gcc和clang都有-Wformat,这会导致以下警告:
1 2
| test.c:5: warning: format ‘%llu’ expects type ‘long long unsigned int’, but argument 2 has type ‘int’
test.c:5: warning: format ‘%llu’ expects type ‘long long unsigned int’, but argument 3 has type ‘long unsigned int’ |
你不能通过unsigned long longs。您正在通过一个int0和unsigned long(ulong_max)。您必须传递给printf(),这正是您在格式字符串中承诺传递的内容。
试试这个:
1 2 3 4
| printf("unsigned long long int:
%llu to %llu
", 0ULL , (unsigned long long)ULONG_MAX ); |
ULONG_MAX是指unsigned long而不是unsigned long long。对于后者,使用ULLONG_MAX(注意额外的L)。
您需要像这样更改printf()调用:
1 2 3 4 5 6 7 8
| printf("unsigned long long int:
%llu to %llu
", 0ULL , ULLONG_MAX );
printf("unsigned long long int:
%llu to %llu
", ULLONG_MAX , ULLONG_MAX ); |
这样可以确保printf()的参数与格式说明符匹配。
long long int是c99标准中的一种类型,MSVC不支持这种类型。使用一个支持C99的编译器(如Mingw for Windows),它就可以工作了。
- MSVC支持long long,尽管没有完全支持c99。