百科问答小站 logo
百科问答小站 font logo



C 语言 printf("%f ",3/2) 为什么结果是 0 ? 第1页

  

user avatar   chen-long-13-4 网友的相关建议: 
      

这是 printf 函数的原型

  1. int printf(const char* format, ...);


它接受一个格式化字符串 format 和不固定的若干个参数
这些参数中的浮点数会依次存放在 %xmm0 ~ %xmm7 寄存器,如果浮点数个数超过8个,则超出部分存放在栈上
这些参数中的非浮点数会依次存放在 %edi %edx %ecx %r8d %r8d 寄存器上,如果非浮点数个数超过5个,则超出部分存放在栈上

数据类型/参数序号 0 1 2 3 4 5 6 7 8+

printf 函数在格式化字符串的时候,从左往右扫描 format 字符串中的控制符

  • 遇到 %f 控制符则按顺序读取一个浮点数
  • 否则,按顺序读取一个非浮点数

比如

  1. printf("%d %f %d %f", 1, 2.0, 3, 4.0);


参数存放:1, 2.0, 3, 4.0

  • 1 -> %edi(非浮点数)
  • 2.0 -> %xmm0(浮点数)
  • 3 -> %edx(非浮点数)
  • 4.0 -> %xmm1(浮点数)

format 中参数读取:”%d %f %d %f”

  • 第一个%d <- %edi(非浮点数)
  • 第一个%f <- %xmm0(浮点数)
  • 第二个%d <- %edx(非浮点数)
  • 第二个%f <- %xmm1(浮点数)

以下是用 objdump 后的反汇编代码,也可以证明以上结果

  1. 400535: 48 ba 00 00 00 00 00 movabs $0x4010000000000000,%rdx
  2. 40053c: 00 10 40
  3. 40053f: 48 b8 00 00 00 00 00 movabs $0x4000000000000000,%rax
  4. 400546: 00 00 40
  5. 400549: 48 89 55 f8 mov %rdx,-0x8(%rbp)
  6. 40054d: f2 0f 10 4d f8 movsd -0x8(%rbp),%xmm1
  7. 400552: ba 03 00 00 00 mov $0x3,%edx
  8. 400557: 48 89 45 f8 mov %rax,-0x8(%rbp)
  9. 40055b: f2 0f 10 45 f8 movsd -0x8(%rbp),%xmm0
  10. 400560: be 01 00 00 00 mov $0x1,%esi
  11. 400565: bf 10 06 40 00 mov $0x400610,%edi
  12. 40056a: b8 02 00 00 00 mov $0x2,%eax
  13. 40056f: e8 9c fe ff ff callq 400410 <printf@plt>


回到题主的问题,为什么以下代码的输出结果是0?

  1. printf(“%f ”,3/2)


先看参数存放:3/2

  • 3/2 -> %edi(3/2是整数,非浮点数

format 中参数读取:”%f ”

  • 第一个%f <- %xmm0(浮点数)

我们把参数存放到了 %edi 寄存器了,却希望从 %xmm0 寄存器中读这个参数,显然不会成功。
但是从输出结果为0看,应该是当时 %xmm0 寄存器的数值恰好是0,而这仅仅是巧合而已。

以上是在 x86_64 环境下测试的结果。


user avatar   pansz 网友的相关建议: 
      

不需要,我已经几乎两年没用过有线充电了。

把常用场合都部署好无线充电以后,真的不用操心换手机换充电器之类的事情。

其实很简单的一个问题:取消耳机口之后,各位是改用L口耳机C口耳机,还是改用无线耳机?我曾经以为会普及L口或者C口耳机,然而现实就是无线耳机开始普及。

无线充电座普及之后,由于它没有插拔,所以她的寿命其实远比手机要长。

--

所以,如果你没有无线充,强烈建议你尝试无线充。




  

相关话题

  C 语言的「void main」是怎么一代代传下来的? 
  学 C 语言用 break 和 continue 是不是坏的习惯? 
  int *p=new int,当free(p)时free函数是怎么知道要释放4个字节而不是5个的? 
  有什么C可以实现但C++不能实现的东西吗? 
  C/C++中的数组为什么必须定义之后在一行内立刻赋值,而不能定义数组之后换一行再赋值? 
  C语言题目,字符型输入如何使用switch? 
  C 语言中,x += 5 == 4 是什么意思? 
  这个如此诡异的C语言「怪事」是怎么回事? 
  在c语言当中,for循环,for(i=0;i<10;++i)与for(i=0;i++<10;)啥区别? 
  C/C++ 如何自定义printf函数的格式化符? 

前一个讨论
如果孩子有自闭症,不送她去机构作干预,我平时多陪陪她,送她去学校上学,把他当做普通孩子来养,能自愈吗?
下一个讨论
小提琴曲那个比较有代表性?





© 2024-09-19 - tinynew.org. All Rights Reserved.
© 2024-09-19 - tinynew.org. 保留所有权利