我写了这个小代码:
#include <stdio.h> int main() { size_t temp; temp = 100; printf("lld=%lld,ld=%ld,u=%u\n",temp,temp); return 0; }
我在一个带有gcc版本4.1.1 20070105(Red Hat 4.1.1-52)的i386 GNU / Linux机器上运行.这是我得到的输出:
lld=429496729700,ld=100,u=7993461
我可以理解,第一个(lld)被打印为垃圾,因为当可变temp只有4个字节时,printf尝试打印8个字节(由lld表示的long long).
但是,我不明白为什么最后一个标识符u被打印为垃圾,而在我看来,这是size_t最接近的适用标识符.
这里我假设size_t是unsigned int(我的i386有4个字节).
现在我用printf线做了一点调整:
... printf("ld=%ld,u=%u,lld=%lld\n",temp); ...
我有一个非常好的答案(除了lld部分).
ld=100,u=100,lld=34331653576851556
有人可以帮我理解我在这里错过什么吗?
非常感谢任何帮助!
解决方法
这是因为您在堆栈中推送的是三个32位值,格式字符串尝试使用其中的四个值,或者更精确地使用一个64位值和两个32位值.
在第一种情况下,lld吸收了两个32位值,ld吸收了第三个值,并且在这之后,你会发现任何事情发生在堆栈上,这真的是任何事情.
当您更改字符串中格式说明符的顺序时,它的作用不同,因为ld吸收了第一个32位值,您吸收了第二个,而lld吸收了第三个加上任何恰好在堆栈上的事情.那.这就是为什么你得到不同的值,这是一个数据对齐/可用性问题.
您可以使用第一个值查看此操作. 429496729700等于(4294967296 1)* 100,即(232 1)* 100.你的代码段
printf("lld=%lld,temp);
实际上有以下效果:
What you pass Stack What printf() uses ------------- ----- ------------------ +-----+ 100 | 100 | \ +-----+ = 64-bit value for %lld. 100 | 100 | / +-----+ 100 | 100 | 32-bit value for %ld. +-----+ | ? | 32-bit value for %u (could be anything). +-----+
在第二种情况下
printf("ld=%ld,temp);
发生以下情况:
What you pass Stack What printf() uses ------------- ----- ------------------ +-----+ 100 | 100 | 32-bit value for %ld. +-----+ 100 | 100 | 32-bit value for %u. +-----+ 100 | 100 | \ +-----+ = 64-bit value for %lld (could be anything). | ? | / +-----+