负数赋值给无符号数的陷阱

有没有人尝试过将负数赋给一个无符号整型变量?知不知道这样做会发生什么?还没有尝试的就让我们来探索下无符号整型隐藏的秘密。

先来看看下面代码:

int main()
{
      unsigned int val = -1;
      cout<<val<<endl;

      return 0;
}

执行的结果:

4294967295
请按任意键继续. . .

 

----------------------------------------

你可能禁不住惊叹:这么大!没想到吧,把一个负数赋值给无符号整型变量,会产生这么大的数!为啥呢?好,我们一步步分析:

首先,仔细观察输出的结果4294967295,发现4294967295=2^32-1,哦!好像有点规律!但是,又为啥会是这样?让我们先来讨论下int和unsigned int的表现形式,其中他俩都是4个字节,32位的二进制表示,但int有一位是符号位,unsigned则没有。那-1的int类型表示为1000 0000 0000 0000 0000 0000 0000 0001,那么将其强制转换成unsigned int 应该是1000 0000 0000 0000 0000 0000 0000 0001(红色为符号位),用指数表示是2^31+1,而不是2^32-1!这是怎么回事呢?(*^__^*) 嘻嘻……,这里还隐藏着一个小秘密!那就是int在真正存储在内存中的二进制数不是值的原码,而是其补码(为了便于运算,可以参考《数字逻辑》)!那么在强制类型转换之前,int变量-1内存中存储的是1111 1111 1111 1111 1111 1111 1111 1111,等于2^32-1。soso在强转为unsigned int时,就是读取该块内存的值赋给变量!这样val就变成了4294967295,超级大的数!所以各位同仁在处理unsigned int 赋值时一定要谨慎!如果出错将影响甚大,因为unsigned int一般都会作为for或while循环体的标识类型,如果将负值赋给它,将导致严重的假死循环!痛哉!痛哉!例如以下代码:

for(unsigned u=10;u>=0;u--)

{

   .....

}

 u永远也不会小于0,循环条件将一直成立!!!

 

远离陷阱,珍惜生命!O(∩_∩)O哈哈~

posted @ 2017-02-17 19:07  nullxjx  阅读(1867)  评论(1编辑  收藏  举报