unsigned long long 型输出的问题,高手进

coolboycool 2010-06-01 02:45:23
程序如下,很简单
#include<stdio.h>

int main(){
unsigned long long amount = 4294967295;
unsigned long amount32 = 429496729;

printf("amount:%llu, amount32:%lu", amount , amount32 );
printf("amount32:%lu, amount:%llu", amount32 , amount );

return 0;
}

输出结果:amount:4294967295, amount32:0
amount32:429496729, amount:4294967295

第一次失败,后面的32位值被清为0,第二次成功,什么原因,不得其解。请高手解答
...全文
19367 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
coolboycool 2010-06-09
  • 打赏
  • 举报
回复
感谢两位答案,明白了,已结贴给分:)
赵4老师 2010-06-02
  • 打赏
  • 举报
回复
VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编不就啥都明白了吗。
(Linux或Unix下应该也可以在用GDB调试时,看每句C对应的汇编。)
selooloo 2010-06-02
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 pengzhixi 的回复:]
个人意见:1.参数的入栈顺序 2.unsigned long long 应该是C90的标准添加的吧,与printf 对参数类型的解析是有关系的。像这种不定参数函数的参数类型解析本身就有一些缺陷。
[/Quote]
编译器支持unsigned long long类型,但 printf好像并没修改对llu的解析,仍然按32位解析的
这个还和大小端有关系,上面说的都是小端机的情况,如果是大端的,情况应该相反
pengzhixi 2010-06-02
  • 打赏
  • 举报
回复
个人意见:1.参数的入栈顺序 2.unsigned long long 应该是C90的标准添加的吧,与printf 对参数类型的解析是有关系的。像这种不定参数函数的参数类型解析本身就有一些缺陷。
selooloo 2010-06-02
  • 打赏
  • 举报
回复
上面写错了
amount高32位 <--0
amount低32位 <--4294967295 <----%llu,打印4294967295
amount32 <--429496729 <----printf从这里开始解析%lu打印429496729
selooloo 2010-06-02
  • 打赏
  • 举报
回复
32位先入栈,printf("amount32:%lu, amount:%llu\n", amount32 , amount );就是

amount高32位 <--0
amount低32位 <--4294967295 <----printf从这里开始解析%llu,打印4294967295
amount32 <--429496729 <----这时再加个%lu就可以打印出amount的值

这里能打印出正确结果只是恰好4294967295不超出32位,
同理令amount位4294967296,再看看结果
selooloo 2010-06-02
  • 打赏
  • 举报
回复
printf打印和入栈情况有关,
printf("amount:%llu, amount32:%lu", amount , amount32 );
amount是64位的,低32位先入栈,然后是高32位,然后amount32入栈
这时栈中的情况是

amount32 <--429496729 <----这时再加个%lu就可以打印出amount的值
amount高32位 <--0 <----%lu ,打印0
amount低32位 <--4294967295 <----printf从这里开始解析%llu,打印4294967295

4294967295正好是32位数的最大值,把它+1,即4294967296
printf("amount:%llu, amount32:%lu", amount , amount32 );
打印结果就是 0,1 了
coolboycool 2010-06-01
  • 打赏
  • 举报
回复
试了下,用I64u可以正常,但是我想知道上面的错误是什么原因?
为什么64位先打印就会有问题
而32位先打印就没问题呢?
赵4老师 2010-06-01
  • 打赏
  • 举报
回复
windows下用__int64
__int64 amount = 4294967295234234i64;
printf("%I64d\n",amount);
cattycat 2010-06-01
  • 打赏
  • 举报
回复
printf("%I64u",amount);
用这个输出64位的整数。
我的vs和gcc输出都没问题啊。
东莞某某某 2010-06-01
  • 打赏
  • 举报
回复
没懂,顶下
selooloo 2010-06-01
  • 打赏
  • 举报
回复
上面说错了,不是类型的提升
而是printf %llu是按32位解析的,先解析了amount的低32位,高32位被printf("amount32:%lu")获取,因为它的高32位都是0,所以打印出来是0;
把它改大点, unsigned long long amount = 4294967295234234LLU;
再打印看看
selooloo 2010-06-01
  • 打赏
  • 举报
回复
printf("amount:%llu, amount32:%lu", amount , amount32 );
这里amount32的类型应该被提升了,提升为unsigned long long ,从32字节变成64字节,高32位补0

而printf %lu仍然按32位解析,所以它解析的是类型提升后的amount32的高32位,也就是0

可以在后面再填个%lu就可以打印出amount32的低32位,也就是它的原值
printf("amount:%llu, amount32:%lu,amount32:%lu\n", amount , amount32 );

70,028

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧