__ctype_b_loc 它的目的是什么?
__ctype_b_loc what is its purpose?
我试图理解一段使用 __ctype_b_loc()
的代码,问题是我不知道这个函数的目的是什么。
到目前为止,我发现它是在ctype.h
中定义的。我还找到了它的原型和实现。我仍然不知道这个功能是干什么用的。
有人可以启发我吗?
经过公平的研究,我想我可以自己回答这个问题。
unsigned short int** __ctype_b_loc (void)
是一个函数,它 returns 指向“traits” table 的指针,其中包含一些与每个字符的特征相关的标志。
这是带有标志的枚举:
来自ctype.h
enum
{
_ISupper = _ISbit (0), /* UPPERCASE. */
_ISlower = _ISbit (1), /* lowercase. */
_ISalpha = _ISbit (2), /* Alphabetic. */
_ISdigit = _ISbit (3), /* Numeric. */
_ISxdigit = _ISbit (4), /* Hexadecimal numeric. */
_ISspace = _ISbit (5), /* Whitespace. */
_ISprint = _ISbit (6), /* Printing. */
_ISgraph = _ISbit (7), /* Graphical. */
_ISblank = _ISbit (8), /* Blank (usually SPC and TAB). */
_IScntrl = _ISbit (9), /* Control character. */
_ISpunct = _ISbit (10), /* Punctuation. */
_ISalnum = _ISbit (11) /* Alphanumeric. */
};
举个例子,如果你查找 table __ctype_b_loc()
returns 的 ascii 码是 0x30
的字符 ('0
') 你会得到 0x08d8
.
0x08d8=0000 1000 1101 1000 (Alphanumeric, Graphical, Printing, Hexadecimal, Numeric)
table 与机器上安装的语言环境 localchar
相关,因此与您系统上的结果相比,该示例可能不准确。
Alessandro 自己的回答非常有用,但我想补充一些信息。
如 Alessandro 所述,__ctype_b_loc(void)
函数 returns 一个数组,其中每个元素包含一个 ASCII 字符的特征。例如,通过在 table 中查找,我们可以了解到字符 'A' 是大写、十六进制、图形、打印、字母数字。
准确的说,__ctype_b_loc()
函数returns一个const unsigned short int**
是一个指向384unsigned short int*
数组的指针。
之所以有 ara 384 个元素,是因为 table 可以通过以下方式索引:
- 任意
unsigned char
值 [0,255](所以 256 个元素)
- EOF (-1)
- 任意
signed char
值 [-128,-1) (所以 127 个元素)
此 table 被以下函数使用:
- 上层
- 变慢
- isalpha
- 不统一
- ...
但是这些函数被定义为宏,所以您永远不会在汇编代码中看到它们被调用。您将看到调用 __ctype_b_loc()
以获取 table、检索正确条目的一些代码以及位掩码的用法以查看我们正在检查的 属性 是否已设置.例如,如果我们想查看一个字符是否为大写,我们必须检查是否设置了位 0。
这里是调用isupper('A');
生成的汇编代码:
call sym.imp.__ctype_b_loc ; isupper('A');
mov rax, qword [rax] ; get the pointer to the array of 'unsigned short int*'
movsx rdx, byte 0x41 ; prepare to look up for character 'A'
add rdx, rdx ; each entry is 2 bytes, so we double the value of 'A'
add rax, rdx ; look up for 'A' in the table
movzx eax, word [rax] ; get the 'unsigned short int' containing the properties
movzx eax, ax
and eax, 0x100 ; 0x0100 in little-endian is 0x0001 in big-endian (check if bit 0 is set)
我试图理解一段使用 __ctype_b_loc()
的代码,问题是我不知道这个函数的目的是什么。
到目前为止,我发现它是在ctype.h
中定义的。我还找到了它的原型和实现。我仍然不知道这个功能是干什么用的。
有人可以启发我吗?
经过公平的研究,我想我可以自己回答这个问题。
unsigned short int** __ctype_b_loc (void)
是一个函数,它 returns 指向“traits” table 的指针,其中包含一些与每个字符的特征相关的标志。
这是带有标志的枚举:
来自ctype.h
enum
{
_ISupper = _ISbit (0), /* UPPERCASE. */
_ISlower = _ISbit (1), /* lowercase. */
_ISalpha = _ISbit (2), /* Alphabetic. */
_ISdigit = _ISbit (3), /* Numeric. */
_ISxdigit = _ISbit (4), /* Hexadecimal numeric. */
_ISspace = _ISbit (5), /* Whitespace. */
_ISprint = _ISbit (6), /* Printing. */
_ISgraph = _ISbit (7), /* Graphical. */
_ISblank = _ISbit (8), /* Blank (usually SPC and TAB). */
_IScntrl = _ISbit (9), /* Control character. */
_ISpunct = _ISbit (10), /* Punctuation. */
_ISalnum = _ISbit (11) /* Alphanumeric. */
};
举个例子,如果你查找 table __ctype_b_loc()
returns 的 ascii 码是 0x30
的字符 ('0
') 你会得到 0x08d8
.
0x08d8=0000 1000 1101 1000 (Alphanumeric, Graphical, Printing, Hexadecimal, Numeric)
table 与机器上安装的语言环境 localchar
相关,因此与您系统上的结果相比,该示例可能不准确。
Alessandro 自己的回答非常有用,但我想补充一些信息。
如 Alessandro 所述,__ctype_b_loc(void)
函数 returns 一个数组,其中每个元素包含一个 ASCII 字符的特征。例如,通过在 table 中查找,我们可以了解到字符 'A' 是大写、十六进制、图形、打印、字母数字。
准确的说,__ctype_b_loc()
函数returns一个const unsigned short int**
是一个指向384unsigned short int*
数组的指针。
之所以有 ara 384 个元素,是因为 table 可以通过以下方式索引:
- 任意
unsigned char
值 [0,255](所以 256 个元素) - EOF (-1)
- 任意
signed char
值 [-128,-1) (所以 127 个元素)
此 table 被以下函数使用:
- 上层
- 变慢
- isalpha
- 不统一
- ...
但是这些函数被定义为宏,所以您永远不会在汇编代码中看到它们被调用。您将看到调用 __ctype_b_loc()
以获取 table、检索正确条目的一些代码以及位掩码的用法以查看我们正在检查的 属性 是否已设置.例如,如果我们想查看一个字符是否为大写,我们必须检查是否设置了位 0。
这里是调用isupper('A');
生成的汇编代码:
call sym.imp.__ctype_b_loc ; isupper('A');
mov rax, qword [rax] ; get the pointer to the array of 'unsigned short int*'
movsx rdx, byte 0x41 ; prepare to look up for character 'A'
add rdx, rdx ; each entry is 2 bytes, so we double the value of 'A'
add rax, rdx ; look up for 'A' in the table
movzx eax, word [rax] ; get the 'unsigned short int' containing the properties
movzx eax, ax
and eax, 0x100 ; 0x0100 in little-endian is 0x0001 in big-endian (check if bit 0 is set)