我写了一个C的小代码。
#include<stdio.h>
int main()
{
int a = 0;
printf("Hello World %llu is here %d\n",a, 1);
return 0;
}
正在打印以下输出
Hello World 4294967296在这里-1216225312
编译时出现以下警告
prog.cpp:在函数'int main()'中:
prog.cpp:5:警告:格式'%llu'需要类型'long long unsigned int',但参数2的类型为'int'
我知道我需要将int转换为long long unsigned int,但我无法理解为什么后来的值被破坏的事实。
提前致谢
答案 0 :(得分:7)
%llu需要一个64位整数。但是你只给它一个32位整数。
效果是printf读取的内容相对于你传递的内容被“移位”了32位。因此,您的“1”未在正确的位置阅读。
编辑:
现在解释输出:
a
和1
存储的间隔为32位,因为它们都是32位整数。
但是,printf期望第一个参数是64位整数。因此,它会将其显示为a + 2^32 * 1
,在您的情况下为4294967296
。打印的第二个值未定义,因为它超过1
。
答案 1 :(得分:4)
因为代码会导致未定义的行为 未定义的行为本身意味着所有赌注都已关闭。
printf
不是类型安全的。在打印输出类型时,你必须小心告诉printf
正确的格式desrciptor。
答案 2 :(得分:3)
您传递给printf()
的格式导致它在堆栈上预期12个字节,但您只推送8个字节。因此,它会读取您未推送的4个字节,并为您提供意外的输出。
确保传递printf()
期望的内容,并注意编译器的警告。
答案 3 :(得分:0)
long long是64位长,因此会发生这样的事情:
1. printf抓取64位并将其打印为第一个参数
2.然后它以64位的偏移量抓取32位,然后打印
由于您将32位值传递给第一个参数,因此两个值都是垃圾
答案 4 :(得分:0)
根据给定的格式,printf读取内存区域64位长度,其中包含a和1,打印4294967296.然后它从接下来的32位读取一些垃圾并打印-1216225312。