有人知道C语言中isgraph()
函数是如何工作的吗?我了解它的用途和结果,但我对其背后的代码很感兴趣。
例如,它是否仅查看其char
值并将其与ASCII表进行比较?还是实际检查它是否可以显示?如果是这样,它是如何做到的呢?
有人知道C语言中isgraph()
函数是如何工作的吗?我了解它的用途和结果,但我对其背后的代码很感兴趣。
例如,它是否仅查看其char
值并将其与ASCII表进行比较?还是实际检查它是否可以显示?如果是这样,它是如何做到的呢?
isgraph()
函数的代码因平台(或更准确地说,因实现)而异。一种常见的技术是使用一个已初始化的位域数组,每个字符在(单字节)代码集中都有一个位域,加上EOF(必须被函数接受),然后选择相关位。这样可以简单地实现为一个宏,它是安全的(只评估其参数一次)和一个简单的(可能是内联的)函数。
#define isgraph(x) (__charmap[(x)+1]&__PRINT)
其中__charmap
和__PRINT
是保留给实现的名称。 +1
的部分处理了常见情况,即EOF
为-1
。
根据C标准(ISO/IEC 9899:1999):
§7.4.1.6 The isgraph function
Synopsis
#include <ctype.h> int isgraph(int c);
Description
The isgraph function tests for any printing character except space (' ').
并且:
§7.4 字符处理
<ctype.h>
¶1 头文件声明了几个有用的函数,用于分类和映射字符。166) 在所有情况下,参数都是int类型,其值应该可表示为unsigned char或等于宏EOF的值。如果参数具有任何其他值,则行为是未定义的。
¶2 这些函数的行为受当前区域设置的影响。只有在“C”区域之外时才具有区域设置特定方面的功能的函数如下所示。
¶3 打印字符一词指的是区域设置特定字符集中的成员,每个成员占用显示设备上的一个打印位置;控制字符一词指的是区域设置特定字符集中不是打印字符的成员。167) 所有字母和数字都是打印字符。
166) 参见“未来库方向”(7.26.2)。
167) 在使用七位US ASCII字符集的实现中,打印字符是那些值从0x20(空格)到0x7E(波浪号)的字符;控制字符是那些值从0(NUL)到0x1F(US)以及字符0x7F(DEL)的字符。
isgraph()宏只查看ASCII表,或者你所在的位置/国家/省份/星球/银河系的ASCII表版本。
这里有一个测试代码计算单词数, 它发现你可以通过编写自己的版本来提高性能,该版本使用isgraph()初始化一个bool数组[256]。代码中还附有基准测试结果。
由于bool变量/数组实际上是BYTE而不是位,如果您使用位数组并进行测试,那么从内存效率的角度来看,您可以做得更好。它只占用32个字节。在任何通用现代处理器上都会被缓存。
重要的是,如果您想要比这里提供的标准测试略有不同的测试(请参见字符测试的图形描述), 您可以自由更改标准测试提供的初始化以包括您自己的异常。
isprint
的实用性和硬编码(非可移植)的测试,例如 (c >= 32 && c <= 126)
(isprint(' ')
为真)。我误解了你的观点。但是无论你是使用 ASCII、EBCDIC 还是苏美尔楔形文字,我都不认为没有使用 <ctype.h>
有什么意义,所以我没想到要进行比较。 - Keith Thompsonisgraph
检查“可打印”字符,但“可打印”的定义可能因您的语言环境而异。您的语言环境可能使用不在 ASCII 表中的字符。在内部,它很可能是一个表查找、基于范围的测试((x >= 'a') && (x <= 'z')
等)或两者的组合。不同的实现可能会略有不同。