I have a problem while using the printf
function to print values of type unsigned long long int
我在使用printf函数打印unsigned long long int类型的值时遇到问题
I have no idea what's wrong. I'm using Dev-Cpp 4.9.9.2 and Visual Studio 2010 Professional (I know that it's not C compiler, but anyway, wanted to try) on Windows 7 Professional 64-bit. For displaying, I used %llu
modifier (according to How do you printf an unsigned long long int(the format specifier for unsigned long long int)?) but I also tried I64d with no effect...
我不知道出了什么问题。我在Windows 7 Professional 64位上使用Dev-Cpp 4.9.9.2和Visual Studio 2010 Professional(我知道它不是C编译器,但无论如何,想要尝试)。为了显示,我使用了%llu修饰符(根据你如何printf一个unsigned long long int(unsigned long long int的格式说明符)?)但我也试过I64d没有效果......
Firstly, I just wanted to print minimum and maximum value of unsigned long long int
(using ULONG_MAX
from limits.h
)
首先,我只想打印unsigned long long int的最小值和最大值(使用limits.h中的ULONG_MAX)
printf("unsigned long long int: \n%llu to %llu \n\n", 0, ULONG_MAX);
Returns:
unsigned long long int: 18446744069414584320 to 1580552164021 (Dev-Cpp)
unsigned long long int:18446744069414584320 to 1580552164021(Dev-Cpp)
unsigned long long int: 18446744069414584320 to 0 (Visual Studio)
unsigned long long int:18446744069414584320 to 0(Visual Studio)
Then I tried to using printf
to print two zeros
然后我尝试使用printf打印两个零
printf("unsigned long long int: \n%llu to %llu \n\n", 0, 0);
Returns:
unsigned long long int: 0 to 1580552164021 (Dev-Cpp)
unsigned long long int:0到1580552164021(Dev-Cpp)
unsigned long long int: 0 to 0 (Visual Studio)
unsigned long long int:0到0(Visual Studio)
Also tried two ULONG_MAX
values
还尝试了两个ULONG_MAX值
printf("unsigned long long int: \n%llu to %llu \n\n", ULONG_MAX, ULONG_MAX);
Returns:
unsigned long long int: 18446744073709551615 to 1580552164021 (Dev-Cpp)
unsigned long long int:18446744073709551615 to 1580552164021(Dev-Cpp)
unsigned long long int: 18446744073709551615 to 0 (Visual Studio)
unsigned long long int:18446744073709551615 to 0(Visual Studio)
Why does it behave like that? Could you explain it to me?
为什么它表现得那样?你能解释一下吗?
4 个解决方案
#1
11
This is wrong:
这是错的:
printf("unsigned long long int: \n%llu to %llu \n\n", 0, ULONG_MAX);
You use a unsigned long long
format specifier, but you pass an int
and an unsigned long
value. Promotion rules mean you can be sloppy for everything int
-sized or smaller, which does not apply to long long
.
您使用无符号长long格式说明符,但传递int和unsigned long值。促销规则意味着您可以对大小或更小的所有内容草率,这不适用于长期。
Use casts:
printf("unsigned long long int: \n%llu to %llu \n\n",
0ULL, (unsigned long long) ULONG_MAX);
Explanation: When passing arguments to printf
, any type that can fit in an int
is promoted to int
, and then any type that can fit in an unsigned int
is promoted to unsigned int
. It is also okay to pass an unsigned type to a signed format specifier or vice versa as long as the value passed can be represented using the type specified by the format specifier.
说明:将参数传递给printf时,任何可以放入int的类型都会提升为int,然后任何可以放入unsigned int的类型都会提升为unsigned int。只要传递的值可以使用格式说明符指定的类型表示,也可以将无符号类型传递给带符号的格式说明符,反之亦然。
So you must be careful with long
and long long
, but you can be sloppy with int
, short
, and char
.
所以你必须小心长期和长期,但你可以用int,short和char邋。
Most compilers have settings to make them warn you about this type of error, since it can be detected at compile-time fairly easily; GCC and Clang have -Wformat
which results in the following warnings:
大多数编译器都有设置让他们警告你这类错误,因为它可以很容易地在编译时检测到; GCC和Clang有-Wformat导致以下警告:
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’
#2
10
You are not passing unsigned long longs
. You are passing an int
(0) and unsigned long
(ULONG_MAX). You must pass to printf()
exactly what you promise to pass in the format string.
你没有传递未签名的长多头。您传递的是int(0)和unsigned long(ULONG_MAX)。您必须准确传递printf()您希望传递的格式字符串。
Try this instead:
试试这个:
printf("unsigned long long int: \n%llu to %llu \n\n", 0ULL, (unsigned long long)ULONG_MAX);
#3
4
ULONG_MAX
refers to unsigned long
and not to unsigned long long
. For the latter, use ULLONG_MAX
(note the extra L
).
ULONG_MAX指的是unsigned long而不是unsigned long long。对于后者,使用ULLONG_MAX(注意额外的L)。
You need to change the printf()
calls like so:
您需要更改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);
This ensures that the arguments to printf()
match the format specifiers.
这可以确保printf()的参数与格式说明符匹配。
#4
0
long long int is a type from the C99 standard, MSVC doesn't support this. Take a compiler with C99 support (like MinGW for Windows) and it will work.
long long int是C99标准的类型,MSVC不支持此。使用支持C99的编译器(如MinGW for Windows),它将工作。
#1
11
This is wrong:
这是错的:
printf("unsigned long long int: \n%llu to %llu \n\n", 0, ULONG_MAX);
You use a unsigned long long
format specifier, but you pass an int
and an unsigned long
value. Promotion rules mean you can be sloppy for everything int
-sized or smaller, which does not apply to long long
.
您使用无符号长long格式说明符,但传递int和unsigned long值。促销规则意味着您可以对大小或更小的所有内容草率,这不适用于长期。
Use casts:
printf("unsigned long long int: \n%llu to %llu \n\n",
0ULL, (unsigned long long) ULONG_MAX);
Explanation: When passing arguments to printf
, any type that can fit in an int
is promoted to int
, and then any type that can fit in an unsigned int
is promoted to unsigned int
. It is also okay to pass an unsigned type to a signed format specifier or vice versa as long as the value passed can be represented using the type specified by the format specifier.
说明:将参数传递给printf时,任何可以放入int的类型都会提升为int,然后任何可以放入unsigned int的类型都会提升为unsigned int。只要传递的值可以使用格式说明符指定的类型表示,也可以将无符号类型传递给带符号的格式说明符,反之亦然。
So you must be careful with long
and long long
, but you can be sloppy with int
, short
, and char
.
所以你必须小心长期和长期,但你可以用int,short和char邋。
Most compilers have settings to make them warn you about this type of error, since it can be detected at compile-time fairly easily; GCC and Clang have -Wformat
which results in the following warnings:
大多数编译器都有设置让他们警告你这类错误,因为它可以很容易地在编译时检测到; GCC和Clang有-Wformat导致以下警告:
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’
#2
10
You are not passing unsigned long longs
. You are passing an int
(0) and unsigned long
(ULONG_MAX). You must pass to printf()
exactly what you promise to pass in the format string.
你没有传递未签名的长多头。您传递的是int(0)和unsigned long(ULONG_MAX)。您必须准确传递printf()您希望传递的格式字符串。
Try this instead:
试试这个:
printf("unsigned long long int: \n%llu to %llu \n\n", 0ULL, (unsigned long long)ULONG_MAX);
#3
4
ULONG_MAX
refers to unsigned long
and not to unsigned long long
. For the latter, use ULLONG_MAX
(note the extra L
).
ULONG_MAX指的是unsigned long而不是unsigned long long。对于后者,使用ULLONG_MAX(注意额外的L)。
You need to change the printf()
calls like so:
您需要更改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);
This ensures that the arguments to printf()
match the format specifiers.
这可以确保printf()的参数与格式说明符匹配。
#4
0
long long int is a type from the C99 standard, MSVC doesn't support this. Take a compiler with C99 support (like MinGW for Windows) and it will work.
long long int是C99标准的类型,MSVC不支持此。使用支持C99的编译器(如MinGW for Windows),它将工作。