为什么使用 0xff 对字符进行按位与运算?

Rog*_*llo 8 c char integer-promotion bitwise-and isspace

我正在阅读一些实现简单解析器的代码。一个名为的函数将scan一行分解为标记。scan有一个静态变量bp,分配给要标记的行。在分配之后,空格被跳过。见下文。我不明白的是为什么代码对bp指向 with的字符进行按位和处理0xff,即, 的目的是* bp & 0xff什么?这怎么样:

while (isspace(* bp & 0xff))
    ++ bp;
Run Code Online (Sandbox Code Playgroud)

与此不同:

while (isspace(* bp))
    ++ bp;
Run Code Online (Sandbox Code Playgroud)

这是scan函数:

static enum tokens scan (const char * buf)
                    /* return token = next input symbol */
{   static const char * bp;

    while (isspace(* bp & 0xff))
        ++ bp;

        ..
}
Run Code Online (Sandbox Code Playgroud)

Vla*_*cow 7

来自 C 标准(7.4 字符处理 <ctype.h>)

1 头文件<ctype.h> 声明了几个对字符分类和映射有用的函数。198)在所有情况下,参数都是一个int,其值应表示为无符号字符或应等于宏EOF 的值。如果参数有任何其他值,则行为未定义。

在这次通话中

isspace(* bp)
Run Code Online (Sandbox Code Playgroud)

由于整数提升,*bp具有该类型的参数表达式char被转换为该类型int

如果类型char表现为类型signed char并且表达式的*bp值为负,则类型的提升表达式的值int也将为负并且不能表示为类型的值 unsigned char

这会导致未定义的行为。

在这次通话中

isspace(* bp & 0xff)
Run Code Online (Sandbox Code Playgroud)

由于按位运算符 &* bp & 0xff类型表达式的结果值int可以表示为类型的值unsigned char

所以这是一个使用技巧,而不是编写更清晰的代码,例如

isspace( ( unsigned char )*bp )
Run Code Online (Sandbox Code Playgroud)

该函数isspace的实现方式通常是将其类型的参数int 用作具有 256 个值(从 0 到 255)的表中的索引。如果该类型的参数的int值大于最大值 255 或负值(并且不等于宏 EOF 的值),则函数的行为未定义。