C中的按位移位 [英] Bitwise shift in C

查看:93
本文介绍了C中的按位移位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些使我感到困惑的C代码:

I got some C code that confuses me:

int a = 1;
int b = 32;
printf("%d\n %d\n", a<<b, 1<<32);

输出为

1
0

该代码在Ubuntu 16.04(Xenial Xerus)上运行,我在GCC版本5.4.0中使用gcc -m32 a.c对其进行了编译.

The code was run on Ubuntu 16.04 (Xenial Xerus), and I compiled it using gcc -m32 a.c with GCC version 5.4.0.

我已经阅读了一些文章,这些文章解释了a<<b为什么输出1的原因,但是我不明白为什么1<<32的结果为0.我的意思是a<<b1<<32的区别是什么?

I've read some posts that have explained why a<<b outputs 1, but I don't understand why 1<<32 results to 0. I mean, what is the difference between a<<b and 1<<32?

推荐答案

将32位int左移32是未定义的行为,因此任何值都可以产生.如果使用1<<32表达式,您的C编译器应警告您.

Shifting a 32-bit int left by 32 is undefined behavior, so any value could be produced as the result. Your C compiler should warn you about it in case of 1<<32 expression.

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

The reason the two outputs that you see are different is that they are produced by different code paths:

  • a << b使用变量,因此它是在运行时由编译后的代码计算的
  • 1<<32是一个常量表达式,因此它是在编译时由编译器本身计算的.
  • a << b uses variables, so it is computed at runtime by the compiled code
  • 1<<32 is a constant expression, so it is computed at compile time by the compiler itself

看起来编译后的代码执行模32的移位,所以32的移位与零的移位相同.但是,编译器本身会移位32,从而使末尾减少一位.编译器可以自由地执行此操作,因为此行为是未定义的.因此,该标准不需要任何特定的行为,甚至不需要在同一程序的各个部分之间保持一致的行为.

It looks like the compiled code performs the shift by modulo 32, so shift by 32 is the same as a shift by zero. The compiler itself, however, shifts by 32, dropping the one bit off the end. The compiler is free to do this, because this behavior is undefined. Hence, the standard does not demand any particular behavior, or even a consistent behavior among parts of the same program.

这篇关于C中的按位移位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆