求解释下面这段程序中关于printf的奇怪机制

njuliao 2012-04-12 10:52:44

#include <stdio.h>
int main()
{
_int64 a;
a = 100;
char b;
b = 1;
printf("%d %d\n", a, b);
return 0;
}


为什么输出是100 0啊,printf怎么做类型转换的?
...全文
165 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
「已注销」 2012-04-13
  • 打赏
  • 举报
回复
1: #include <stdio.h>
2:
3: int main(void)
4: {
5: _int64 a;
6: char b;
7:
8: a = 100;
9: b = 1;
10: printf("%d %d\n", a, b);
010A1000 6A 01 push 1 //b参数
010A1002 6A 00 push 0 //a参数高32位
010A1004 6A 64 push 64h //a参数低32位,64h = 100
010A1006 68 F4 20 0A 01 push offset string "%d %d\n" (10A20F4h)
010A100B FF 15 A0 20 0A 01 call dword ptr [__imp__printf (10A20A0h)]
010A1011 83 C4 10 add esp,10h
11:
12: return 0;
010A1014 33 C0 xor eax,eax
13: }
010A1016 C3 ret

看汇编代码,调用printf时压栈4个参数,因为a为64位,分成2次压栈!
然后在进入printf内部,按格式串
("%d %d\n", a, b);
也只提取2个int型!
故第一个%d用a的低32位填充,第二个%d使用a的高32位填充,
故输出:100 0
正确格式串应为:("%lld %d\n", a, b);


本人新手,不对的地方欢迎大家指正!
Vincent_Song 2012-04-12
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

int64用%I64d或%lld
用%d时相当于,把int64拆成两个int
C/C++ code
_int64 a;
a = 100;
char b;
b = 1;
int a1 = *(int*)((int*)&a + 1); //低位,等于100
int a2 = *(int*)&a; //高位,为0
print……
[/Quote]

你代码的注释写的有问题,不要误导了别人,printf也写的有问题。

_int64 a;
a = 100;
char b;
b = 1;
int a1 = *(int*)((int*)&a + 1); //高位,为0
int a2 = *(int*)&a; //低位,等于100
printf("%d %d %d\n", a1, a2, b);
iamnobody 2012-04-12
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

我的意思是说,printf不对变量做类型转换,直接用两个%d打印一个double
[/Quote]

你要是想研究double 的二进制表示,就去百度 IEEE-754 标准,作为参考.

要是想研究你的编译器(不是c/c++)的printf 的实现,就去看它的代码.

要是想学C/C++,就老实用 %lf 输出 double ,

否则都是浪费时间.
Vincent_Song 2012-04-12
  • 打赏
  • 举报
回复
将格式化类型更改即可%lld。
njuliao 2012-04-12
  • 打赏
  • 举报
回复
我的意思是说,printf不对变量做类型转换,直接用两个%d打印一个double
stjay 2012-04-12
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

C/C++ code

#include <stdio.h>
int main()
{
double a;
a = 100;
char b;
b = 1;
printf("%d %d\n", a, b);
return 0;
}



这个也不对,那怎么解释
[/Quote]

好好看printf的格式符
double用%f
elegant87 2012-04-12
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

原因都是,你的计算机上a是8字节,%d处理4字节
[/Quote]
正解
stjay 2012-04-12
  • 打赏
  • 举报
回复
int64用%I64d或%lld
用%d时相当于,把int64拆成两个int
    _int64 a;
a = 100;
char b;
b = 1;
int a1 = *(int*)((int*)&a + 1); //低位,等于100
int a2 = *(int*)&a; //高位,为0
printf("%d %d\n", a1, a2, b);
Lactoferrin 2012-04-12
  • 打赏
  • 举报
回复
原因都是,你的计算机上a是8字节,%d处理4字节
njuliao 2012-04-12
  • 打赏
  • 举报
回复

#include <stdio.h>
int main()
{
double a;
a = 100;
char b;
b = 1;
printf("%d %d\n", a, b);
return 0;
}


这个也不对,那怎么解释
Lactoferrin 2012-04-12
  • 打赏
  • 举报
回复
你这相当于
int32_t a_high=0,a_low=100;
char b=1;
printf("%d %d\n",a_low,a_high,b);

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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