您好我在按位运算符和移位方面遇到了一些问题。我相信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;
}
答案 0 :(得分:2)
您需要将flag_holder
的类型更改为unsigned
。假设您的int
是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
。这也可以写成:
*flag_holder = *flag_holder | (1U << flag_position);
check_flag()
也存在问题。位移代码需要更改为:
int bit = (flag_holder >> flag_position) & 1U;
在使用&
运算符提取之前,这会将感兴趣的位移动到最低位置。它的编写方式是左移,&
始终与0
位进行比较。