C语言中EOF与char比较的类型转换两大核心疑问
char类型与EOF比较的常见问题
先看这段存在不良实践的代码:
char c; while ((c = getchar()) != EOF) { ... }
问题核心是值为0xFF的char会和EOF混淆,但很多人会疑惑类型提升规则为啥没起作用,下面逐个解答疑问:
疑问1:读取到0xFF的char,为何不会先转int再和EOF比较?
问题出在赋值环节,不是比较环节:
getchar()的返回值是int类型,读取到字节0xFF时,返回的是0x000000FF(以32位int为例);- 当把这个值赋值给
char c时,若编译器默认char为有符号类型,0xFF会被转换成有符号char的-1(遵循补码规则); - 到
c != EOF的比较阶段,c确实会被提升为int,但此时它已经是-1,而EOF通常被定义为-1,两者相等,导致循环提前终止,无法正确读取0xFF这个字节。
如果char是无符号类型,这个问题不会出现,但char的有符号性由编译器决定,所以用char存储getchar()返回值本身就是不可移植的不良实践,正确做法是用int c来接收。
疑问2:二进制1111 1111的char转16位int,结果是啥?
分两种情况:
- 无符号char:
0xFF表示数值255,转换为16位int时会做零扩展,高位补0,结果是二进制0000 0000 1111 1111(即0x00FF),数值保持255; - 有符号char:
0xFF是有符号char的-1(补码表示),转换为int时会做符号扩展,高位补符号位的1,16位int的结果是二进制1111 1111 1111 1111(即0xFFFF),数值还是-1,不会变成255。
内容的提问来源于stack exchange,提问作者King In The North
相关产品推荐
相关产品推荐

