欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

一个C里容易忽略的细节

一个C里容易忽略的细节

今天发现了一个C里容易忽略的细节。
由于这个小细节,我的程序调试了半天,耽误了不少功夫。
现在拿出来和大家分享一下~共同进步~。
首先,VC下的,一个很简单的程序
# include <stdio.h>
int main ()
{
  short int a ;
  a = 0x8000 ;

  if (a == 0x8000)
    printf ("T\n") ;
  else
    printf ("F\n") ;
  return 0 ;
}

大家猜才结果是什么呢?
答案是F。
如果你认为是T,呵呵,最好自己调试一下,找到原因,不太难的,找不到的话再往下看~~
(如果你认为本来就是F,理由是short int 的范围是-32768到32767,这里0x8000是32768,溢出了,不相等,那么,不好意思,你的理解有偏差。不信你把short int换成int,再把0x8000扩展到0x80000000,同样的问题在int型的时候输出T,怎么解释?~)
这里,a是short int型,占两个字节。当我们把0x8000赋给a后,a中的值为
1000 0000 0000 0000(二进制)
在执行if条件时,程序要把a的值和立即数0x8000进行比较。
但是a的值保存在内存当中,于是程序会将a的值从内存里取到寄存器中(通常是eax)
mov eax, a的地址   ;    这个是假想生成的代码
但是a的值只有2字节,eax有4字节。这里编译器在取的时候做了一个符号扩展:
movsx eax, a的地址    ;  这个是实际生成的代码

这样,编译器其实是拿eax里,也就是a的值符号扩展后,也就是0xffff8000和0x8000进行比较,判定为不相等。

现在,如果把short int 换成int,0x8000换成0x80000000就不会出现判断失误的问题了。因为int和eax是等长的,没有进行符号扩展。

分析完毕。请各位高手拍砖留情~

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功