当我阅读K& R时,我对此代码感到困惑:
#include "syscalls.h"
int getchar(void)
{
char c;
return (read(0, &c, 1) == 1) ? (unsigned char)c : EOF;
}
据说unsigned char用于避免此代码中符号扩展带来的错误。 这是我能想到的唯一案例,我给出了这个示例代码:
char c = 0xf0; //11110000, just make highest bit > 1
printf("%i\n",(int)(unsigned char)c);
printf("%i\n",(int)c);
Output: 240 // 0...011110000
-16 // 1...111110000
但实际上ascii只有0~127 最高位不能分配给1.为什么K& R cast char>>无符号的字符?
答案 0 :(得分:3)
ASCII 仅限于0..127
范围,但不仅是read
可以读取的ASCII - 在K& R中,它可以得到整个{{1} } 0..255
值的范围。
这就是char
返回getchar
的原因,因为它必须能够返回任何 int
值加上特殊的char
值。
通过将字符转换为EOF
,然后在返回时将其提升为unsigned char
,它会阻止值int
进行符号扩展。如果您允许该符号扩展,您将无法区分255(将签名扩展到所有1位)和128..255
(-1为-1,所有1位)之间的区别。
我并非完全确定你使用K& R来学习语言的策略顺便说一句。从那时起,C已经采用 long 方式。从内存来看,即使是最新的K& R书仍然是C89 / 90 ANSI标准(在ISO基本上接管责任之前),并且该语言从那时起已经通过两次大规模升级。
答案 1 :(得分:1)
unsigned char变量的值介于0到255之间,对于类型转换的要求,请遵循同一本书中的注释
Whether plain chars are signed or unsigned is machine-dependent, but printable characters are always positive.
现在,如果我们谈论c标准,那么它给出如下
The implementation shall define char to have the same range, representation, and behavior as either signed char or unsigned char.
答案 2 :(得分:1)
return (read(0, &c, 1) == 1) ? (unsigned char)c : EOF;
表示:将一个字符读入c;如果你能读到至少一个字符,那就归还它;否则返回(int)EOF。
请注意,getchar()返回一个int,因此转换为char-> unsigned char-> int