从cppreference isspace() : The behavior is undefined if the value of ch is not representable as unsigned char and is not equal to EOF
。
当*bp
是负数时,例如它是-42
,那么它不能表示为unsigned char
,因为它是负数unsigned char
,而且 必须是正数或零。
在二进制补码系统上,值被符号扩展为更大的“宽度”,因此它们将设置最左边的位。然后,当您采用0xff
更宽的类型时,最左边的位被清除,最终得到一个正值,小于或等于0xff
,我的意思是可以表示为unsigned char
。
请注意,参数要&
经过隐式提升,因此结果会在调用之前*bp
转换为。让我们假设例如并假设一个具有 8 位 char 且已签名且具有 32 位的健全平台,然后:int
isspace
*bp = -42
int
*bp & 0xff # expand *bp = -42
(char)-42 & 0xff # apply promotion
(int)-42 & 0xff # lets convert to hex assuming twos-complement
(int)0xffffffd6 & 0xff # do & operation
(int)0xd6 # lets convert to decimal
214 # representable as unsigned char, all fine
没有& 0xff
负值将导致未定义的行为。
我建议更喜欢isspace((unsigned char)*bp)
.
基本上最简单的isspace
实现看起来像:
static const char bigarray[257] = { 0,0,0,0,0,...1,0,1,0,... };
// note: EOF is -1
#define isspace(x) (bigarray[(x) + 1])
在这种情况下你不能通过例如-42
,原因bigarray[-41]
是无效的。