<ctype.h><fenv.h><float.h><inttypes.h><iso646.h><limits.h>
章节大纲
-
<ctype.h>
– 字符处理(Character Handling)在标准 C 中,
<ctype.h>
中提供的所有函数都接受一个int
类型参数。然而,传入的值必须是可以用unsigned char
表示的值或宏EOF
。若传入其他值,行为是未定义的。C89 引入了**区域设置(locale)**的概念。默认情况下,C 程序运行在
"C"
区域,除非调用了setlocale
函数(或实现默认区域不是 "C")。在"C"
区域中,<ctype.h>
的函数行为与 C89 之前一致。当选择了除 "C" 以外的区域时,某些字符类别的判定可能会扩展。例如,在西欧地区运行的实现中,可能将带变音符(如
ä
、ê
、ñ
)的字符视为字母。因此,字符ä
是否使isalpha
返回真,是由当前区域设置定义的。许多实现使用的字符表示比宿主字符集所需的位数更多,例如支持 7 位 ASCII 的 8 位字符系统。这样可以利用未使用的位扩展字符集。此外,C 程序员可以将
char
当作小整数使用,存入任何能表示的位模式。但当
char
中的内容不是本机字符集的一部分时,不应将其传入<ctype.h>
中的函数,除非当前区域允许。即使允许,结果仍是实现定义的。同时,还应注意char
是否为有符号类型,因为值为0x80
的 8 位char
,在 signed 与 unsigned 情况下行为会不同。标准 C 要求
<ctype.h>
中的函数必须作为实际函数实现。但也允许它们以宏的形式实现,前提是宏是安全的(即每个参数只被求值一次)。如果需要使用函数版本,可以通过#undef
取消对应宏。建议:
<ctype.h>
中的测试函数在返回 true 时的实际值是实现定义的。因此,不应用作算术比较,只应用于逻辑判断。标准 C 保留了所有以
is
或to
开头、后跟小写字母(然后是任意标识符字符)的函数名,以备将来扩展库函数。以下函数具有区域相关行为:
-
isalpha
,isblank
,isgraph
,islower
,isprint
,ispunct
,isspace
,isupper
,toupper
,tolower
C89 之前,以下函数在许多实现中也通过此头文件提供:
-
isascii
,toascii
,iscsym
,iscsymf
但这些函数不属于标准 C 支持的函数。
C++ 注意事项:对应的标准 C++ 头文件为
<cctype>
。
字符分类函数(Character Classification Functions)
isalpha
函数
使用isalpha
替代如下代码:if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
因为在某些字符集(如 EBCDIC)中,大小写字母在内部编码上不一定是连续的。
isblank
函数
由 C99 引入。islower
,isupper
函数
同样参考isalpha
的说明。
字符大小写转换函数(Character Case Mapping Functions)
tolower
和toupper
函数
在非 "C" 区域中,大写转小写的映射不一定是一对一的。
例如,大写字母可能被映射为两个小写字母,或者可能根本没有小写形式。toupper
同理。
<errno.h>
– 错误处理(Errors)早期的
errno
被声明为extern int
,但标准 C 要求它是一个宏。
该宏可以展开为对同名函数的调用。标准中,errno
被定义为可修改的int *
类型左值。
例如:errno
可以定义为*_Errno()
,其中_Errno()
是一个返回int *
的函数。对
errno
使用#undef
试图访问底层对象的行为是未定义的。许多标准库函数在检测到某些错误时会将
errno
设为非零值,且该值必须为正数。
标准 C 明确规定:库函数不负责将errno
重置为 0,因此不能依赖其清除行为。通常,
errno
的宏值以E
开头。虽然各系统之间对错误名的拼写和含义不统一,但 C89 仅定义了两个:-
EDOM
(数学域错误) -
ERANGE
(结果超出范围)
C99 新增:
-
EILSEQ
(非法多字节序列)
标准兼容实现可定义其他以
E
加数字或大写字母开头的宏。例如:E2BIG // 参数列表太长 EACCES // 权限被拒绝 EAGAIN // 暂时无法分配资源 EBADF // 错误的文件描述符 EEXIST // 文件已存在 ENOMEM // 内存不足 ENOTDIR // 非目录 EPIPE // 管道已破裂 ...
完整列表可见于原文,或参考实现的
<errno.h>
。参见:C11 添加的“边界检查接口”附录中可能对该头文件提出的要求(如宏
__STDC_LIB_EXT1__
)。C++ 注意事项:对应的标准 C++ 头文件为
<cerrno>
。
<fenv.h>
– 浮点环境(Floating-Point Environment)该头文件由 C99 引入。
标准 C 保留所有以
FE_
开头、后接大写字母的宏名,用于将来在此头文件中添加新宏。C++ 注意事项:对应的标准 C++ 头文件为
<cfenv>
。
<float.h>
– 浮点类型特性(Characteristics of Floating Types)该头文件通过一系列宏定义目标系统的浮点类型特性,其值多为实现定义的。
截至 C17,大部分宏已由 C89 定义,少数新增:
-
C99 新增:
DECIMAL_DIG
,FLT_EVAL_METHOD
-
C11 新增:
FLT_DECIMAL_DIG
,DBL_DECIMAL_DIG
,LDBL_DECIMAL_DIG
,以及FLT_HAS_SUBNORM
,DBL_HAS_SUBNORM
,LDBL_HAS_SUBNORM
,FLT_TRUE_MIN
,DBL_TRUE_MIN
,LDBL_TRUE_MIN
虽然许多系统采用 IEEE-754 浮点格式,但在 C89 制定时,还有其他三种格式被广泛使用,C89 对这些格式也提供支持。
标准 C 为
FLT_ROUNDS
宏定义了值 -1 到 3,其它值表示实现定义的舍入方式。标准 C 为
FLT_EVAL_METHOD
宏定义了值 -1 到 2,其它负值表示实现定义行为。
该宏的值可能影响浮点常量的求值(详见“浮点常量”相关说明)。C++ 注意事项:对应的标准 C++ 头文件为
<cfloat>
。
<inttypes.h>
– 整数类型的格式转换(Format Conversion of Integer Types)该头文件由 C99 引入。
标准 C 保留所有以
PRI
或SCN
开头、后跟小写字母或X
的宏名,用于未来在此头文件中扩展。C++ 注意事项:对应的标准 C++ 头文件为
<cinttypes>
。
<iso646.h>
– 替代拼写(Alternative Spellings)该头文件由 C95 引入,定义了一些操作符的英文拼写替代形式,例如:
-
and
替代&&
-
or
替代||
-
not
替代!
C++ 注意事项:对应的标准 C++ 头文件为
<ciso646>
,这些宏在标准 C++ 中被当作关键字处理。
<limits.h>
– 数值限制(Numerical Limits)该头文件通过一系列宏定义目标系统中整数类型的数值特性,其值大多是实现定义的。
几乎所有宏都已在 C89 中定义,少数例外如下:
-
C99 新增:
LLONG_MIN
,LLONG_MAX
,ULLONG_MAX
C++ 注意事项:对应的标准 C++ 头文件为
<climits>
。 -