zoukankan      html  css  js  c++  java
  • C——整数溢出

    短的整数类型赋值给长的整数类型

    • 示例代码

      void main()
      {
      	int w = 0x12345678;
      	unsigned short r = -2;
      	w = r;
      	printf("%d
      ", w);
      	getchar();
      }
      
    • 上面结果最后是,65534,这是无符号的,如果是有符号呢?结果是,-2,这里的过程如下

      • 无符号 short 后面挂了一个负数,显示是超过了范围,但是从语法上是不会报错的,那么在内存中又是怎么存储 -2呢
      • 依然按照有符号的方式存储 -2,最高位是符号位,数值1, 因为是负数,那么存储是按照补码方式存储,结果是,1111 1111 1111 1110
      • 赋值操作是整个替换,int 类型后面 16位被 1111 1111 1111 1110 占据,前面 16位会按照 short 类型判断,进行填充,因为此时 short 是无符号类型,所以 int 不会管 short 最高位是1还是0,前16位全部补充0
      • 0000 0000 0000 0000 1111 1111 1111 1110,这是最后内存的形式
      • printf 参数 %d,是按照 int 类型的有符号方式输出成十进制的数,所以它认为上面的结果是正数,所以其源码和补码一致,不用进行转化,结果输出,65534
      • 下面说有符号的时候的为什么输出结果是 -2,内存将 -2 按照补码进行存储,也就是,1111 1111 1111 1110
      • 赋值给 int 类型的时候,它依然会判断 short 类型,因为是 short 是有符号类型,它会根据 short 符号位填充自己的前16位,如果short 符号位是1,那么前16位都会是1,所以结果是,1111 1111 1111 1111 1111 1111 1111 1110
      • printf 参数是 %d,它会依据有符号 int 类型方式输出成十进制的数,所以判断上述结果符号位,结果是1,需要将补码再次转成源码(与转补码过程一致),结果是 1000 0000 0000 0000 0000 0000 0000 0010,最后结果是 -2

    长的整数类型赋值给短的整数类型

    • 示例代码

      void main()
      {
      	int w = 0x12349678;
      	unsigned short r = 1;
      	r = w; 
      	printf("%d
      ", r); 
      	getchar();
      }
      
    • 上面结果最后是 ,38520,这是无符号,那么如果是有符号呢?结果是,-27016,换了符号结果的变化过程如下

      • 0x12345678,是一个正数,所以在内存中它的补码就是它的原码,00001 0010 0011 0100 1001 0110 0111 1000
      • short 类型长度就是2个字节,所以它能获取到的数值就是 9678,继承来的补码为,1001 0110 0111 1000
      • printf 参数是 %d,其含义是输出有符号的 int 类型的十进制数值,所以需要将 short 类型往前填充16位,这个过程与上面 short类型赋值给 int 过程是一致,先判断 short 是否有符号,无符号直接填充16个0,又因为是正数,所以不用再次转码,所以最后输出是 ,38520
      • 那么有符号的为什么是,-27016呢,原因还是 printf 后面补位的原因,因为此时 short 是有符号的,又由于 short 符号位是1,那么前16位都会是1 ,1111 1111 1111 1111 1001 0110 0111 1000 ,又因为是负数,所以还需要转码,那么最后二进制转码之后是,1000 0000 0000 0000 0110 1001 1000 1000,所以最后是 ,-27016

    最后的关于 short、int 一些总结

    • 示例代码

      void main() {
          unsigned short num = -2;
      	printf("%d", num);
      	getchar();
      }
      
      
    • 有无符号对输出结果的影响是很明显的 ,上面的结果无符号是,65534,有符号是,-2,

    • 主要原因是补位过程,会根据数据类型,来进行补位,如果是 unsigned 修饰,那么直接不用判断,直接补0,如果没有 unsigned 修饰,才去判断具体数的符号位,如果是1,就直接补16个1,如果是0,则还是补16个0

    帮助文档

  • 相关阅读:
    Windows永久修改pip安装源
    MySQL 超键 候选键 主键 外键是什么
    scrapy中间件
    crawlspider
    scrapy
    MongoDB 命令
    如何反扒
    表前缀sw_时
    自增序号,而且默认变量就是$i,也就是说在你的volist标签之内,可以直接使用$i
    html,if标签使用
  • 原文地址:https://www.cnblogs.com/cnloop/p/9292543.html
Copyright © 2011-2022 走看看