【发布时间】:2017-03-21 15:12:14
【问题描述】:
在以下示例中,打印全为 1 的字节的位表示:
#include <stdio.h>
int main (void)
{
char c = 255;
char z;
for (int i = 7; i >= 0; i--) {
z = 1 << i;
if ((z & c) == z) printf("1"); else printf("0");
}
printf("\n");
return 0;
}
输出为11111111
现在我们把char c改成int c,这样例子就变成了:
#include <stdio.h>
int main (void)
{
int c = 255;
char z;
for (int i = 7; i >= 0; i--) {
z = 1 << i;
if ((z & c) == z) printf("1"); else printf("0");
}
printf("\n");
return 0;
}
现在输出是01111111。
为什么输出不同?
更新
编译如下test.c:
#include <stdio.h>
int main(void)
{
char c=-1;
printf("%c",c);
return 0;
}
$ gcc test.c
$ ./a.out | od -b
0000000 377
0000001
输出为 377,表示 glibc 与 gcc 相矛盾,因为有符号字符会自动转换为无符号字符。 为什么会有这样的并发症?默认情况下让 char 无符号是合理的。有没有什么具体的原因?
【问题讨论】:
-
如果您需要特定的位宽,请使用来自
stdint.h的固定宽度类型。并且在移位时,通常最好使用无符号类型,因为有符号整数上的某些移位/值是实现定义的,甚至会调用未定义的行为。
标签: c type-conversion implicit-conversion