关于数据在内存中存储的运算

 

     在这里首先简单介绍下,整型提升和类型转换,以方便后面程序分析中应用到

整型提升

    

  C语言之父的著作 K&R 中关于整型提升(integralpromotion)的定义为:

  "A character, a short integer,or an integer bit-field, all either signed or not, or an object of    enumerationtype, may be used in an expression wherever an integer maybe used. If an intcan represent all the values of the original type, then the value is convertedto int; otherwise the value is converted to unsigned int. This process iscalled integral promotion."


  归纳总结为两个原则如下:

   1). 一个表达式中凡是可以使用整型的地方,都可以使用char、short int 或者整型位域(这几个基本类型无论是否带符号都可) 的变量,以及枚举类型的对象。

   2). 如果1)中的变量的原始类型的所有值都可以被int表示,那么原值被转换为int; 否则的话,转为unsigned int型。


  那么问题来了,为什么要整形提升呢?

  通常情况下,在对int类型的数值作运算时,CPU的运算速度是最快的。在x86上,32位算术运算的速度比16位算术运算的速度快一倍。C语言是一个注重效率的语言,所以它会作整型提升,使得程序的运行速度尽可能地快。因此,你必须记住整型提升规则,以免发生一些整型溢出的问题。


类型转换


         不同类型数据之间进行算数运算时,会将所有操作数转换为同种类型,并以此作为结果的类型,这种方式称为普通算术类型的转换。

        总结:普通算术类型转换只在在操作数之间类型不一致的情况下发生,整型提升在操作数具有相同的类型时,仍有可能发生整型提升


例题:

    1.下面程序的输出结果是什么

         

      分析:

               sizeof(a+b)   a+b是一个算术表达式,且都为char型,符合整型提升的条件,所以需对ab进行整型提升,a、b均整型提升(int型),所以占4个字节

               sizeof(c=a+b) 表达式c=a+b中,a和b是算术运算,因此整型提升(int型),计算结果(int型)再赋值给c(char型),又执行了隐式的类型转换,所以最终占1字节。

     2.

         

    

       分析:-1的补码序列(11111111),现在以%d的形式输出,所以需要对-1的补码形式整形提升,

               (提升时补符号位,无符号数提升时补0)

         注:char在此运行环境中被看作有符号数

                对于a (-1)整形提升后补码的形式为:

                      11111111 1111111111111111 11111111  (以%d输出时,最高位为1,负数,)

                减1,取反后得到原码:

                      10000000 0000000000000000 00000001 (-1

       同理,可分析b

               对于c(-1)无符号数整形提升后的补码形式为:

                      00000000 0000000000000000 11111111  (最高位为1,正数(255))

   3.

         

          

         这个就很奇怪了,为什么会输出一个这么大的数字?   char存储不应该就是只有8位,最大表示为127.

         分析:-128补码(1000000),现在以%u形式输出,(整形提升)

                 -128 整形提升后补码形式:

                 11111111 11111111 1111111110000000

        还有这里的%u,我们都应该知道数据在内存中是以补码形式存储的,现在%u输出也就是认为你就是无符号数,所以在%u的角度来讲,它直接从你的内存中拿出来的就是原码,直接输出内存中拿出来的数据.

      4.

          

     这里是不是感觉很奇怪,char表示的范围为-128—127,chara=128有时如何存储的呢?在这里我是这样理解的,先不考虑是否能存下,对于128直接存入内存则为00000000 00000000 00000000 10000000,然后截取低八为,即为10000000再然后的分析同题。


     5.

             

        这里有为什么是-10呢?只需要按补码的形式进行运算,最后转化为有符号数

        -20原反补码如下:

             10000000 00000000 00000000 00010100

             11111111   11111111   11111111   11101011

             11111111    11111111   11111111  11101100

      10的原反补码相同

             00000000 00000000 00000000 00001010

      -20+10结果为;

             11111111 11111111 11111111 11110110

       减1,取反得原码为:

             10000000 00000000 00000000 00001010 (-10

   6. 这段程序会在屏幕上输出什么呢

     

    

         答案是死循环,这又是为什么呢

          注意这里的i为无符号数,永远大于0,所以为死循环

     7.

     

       第一种:a[i]=i-1

       运行结果为:1

       分析:a数组中存储的元素为{-1,0,1,2 ……}

                  Strlen(a)求字符串长度,遇到‘\0

       第二种:a[i]=-1-i

      运行结果为:255

       分析:a数组中的元素{-1,-2....,-128,127,126...3,2,1,0...}


 这里简单介绍下关于对于char类型取值范围的图解:

             

    8.

       

  

    short int取值范围为-32768--32767

    类别上图char 的取值范围图解,可推理得出答案。

 9.

   

     这个结果为死循环,不难理解,因为unsigned char 的取值范围为0—255


    上面即是关于数据在内存中存储的一些运算题,再解决上面问题的过程中,我们应很好的理解整形在内存中的存储,以及运算过程中的整型提升与类型转换。





   

        






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值