C语言中的移位操作

C语言中的移位操作,c,bit-manipulation,bit-shift,C,Bit Manipulation,Bit Shift,是否可以像在C档换档操作中换档1s那样换档0s 像这样的 for (i=0; i<32; i++) { if (data & 0x01) { data |= (1<<i); } else { data &=~ (0<<i); } } 对于(i=0;i您不移动0或1,您移动位值,无论是0还是1。换句话说,您移动位位置,而不考虑其中存储的值 来自C11标准,第§6.5.7章,位移位运算

是否可以像在C档换档操作中换档
1
s那样换档
0
s

像这样的

for (i=0; i<32; i++) {
    if (data & 0x01) { 
        data |= (1<<i);
    }
    else { 
        data &=~ (0<<i);
    }
}

对于(i=0;i您不移动
0
1
,您移动位值,无论是
0
还是
1
。换句话说,您移动位位置,而不考虑其中存储的值

来自
C11
标准,第§6.5.7章,位移位运算符


E1的结果不是移位
0
1
,而是移位位值,可以是
0
1
。换句话说,移位位位置,而不考虑存储在其中的值

来自
C11
标准,第§6.5.7章,位移位运算符


E1的结果是好消息是——你想得太多了

取整数,说:
01011011

将其向左移动1:
10110110

“整件事”一起移位;零被移位到LSB中。在右移的情况下,对于无符号,再次为零,或者对于有符号数字定义的实现:

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

()

这意味着有符号数字右移可能导致算术移位或逻辑移位



如果你想把
1
s移到低端,而不是
0
s,只需或用一个位掩码来表示你移动的位置数。

好消息是——你想得太多了

取整数,说:
01011011

将其向左移动1:
10110110

“整件事”一起移位;零被移位到LSB中。在右移的情况下,对于无符号,再次为零,或者对于有符号数字定义的实现:

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

()

这意味着有符号数字右移可能导致算术移位或逻辑移位



如果要将
1
s移到低端,而不是
0
s,只需或使用位掩码来表示移位的位数。

移位操作是使用CPU寄存器执行的。寄存器由许多位组成(8、16和32是常见的,并且您似乎有一个32 CPU),其组合可以解释为十进制值

在您的示例中,您使用值1。C语言允许以多种方式表示值1,所有这些都会导致CPU寄存器的内容相同:

decimal      hexadecimal  binary
1            0x00000001   0b00000000000000000000000000000001
3713883835   0xDD5D5EBB   0b11011101010111010101111010111011
(在所有情况下,可以省略前导的
0
s。)


在二进制表示法中,指定了所有CPU寄存器位值。如您所见,这包括0和1。因此,当您将值1放入寄存器并使用
执行左移位时,移位操作将使用CPU寄存器执行。寄存器由许多位组成(8、16和32是常见的,您似乎有一个32 CPU),组合起来可以解释为十进制值

在您的示例中,您使用值1。C语言允许以多种方式表示值1,所有这些都会导致CPU寄存器的内容相同:

decimal      hexadecimal  binary
1            0x00000001   0b00000000000000000000000000000001
3713883835   0xDD5D5EBB   0b11011101010111010101111010111011
(在所有情况下,可以省略前导的
0
s。)


在二进制表示法中,所有CPU寄存器位值都是指定的。如您所见,这包括0和1。因此,当您将值1放入寄存器并使用
执行左移位时,移位是同时“移位”0和1。首先,
为什么要清除?我只是在屏蔽(检查)所需位并在移位运算符的帮助下将其存储在新变量中设置位我需要使用|=运算符组合和清除需要使用&=~移位是“移位”0和1。首先,
为什么要清除?我只是屏蔽(检查)所需位,并在移位运算符的帮助下将其存储在新变量中。要设置位,我需要使用|=运算符组合,并清除需要使用&=~如果我移位变量,它是否会在将来的操作中保留该值?@Lazar未来的操作是什么?请参阅,
生成移位值。如果要存储值,您必须将移位后的值分配回变量本身。就像执行
i+1
不会改变
i
,但
i=i+1
会改变一样。因此,要获得新的变量值,我们需要在应用操作的新变量或现有变量中分配该值。当在/递减或移位变量时,var的值iable在分配给它自己之前不会改变,就像你对i所说的那样。如何设置一些位,但设置为变量,但不影响已存储在其中的其他位?@Lazar 1)是的2)这就是按位运算符的含义。如果我移动变量,它是否会在未来的操作中保留该值?@Lazar未来的操作是什么?请参见,
>
产生移位值。如果要存储该值,必须将移位后的值赋回变量本身。就像执行
i+1
不会改变
i
,但
i=i+1
会改变。因此,要获得新的变量值,我们需要在应用操作的新变量或现有变量中指定该值。当输入/递减或移位变量时,变量的值在分配给它自己之前不会改变,就像你们对i所说的那个样
for(i=0;i<32;i++)
{
    data = (165 << i) // 165 = 0xA5 = 0b10100101
}

Produces:
i = 0,  data = 0x00000000000000000000000010100101
i = 1,  data = 0x00000000000000000000000101001010
i = 2,  data = 0x00000000000000000000001010010100
etc.
i = 28, data = 0x10100000000000000000000000000000
i = 29, data = 0x01000000000000000000000000000000
i = 30, data = 0x10000000000000000000000000000000
i = 31, data = 0x00000000000000000000000000000000