c/c++语言开发共享C中的按位移位

我得到了一些令我困惑的C代码:

int a = 1; int b = 32; printf("%dn %dn", a<<b, 1<<32); 

输出是

 1 0 

代码在Ubuntu 16.04(Xenial Xerus)上运行,我使用GCC版本5.4.0的gcc -m32 ac编译它。

我读过一些post已经解释了为什么a<<b输出1,但我不明白为什么1<<32结果为0.我的意思是, a<<b1<<32之间a<<b什么区别?

    将32位int移位32是未定义的行为,因此可以生成任何值作为结果。 在1<<32表达式的情况下,您的C编译器应该警告您。

    您看到的两个输出不同的原因是它们由不同的代码路径生成:

    看起来编译的代码按模32执行移位,因此移位32与移位零相同。 然而,编译器本身移位32,将一位丢弃。 编译器可以自由地执行此操作,因为此行为未定义。 因此,该标准不要求任何特定行为,甚至同一程序的各部分之间的一致行为。

    a<1<<32未定义的行为 ,因为右操作数等于位数。

    C11§6.5.7按位移位算子

    第3段:

    对每个操作数执行整数提升。 结果的类型是提升的左操作数的类型。 如果右操作数为负数,或者大于或等于左表达式类型中的位数,则结果为undefined。

    第4段:

    E1 << E2的结果是E1左移E2位位置; 腾出的位用零填充。 如果E1具有无符号类型,则结果的值为E1 × 2E2 ,模数比结果类型中可表示的最大值减1。 如果E1具有有符号类型和非负值,并且在结果类型中可以表示E1 × 2E2 ,那么这就是结果值; 否则, 行为未定义。

    因此,如果数字的移位大于整数的大小,则行为是未定义的。

    GCC产生警告:

     warning: left shift count >= width of type [-Wshift-count-overflow] printf("%dn%d",a< 

    通过恒定值移位而不是移位b位可以导致在未定义的行为可能优化不存在的规则下的不同行为。 换句话说,移位恒定值可能与移位可变位数的方式不同。 两者都显然是未定义的行为,因此编译器可以随心所欲地处理任何一种情况。 它可以从字面上生成随机数。

    转移签名值是危险的,应该避免。

    如果int的大小是32位,则1 << 31是依赖于实现的 - 二的补码= -2147483648。 -1 << 31给出相同的结果。

    如果将值> =次移位,则结果未定义的位数。

      以上就是c/c++开发分享C中的按位移位相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/560381.html

      (0)
      上一篇 2021年1月27日
      下一篇 2021年1月27日

      精彩推荐