C 移位计数操作允许哪些值? #包括 内部主(空) { 无符号整数var=1; var=var

C 移位计数操作允许哪些值? #包括 内部主(空) { 无符号整数var=1; var=var,c,bit-shift,C,Bit Shift,C116.5.7位移位运算符 如果右操作数的值为负数或大于或 等于提升的左操作数的宽度,行为为 未定义 这意味着在这种情况下,如果移位32位或更多位,则没有定义良好的行为。任何情况都可能发生,包括崩溃和奇怪的结果 我从我的旧教科书中读到,ANSI C不允许在一次操作中将一个值的所有位移位 这是正确的,您必须执行几个位操作,例如xc16.5.7位移位运算符 如果右操作数的值为负数或大于或 等于提升的左操作数的宽度,行为为 未定义 这意味着在这种情况下,如果移位32位或更多位,则没有定义良好的行为。

C116.5.7位移位运算符

如果右操作数的值为负数或大于或 等于提升的左操作数的宽度,行为为 未定义

这意味着在这种情况下,如果移位32位或更多位,则没有定义良好的行为。任何情况都可能发生,包括崩溃和奇怪的结果

我从我的旧教科书中读到,ANSI C不允许在一次操作中将一个值的所有位移位


这是正确的,您必须执行几个位操作,例如
xc16.5.7位移位运算符

如果右操作数的值为负数或大于或 等于提升的左操作数的宽度,行为为 未定义

这意味着在这种情况下,如果移位32位或更多位,则没有定义良好的行为。任何情况都可能发生,包括崩溃和奇怪的结果

我从我的旧教科书中读到,ANSI C不允许在一次操作中将一个值的所有位移位


这是正确的,您必须执行几个位操作,例如,
xGCC字面上说您回答:
左移位计数>=类型的宽度[-Wshift count overflow]


它还取决于您使用的体系结构。您的问题已经得到了回答。

GCC字面上说您回答:
左移位计数>=类型的宽度[-Wshift count overflow]


它还取决于您所使用的体系结构。您的问题已经得到了回答。

只是为了更深入一点:

经典的C语言是作为“可移植汇编程序”开发的。内置操作只是大多数CPU实现的操作,它们的语义为可移植性提供了最低的公分母

几乎每个CPU都提供左移和右移操作,但是平台在溢出和负数等细节上有所不同,所以C标准没有定义角情况


特别是,对于大于寄存器宽度的移位计数,许多CPU只使用所需的位数,并截断其余的位数。当计数为常量时,编译器可能会注意到未定义的行为,并将该操作作为垃圾丢弃。

只是为了更深入一点:

经典的C语言是作为“可移植汇编程序”开发的。内置操作只是大多数CPU实现的操作,它们的语义为可移植性提供了最低的公分母

几乎每个CPU都提供左移和右移操作,但是平台在溢出和负数等细节上有所不同,所以C标准没有定义角情况


特别是,对于大于寄存器宽度的移位计数,许多CPU只使用所需的位数,并截断其余的位数。当计数为常量时,编译器可能会注意到未定义的行为,并将该操作作为垃圾丢弃。

移位的位数超过数据类型中的位数会导致未定义的行为。因此将32位变量移位32位(或更多)是无效的。@Badda这不是有意义的重复,因为C在进行位移位时有很多特定于语言的行为。可能的重复行为是未定义的行为,因为
32
超出范围[0-31].移位的位数超过数据类型中的位数会导致未定义的行为。因此,将32位变量移位32位(或更多)位无效。@Badda这不是有意义的重复,因为C在位移位时有很多特定于语言的行为。可能的重复是未定义的行为,因为
32
超出范围[0-31]。如果我键入
var=12;
然后键入
var=var@Mynicks它是完全未定义的,即使在同一个编译器上也是如此。GCC可能今天输出12,明天输出42,然后第二天崩溃并烧掉。这里的关键是你不能依靠未定义的行为来给出某种行为……因此是未定义的。@Mynicks,如果某些行为未定义ur在C中,那么它总是和到处都是未定义的。GCC似乎只是跳过了整个移位操作,因为结果是未定义的(也称为无用)无论如何。如果我键入
var=12;
然后键入
var=var@Mynicks它是完全未定义的,即使在同一个编译器上也是如此。GCC可能今天输出12,明天输出42,然后第二天崩溃并烧掉。这里的关键是,您不能依靠未定义的行为来给出某种行为……因此未定义。@Mynicks,如果有什么未定义的话在C中的行为,那么它总是和到处都是未定义的。GCC似乎只是跳过了整个移位操作,因为结果是未定义的(也称为无用)。
#include <stdio.h>

int main(void)
{
    unsigned int var=1;
    var = var<<32;
    printf("%u ",var);
}