我已经检查了已经发布的问题,但无法完全找到我的问题的解决方案......
我正在制作一个控制台程序,它输入 2 个变量:1 个是一个字节,另一个是我需要仅使用掩码和 if 语句从该字节获取的数字。
int E1 () {
unsigned char a, b, c;
printf("Number (byte):");
scanf("%d", &a);
a= (unsigned char)a;
printf("n Bit you want to output (between 0 and 7) :");
scanf("%d", &b);
b=(unsigned char)pow((float)2.0,b);
printf("Mask is: %d", b);
c= a & b; //<-- This returns 0
if (c>0) {
printf("nnThe bit is: 1");
}
else {
printf("nnThe bit is: 0");
}
return 0;
}
我问过我的老师,他说应该可以正常工作。我试过了,但它不起作用。他正在使用Visual Studio Express,可以从Microsoft网站上获得的免费版本,而我使用的是Code::Blocks(以防这对结果产生影响(。我在我认为问题出在哪里但不确定的地方添加了评论。
任何人都可以帮我解决这个问题。提前谢谢。
使用 1<<b
作为掩码。它不仅是惯用的,而且比使用浮点计算效率高得多。所以删除这一行:
b=(unsigned char)pow((float)2.0,b);
并像这样设置c
:
c = a & (1<<b)
这样效果更好吗?
一些测试告诉我,这部分是错误的:
scanf("%d", &a);
这实际上是未定义的行为:它可能有效,也可能无效,但你不能真正依赖任何东西。这是因为虽然a
只是一个 1 字节的字符,而%d
需要一个 4 字节的整数,这意味着scanf
写入四个字节的内存而不是一个字节。
这有一个不幸的副作用,即第二次调用(scanf("%d", &b)
(可能会使用存储程序中其他一些变量的内存,在本例中为 a
。这会被覆盖并设置为 0,从而导致表达式 0 & b
当然计算结果为 0
。
解决这个问题的正确方法是使用%hhd
而不是%d
,这使得scanf
期望char
而不是int
,并且只写入1字节的内存。
关于代码的旁注
- 行
a = (unsigned char) a;
是无用的,因为a
已经是unsigned char
型了。 - 正如 Graham 在他的回答中指出的那样,在计算 2 的幂时,你应该使用
b = (1 << b);
,因为这是更漂亮的代码,也更有效率——许多现代 CPU 只需一条指令即可做到这一点。
printf("The bit is: %d", 1 & a>>b);