关于C#:打印unsigned long long int值类型返回奇怪的结果

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.hULONG_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格式说明符,但传递intunsigned 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。也可以将无符号类型传递给有符号格式说明符,反之亦然,只要传递的值可以使用格式说明符指定的类型表示。

因此,你必须小心使用longlong long,但是你可以随意使用intshortchar

大多数编译器都有设置,使它们对这种类型的错误发出警告,因为它在编译时很容易被检测到;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),它就可以工作了。