你好,我对按位运算符和移位有一些问题。我相信check_flag()
是有效的,但set_flag()
不是。有人能解释一下怎么回事吗?
#include <stdio.h>
void set_flag(int* flag_holder, int flag_position);
int check_flag(int flag_holder, int flag_position);
int main(int argc, char* argv[])
{
int flag_holder = 0;
int i;
set_flag(&flag_holder, 3);
set_flag(&flag_holder, 16);
set_flag(&flag_holder, 31);
for(i=31; i>=0; i--)
{
printf("%d", check_flag(flag_holder, i));
if(i%4 == 0)
{
printf(" ");
}
}
printf("\n");
return 0;
}
void set_flag(int* flag_holder, int flag_position)
{
*flag_holder = *flag_holder |= 1 << flag_position;
}
int check_flag(int flag_holder, int flag_position)
{
int bit = (flag_holder << flag_position) & 1;
if(bit == 0)
return 0;
else
return 1;
return bit;
}
最佳答案
您需要将flag_holder
的类型更改为unsigned
。假设您的int
s是32位宽,当您设置高阶位(位置31)时,您是在设置符号位。这将导致右位移位的实现定义行为和左位移位的未定义行为。set_flag()
函数应更改为:
void set_flag(unsigned* flag_holder, int flag_position)
{
*flag_holder |= (1U << flag_position);
}
在将位设置为
flag_position
中的flag_holder
之前,这会将位移到位置。1U
是只设置了最低阶位的unsigned int
位;(1U << flag_position)
将单个设置位移到左侧。flag_position
运算符相当于将按位或的结果和移位的位赋给|=
。这也可以写成:*flag_holder = *flag_holder | (1U << flag_position);
*flag_holder
中也有问题。位移位码需要更改为:int bit = (flag_holder >> flag_position) & 1U;
这会在使用
*flag_holder
运算符提取之前将感兴趣的位移到最低阶位置。用左移位的方式写时,check_flag()
总是与&
位比较。关于c - C中的按位运算符和移位问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41864691/