在ctype.h第20行中,__ismask定义为:
__ismask
#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
(int)(unsigned char)(x)是做什么的?我猜它把x转换成unsigned char(只检索第一个字节,而不管x是什么),但为什么它在最后转换成int?
(int)(unsigned char)(x)
x
int
zlhcx6iw1#
(unsigned char)(x)有效地计算值为x % (UCHAR_MAX + 1)的unsigned char。这具有给出非负值(在0和UCHAR_MAX之间)的效果。在大多数实现中,UCHAR_MAX的值为255(尽管标准允许unsigned char支持更大的范围,但这种实现并不常见)。由于(unsigned char)(x)的结果保证在int支持的范围内,因此转换为int不会更改值。净效应是最低有效字节,具有正值。一些编译器在使用char(有符号或无符号)类型作为数组索引时会给予警告。转换为int会关闭这些编译器。
(unsigned char)(x)
x % (UCHAR_MAX + 1)
unsigned char
0
UCHAR_MAX
255
char
qf9go6mv2#
unsigned char-cast是为了确保值在0..255的范围内,然后将结果值用作255字节大的_ctype数组中的索引,参见Linux中的ctype. h。
_ctype
qv7cva1a3#
由于unsigned类型的环绕属性,转换为unsigned char可以安全地提取x的最低有效位CHAR_BIT。(如果char在平台上是signed类型,则转换为char可能是未定义的:有符号类型溢出是c)中未定义的行为。CHAR_BIT通常是8。转换为int后,将转换为unsigned char。标准保证int始终可以保存unsigned char可以接受的任何值。如果你想提取8个最低有效位,一个更好的选择是应用& 0xFF并将结果转换为unsigned类型。
unsigned
CHAR_BIT
signed
& 0xFF
f3temu5u4#
我认为char是依赖于实现的,要么是signed,要么是unsigned。所以你需要通过写unsigned char来显式化,以免转换为负数。然后转换为int。
4条答案
按热度按时间zlhcx6iw1#
(unsigned char)(x)
有效地计算值为x % (UCHAR_MAX + 1)
的unsigned char
。这具有给出非负值(在0
和UCHAR_MAX
之间)的效果。在大多数实现中,UCHAR_MAX
的值为255
(尽管标准允许unsigned char
支持更大的范围,但这种实现并不常见)。由于
(unsigned char)(x)
的结果保证在int
支持的范围内,因此转换为int
不会更改值。净效应是最低有效字节,具有正值。
一些编译器在使用
char
(有符号或无符号)类型作为数组索引时会给予警告。转换为int
会关闭这些编译器。qf9go6mv2#
unsigned char
-cast是为了确保值在0..255的范围内,然后将结果值用作255字节大的_ctype
数组中的索引,参见Linux中的ctype. h。qv7cva1a3#
由于
unsigned
类型的环绕属性,转换为unsigned char
可以安全地提取x
的最低有效位CHAR_BIT
。(如果char
在平台上是signed
类型,则转换为char
可能是未定义的:有符号类型溢出是c)中未定义的行为。CHAR_BIT
通常是8。转换为
int
后,将转换为unsigned char
。标准保证int
始终可以保存unsigned char
可以接受的任何值。如果你想提取8个最低有效位,一个更好的选择是应用
& 0xFF
并将结果转换为unsigned
类型。f3temu5u4#
我认为
char
是依赖于实现的,要么是signed
,要么是unsigned
。所以你需要通过写unsigned char
来显式化,以免转换为负数。然后转换为int
。