zoukankan      html  css  js  c++  java
  • (转载)C语言右移运算符的问题(特别当与取反运算符一起时)

    (转载)http://hi.baidu.com/fanggai/item/1c44f1f2e3d81dc4a935a266

    关键词:C语言,右移运算符,右移运算符+取反运算符,算术右移

    环境:VC6.0

    由一段C语言面试题引起,对其中的某些运算结果有疑惑,写了段小程序测试了下。
    由下面的程序和输出结果得出一些结论:
    1.位运算符不改变原变量的值,即无副作用;
    2.进行取反运算~时,编译器会将char型转换为int型进行计算(VC6.0,其他编译器未测试),这时要特别注意,一般int型字节数比char型多,转换后高位为0,取反后为1,若后续有右移运算,则会将这些1移入,影响计算结果。

    unsigned char a = 0xA5;
    unsigned char b = ~a>>4;
    printf("b= %d \n", b);//245

    a = 0xA5取反后2进制表示为01011010,若按该数值进行右移运算>>4(无论是逻辑右移还是算术右移),则结果应为00000101,对应的十进制数应为5,而输出结果为245,这是为什么呢?
    其实应该是这样的:
    1)将a转换为int型(4字节),即00::0010100101(32位,::表示20个0);
    2)将a取反,则变为11::1101011010(32位,::表示20个1);
    3)a开始右移,右移4位,然后截取低8位赋值给b,即11110101,对应的十进制数值为245。

    附测试程序如下:
    #include <stdio.h>
    int main()
    {

       unsigned char a = 0x11;//初始值最高位为0
    unsigned char b = (~a)<<4;
    printf("b= %d \n", b); //224
    b = ~a<<4;
    printf("b= %d \n", b); //224
    b = ~(a<<4);
    printf("b= %d\n",b); //239

    b = (~a)>>4; //~优先级高于>>
    printf("b= %d\n",b);//254
    b = ~(a>>4);
    printf("b= %d\n",b);//254
    b = ~a>>4; //
    printf("b= %d\n",b);//254


    a = 0xA5; //初始值最高位为1
    b = ~a>>4;
    printf("b= %d \n", b);//245,

    b = (~a)>>4;
    printf("b= %d \n", b);//245,


    a = 0xA5;
    b = a>>4; //没有取反运算
    printf("b = %d \n", b); //10,

    return 0;                                                                  
    }

    3.判断VC6.0是逻辑右移还是算术右移

    #include <stdio.h>
    int main()
    {
      int i = 0x80028002;
      int j = i>>31;   // int型变量可以做移位运算
      printf("j= %d \n", j);  // -1,由此判定右移时还是算术右移
    }

    分析过程:

    上述程序输出j = -1,则推断为算术右移。

    1)i = 0x80028002的二进制表示1000 0000 0000 0010 1000 0000 0000 0010;

    2)由于最高符号位为1,i右移31位,i的二进制表示1111 1111 1111 1111 1111 1111 1111 1111;

    3)i的原码表示1000 0000 0000 0000 0000 0000 0000 0001,故i的值为-1。

    欢迎讨论。


    例子:

    #include <stdio.h>
    
    int main(int argc, char** argv)
    {
        unsigned char a = 0xa5;
        unsigned char b = (~a) >> 4;
    
        char c = 0xa5;
        char d = (~c) >> 4;
    
        printf("%d\n", b);
        printf("%d\n", d);
        printf("\n");
        printf("%d\n", sizeof(~a));
    
        return 0;
    }

    程序输出:

    b = ~a >> 4的运算顺序肯定是a先取反,但a是字符型,进行取反运算的时候编译器自动转换为int型,于是a变成int型。

    然后取反,再进行右移4位操作,就可以得到这个结果了。其实用sizeof(~a)就可以检测出~a之后是int型。

    总结:对char、unsigned char取反时,现将其提升为int类型,然后再进行取反。

  • 相关阅读:
    [Leetcode]@python 89. Gray Code
    [Leetcode]@python 88. Merge Sorted Array.py
    [Leetcode]@python 87. Scramble String.py
    [Leetcode]@python 86. Partition List.py
    [leetcode]@python 85. Maximal Rectangle
    0523BOM
    0522作业星座
    0522dom
    0520
    0519作业
  • 原文地址:https://www.cnblogs.com/Robotke1/p/3076020.html
Copyright © 2011-2022 走看看