C语言二进制移位运算符

C语言二进制移位运算符,c,bit-manipulation,C,Bit Manipulation,我正在为一个项目学习一些基本的C语言。 在维基百科关于二进制移位运算符的文章中: 如果变量ch包含位模式11100101,则ch>>1将生成结果011110010,ch>>2将生成00111001 为了澄清,如果将二进制运算符的最后一位移到右边(>>1),它会丢失吗?它不会像圆形阵列那样向前旋转,对吗?是的 如果x为无符号或正,则移位操作x>>1将产生一个等于x除以2的值,如果x为负(C.2011§6.5.7¨5),则执行定义移位操作。右侧,除非在移位前保存其值,否则最外层位将丢失: unsig

我正在为一个项目学习一些基本的C语言。 在维基百科关于二进制移位运算符的文章中:

如果变量ch包含位模式11100101,则ch>>1将生成结果011110010,ch>>2将生成00111001

为了澄清,如果将二进制运算符的最后一位移到右边(>>1),它会丢失吗?它不会像圆形阵列那样向前旋转,对吗?

是的


如果
x
为无符号或正,则移位操作
x>>1
将产生一个等于
x
除以2的值,如果
x
为负(C.2011§6.5.7¨5),则执行定义移位操作。

右侧,除非在移位前保存其值,否则最外层位将丢失:

unsigned char ch = 229; 
int lostBit = ch & 0x01;
ch >>= 1;

请注意,位移位运算符
>
仅为无符号或正值定义。在您的示例中,如果
ch
是有符号字符,则值
11100101
实际上表示一个负数(-27),并且该操作将产生未定义的行为。

以下是C(C标准)的圣字关于右移位的说明:

:

E1>>E2的结果是E1右移位E2位位置。如果E1有 无符号类型,或者如果E1具有有符号类型和非负值, 结果的值是E1商的整数部分/ 2E2。如果E1具有有符号类型和负值,则结果为 值是实现定义的

换言之:
x>>n
==
x/2到(n)
,但如果
xC(古老的东西)-你想侮辱吗?:)是的,移出位丢失。在CYes中没有圆形旋转,对吧…Visual Studio对于最新的C标准来说不是一个好的选择。所以你在问Wikipedia在这方面是否正确?这样做并非完全不合理,但如果你认为它是正确的,那么它已经回答了你的问题(是的,而且它是正确的)。@Rizzo最常见和标准的定义选择是
GCC
。我不明白你怎么能在C99和C11上使用VS,因为它不支持它们。事实上,这很有趣,因为如果你说的是你提到的,一个负数的有符号字符呢?(说-2)。我猜实现的定义仅仅意味着基于您所使用的IDE或框架using@KevinHu实现定义和未定义之间的区别在于,您永远不应该调用或依赖未定义的行为,而可以假设特定的实现定义的行为,如果您的代码不需要可移植,并且您的编译器实现正在做您需要的事情。@KevinHu那么它的实现是定义的,这就是为什么在那里使用实际除法可能是一个更好的主意(优化器往往非常聪明,会注意到您正在除以一个2的幂的常数,在这种情况下,他们会将操作转换为程序集级别的位移位)。@KevinHu,“实现定义”意味着C语言实现——实际上是编译器和相关的运行时支持——可以选择,而且它必须记录该选择。该行为对于该实现来说是可靠的。是的,如果您想确保实现之间的可移植性,那么您必须避免依赖于实现定义的行为。Oh、 我明白了。定义的实现也可以处理未签名和已签名的,对吗?我相信如果您不指定标识,那么实现会为您做这件事(内存占用较少,但更危险)