C语言 为什么 C 中的一个 printf() 不能同时打印两个 64 位值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6850737/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why can one printf() in C not print two 64-bit values at the same time?
提问by Jeegar Patel
I am working on a 32-bit system. When I try to print more than one 64 bit value in a single printf, then it cannot print any further (i.e. 2nd, 3rd, ...) variable values.
我在 32 位系统上工作。当我尝试在单个 printf 中打印多个 64 位值时,它无法打印更多(即第二、第三、...)变量值。
example:
例子:
uint64_t a = 0x12345678;
uint64_t b = 0x87654321;
uint64_t c = 0x11111111;
printf("a is %llx & b is %llx & c is %llx",a,b,c);
Why can this printf not print all values?
为什么这个 printf 不能打印所有值?
I am modifying my question
我正在修改我的问题
printf("a is %x & b is %llx & c is %llx",a,b,c);
by doing this result is : a is 12345678 & b is 8765432100000000 & c is 1111111100000000
这样做的结果是:a 是 12345678 & b 是 8765432100000000 & c 是 1111111100000000
if i am not printing a's value properly then why other's value's are gona change??
如果我没有正确打印 a 的值,那么为什么其他的值会改变??
回答by Vinicius Kamakura
You should use the macros defined in <inttypes.h>
您应该使用中定义的宏 <inttypes.h>
printf("a is %"PRIx64" & b is %"PRIx64" & c is %"PRIx64"\n",a,b,c);
It is ugly as hell but it's portable. This was introduced in C99, so you need a C99 compliant compiler.
它很丑陋,但它是便携式的。这是在 C99 中引入的,因此您需要一个符合 C99 的编译器。
回答by XYZ
You need to use the correct format:
您需要使用正确的格式:
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
int main(void)
{
uint64_t a = 0x12345678;
uint64_t b = 0x87654321;
uint64_t c = 0x11111111;
printf("a is %#" PRIx64
" & b is %#" PRIx64
" & c is %#" PRIx64 "\n",
a, b, c);
return EXIT_SUCCESS;
}
Output:
输出:
a is 0x12345678 & b is 0x87654321 & c is 0x11111111
回答by Paul
It prints them all on my computer, but there are three compile time warnings since %llxexpects a long long unsigned int.
它将它们全部打印在我的计算机上,但是由于%llx需要long long unsigned int.
Are you sure you need to be using 64 bit types though? All three of your hexcodes are only 32 bits. Maybe you could just use 32 bits and do:
你确定你需要使用 64 位类型吗?您的所有三个十六进制代码都只有 32 位。也许您可以只使用 32 位并执行以下操作:
unsigned int a = 0x12345678;
unsigned int b = 0x87654321;
unsigned int c = 0x11111111;
printf("a is %x & b is %x & c is %x",a,b,c);
(Or use the stdint equivalent of 32bit unsigned int)
(或使用相当于 32 位 unsigned int 的 stdint)
Unless you need them to be 64 bits so you can add more bits to them later.
除非您需要它们是 64 位,以便以后可以向它们添加更多位。
回答by Fred Schleifer
As appropriate for a forum named Stack Overflow, the cause of the unexpected printf()output is due to stack misalignment. The size mismatch between the %xconversion specification and function argument acauses the misalignment.
对于名为Stack Overflow的论坛而言,意外printf()输出的原因是堆栈未对齐。%x转换规范和函数参数之间的大小不匹配a会导致未对齐。
When compiling the statement
编译语句时
printf("a is %x & b is %llx & c is %llx",a,b,c);
the compiler generates machine code that pushes the function arguments on the stack in right-to-left order.
编译器生成机器代码,以从右到左的顺序将函数参数压入堆栈。
The compiler uses the variable declarations, not the format string, to determine the data size of each argument on the stack (except possibly for generating warnings). In an x86 CPU (as in most machines) the stack pointer decrements with every push. When entering the printf()library function, the stack therefore has the following layout:
编译器使用变量声明而不是格式字符串来确定堆栈上每个参数的数据大小(可能生成警告除外)。在 x86 CPU(如在大多数机器中)中,每次推送堆栈指针都会递减。printf()因此,进入库函数时,堆栈具有以下布局:
00A4: ...
00A0: 00000000
009C: 11111111 Variable 'c' pushed on the stack as uint64
0098: 00000000
0094: 87654321 'b' pushed on the stack as uint64
0090: 00000000
008C: 12345678 'a' pushed on the stack as uint64
0088: <pointer to format string>
0084: <return address>
The top-of-stack address of 0084 is arbitrary for this example.
对于这个例子,栈顶地址 0084 是任意的。
Since all three variables are declared as uint64_t, the compiled code pushes these variables on the stack as 64-bit values. For a little-endian machine such as an x86 CPU, the high bytes of each uint64value end up in the higher addresses.
由于所有三个变量都声明为uint64_t,编译后的代码将这些变量作为 64 位值压入堆栈。对于像 x86 CPU 这样的 little-endian 机器,每个uint64值的高字节最终位于较高的地址中。
The implementation of printf()uses the format string to determine the number of and sizes of the arguments on the stack. Unlike the compiler, printf()receives no information about the original variable declarations. The first conversion specification is %x, so printf()expects ato be a 32-bit value, and therefore, printf()parses the stack layout as follows:
的实现printf()使用格式字符串来确定堆栈上参数的数量和大小。与编译器不同,printf()它不接收有关原始变量声明的信息。第一个转换规范是%x,因此printf()期望a是 32 位值,因此,printf()按如下方式解析堆栈布局:
00A4: ...
00A0: 00000000
009C: 11111111
0098: 00000000 '%llx' reads 'c' as uint64, but from the wrong address
0094: 87654321
0090: 00000000 '%llx' reads 'b' as uint64, but from the wrong address
008C: 12345678 '%x' causes printf() to read 'a' as a uint32
0088: <pointer to format string>
0084: <return address>
The stack misalignment explains why aprints 12345678 as expected, but band chave been effectively left-shifted by 32 bits to 8765432100000000 and 1111111100000000.
堆栈不对解释了为什么a打印12345678不如预期,但b并c得到了有效的32位左移到87654321亿和11111111亿。
Correcting the first %xconversion specification or casting argument ato uint32 should fix the problem.
将第一个%x转换规范或强制转换参数更正a为 uint32 应该可以解决问题。
回答by nvd
Use:
用:
"%lli" for int64_t
"%llu" for uint64_t
"%llx" for hex
"%llX" for HEX
Have a look inside "inttypes.h".
看看里面的“inttypes.h”。

