具有lld,ld和d类型标识符的size_t变量的c – printf

前端之家收集整理的这篇文章主要介绍了具有lld,ld和d类型标识符的size_t变量的c – printf前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我写了这个小代码
#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

有人可以帮我理解我在这里错过什么吗?

非常感谢任何帮助!

[注意:我尝试使用gcc -O [0,2]标签打开/关闭切换优化,观察结果没有任何差异.]

解决方法

这是因为您在堆栈中推送的是三个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).
                 | ?   | /
                 +-----+

猜你在找的C&C++相关文章