取反操作的细节问题

首先看以下一段代码:
1  #include  < cstdio >
2 
3  int  main()
4  {
5      unsigned  char  t  =   0xa5 ;
6      unsigned  char  i  =  ( ~ t) >> 4 ;
7      printf( " %x\n " , i);
8       return   0 ;
9  }

建议最好仔细先想一下再往下看

对于char、bool、unsigned char等低于int字节数的类型,进行运算的时候首先进行提升,因此在进行~t运算之前,先要将其放入32位寄存器,由于是unsigned char,因此前面补位全补0,因此0xa5-->0x000000a5,然后取反为0xffffff5a,然后再向右移四位为0xfffffff5,然后再转化为unsigned char型的0xf5赋值给i,因此最后输出结果为0xf5

再看下面这段代码:
1  #include  < cstdio >
2 
3  int  main()
4  {
5       char  t  =   0xa5 ;
6       char  i  =  ( ~ t) >> 4 ;
7      printf( " %x\n " , i);
8       return   0 ;
9  }

思想和上面的完全相同,还是先提升为int然后再进行运算,但是注意这里是char型,因此提升的时候应该是根据最高位进行提升,最高位为1则前面全补全为1,否则全补全为0。因此再进行~t操作前应该先补全为0xffffffa5,然后进行取反操作为0x0000005a,然后再右移四位为0x00000005,再转化成char型的0x05赋值给i,因此最后结果为0x5

再看最后一个例子:
 1  #include  < cstdio >
 2 
 3  int  main()
 4  {
 5       char  a  =   0x80 ;
 6       char  b  =   0x2 ;
 7      unsigned  char  c  =   0x80 ;
 8      unsigned  char  d  =   0x2 ;
 9      printf( " %x\n " , a  /  b);
10      printf( " %x\n " , c  /  d);
11       return   0 ;
12  }
13 

主要是巩固前面说过的情况,非常类似,进行运算之前,a、b、c、d都要先补齐为:
a--->0xffffff80
b--->0x00000002
c--->0x00000080
d--->0x00000002
然后再进行运算,因此结果为:
0xffffffc0
0x40

最后再总结一下:unsigned char、char、bool等低于int型的类型,进行运算的时候都要先提升再运算,提升时根据signed和unsigned,在前面补位为0或者1,若是unsigned,则直接前面全补0;若为signed,则根据最高位为0还是1,若为0则全部补位为0,若为1则全部补位为1。


转载链接:http://www.cppblog.com/myjfm/archive/2011/04/08/143572.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值