预计阅读本页时间:-
ANSI C库把函数分为不同的组,每个组都具有与之相关的头文件。本附录给出了库的总览,列出了这些头文件并简单地描述了相关的函数。文中对一些函数(例如一些I/O函数)进行了较为详细的讨论。更一般地,如果想获得完整的说明,请参考具体实现的文档或参考手册,或试试下面的在线参考:
http://www.dinkumware.com/htm_cl/index.html
广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元
B.5.1 诊断:assert.h
这个头文件把assert()定义为一个宏。在包含assert.h头文件之前定义宏标识符NDEBUG可以禁用assert()宏。用作参数的表达式通常是一个关系或逻辑表达式,如果程序正确执行的话,那么在程序执行到该点时该表达式应该为真。
表B.2 诊断宏
原 型 | 说 明 |
---|---|
void assert(int exprs); | 如果exprs为非0(或真),宏不做任何事;如果exprs为0(假),assert()就显示该表达式、assert()语句所在的行号和包含该语句的文件名;然后它调用abort() |
B.5.2 复数:complex.h(C99)
C99标准添加了对复数计算的广泛支持。除了提供_Complex类型之外,实现还可以提供_Imaginary类型。该头文件定义了表B.3中列出的宏。
表B.3 complex.h宏
宏 | 说 明 |
---|---|
complex | 展开为类型关键字_Complex |
_Complex_I | 展开为一个类型是const float_Complex的表达式,它的值平方后为−1 |
imaginary | 如果支持虚数类型,就展开为类型关键字_Imaginary |
_Imaginary_I | 如果支持虚数类型,就展开为一个类型是const float_Imaginary的表达式,它的值平方后为−1 |
I | 展开为_Complex_I或_Imaginary_I |
在C中使用complex.h头文件实现对复数的支持,而在C++中是使用complex头文件实现。两种实现有很大的不同,C++是使用类来定义复数类型的。
可以使用STDCCX_LIMITED_RANGE编译指示来表明是可以使用普通的数学公式(打开时),还是要对极值进行特别的注意(关闭时):
库函数可以分为三种:double、float和long double。表B.4列出了double版本。float和long double版本只是在函数名后面分别加上f和1。这样,csinf()就是csin()的float版本,而csinl()是csin()的long double版本。
角度是以弧度为单位的。
表B.4 复数函数
原 型 | 说 明 |
---|---|
double complex cacos(double complex z); | 返回z的复数反余弦 |
double complex casin(double complex z); | 返回z的复数反正弦 |
double complex cat an(double complex z); | 返回z的复数反正切 |
double complex ccos(double complex z); | 返回z的复数余弦 |
double complex csin(double complex z); | 返回z的复数正弦 |
double complex ctan(double complex z); | 返回z的复数正切 |
double complex cacosh(double complex z); | 返回z的复数反双曲余弦 |
double complex casinh(double complex z); | 返回z的复数反双曲正弦 |
double complex catanh(double complex z); | 返回z的复数反双曲正切 |
double complex ccosh(double complex z); | 返回z的复数双曲余弦 |
double complex csinh(double complex z); | 返回z的复数双曲正弦 |
double complex ctanh(double complex z); | 返回z的复数双曲正切 |
double complex cexp(double complex z); | 返回e的z次幂的复数值 |
double complex clog(double complex z); | 返回z的自然对数(以e为底)的复数值 |
double cabs(double complex z); | 返回z的绝对值(或长度) |
double complex cpows(double complex z,double complex y); | 返回z的y次幂的值 |
double complex csqrt(double complex z); | 返回z的复数平方根 |
double carg(double complex z); | 以弧度返回z的相位角(或辐角) |
double cimag(double complex z); | 以实数形式返回z的虚部 |
double complex conj(double complex z); | 返回z的共轭复数 |
double complex cproj(double complex z); | 返回z在Riemann域上的投影 |
double creal(double complex z); | 以实数形式返回z的实部 |
B.5.3 字符处理:ctype.h
这些函数接受int参数,这些参数能够被表示为unsigned char值或EOF,如果提供其他值则结果没有定义。在表B.5中“真”作为“非0值”的速记形式。对一些定义的解释要依赖于当前场所的设置,它是由locale.h中的函数来控制的;该表显示了在“C”场所中的解释。
表B.5 字符处理函数
原 型 | 说 明 |
---|---|
int isalnum(int c); | 如果c是字母数字(字母或数字)则返回真 |
int isalpha(int c); | 如果c是字母则返回真 |
int isblank(int c); | 如果c是空格或水平制表符则返回真(C99) |
int iscntrl(int c); | 如果c是控制字符,例如Ctrl+B,则返回真 |
int isdigit(int c); | 如果c是数字则返回真 |
int isgraph(int c); | 如果c是空格之外的任何打印字符则返回真 |
int islower(int c); | 如果c是小写字符则返回真 |
int isprint(int c); | 如果c是打印字符则返回真 |
int ispunct(int c); | 如果c是标点字符(除空格或字母数字之外的任何打印字符)则返回真 |
int isspace(int c); | 如果c是下列空白字符:空格、换行、走纸、回车、垂直制表、水平制表或其他由实现 定义的字符,那么返回真 |
int isupper(int c); | 如果c是大写字符则返回真 |
int isxdigit(int c); | 如果c是十六进制数字字符则返回真 |
int tolower(int c); | 如果参数为大写字符则返回它的小写,否则返回原始参数 |
int toupper(int c); | 如果参数是小写字符则返回它的大写,否则返回原始参数 |
B.5.4 错误报告:errno.h
errno.h支持较老的错误报告机制。这种机制提供了可以被标识符(也可能是宏)ERRNO访问的外部静态内存位置。一些库函数在这个位置放一个值来支持错误,然后包含这个头文件的程序就可以检查ERRNO的值以确定是否报告了一个错误。ERRNO机制被认为缺少艺术性,而要设置ERRNO值也不再需要数学函数。标准提供了三个宏值来表示特定的错误,但是有些实现可以提供更多。表B.6列出了标准的宏。
表B.6 errno.h宏
宏 | 含 义 |
---|---|
EDOM | 函数调用中的域错误(参数越界) |
ERANGE | 函数返回值的范围错误(返回值越界) |
EELSEQ | 宽字符转换错误 |
B.5.5 浮点数环境:fenv.h(C99)
C99标准通过fenv.h头文件提供了对浮点数环境的访问和控制。这个特性支持对数值计算的更多控制,但是它要得到广泛的实现可能还需要一段时间。
浮点数环境(floating-point environment)包括一组状态标志和控制模式。在浮点数计算中发生的异常情形,例如被零除,可以“抛出一个异常”。这意味着该事件设置了浮点数环境标志中的一位。控制模式值可以进行一些控制,例如控制舍入的方向。fenv.h头文件定义了一组用来表示异常和控制模式的宏,它也提供了与环境进行交互的函数原型。头文件还提供了一个pragma来启用或禁用对浮点数环境的访问。
下面的指令开启了对环境的访问:
而下面的指令则关闭了对环境的访问:
如果在外部,这个编译指示应该在任何外部声明之前或在复合代码块的开始处给出。它一直保持有效,直到碰到另一个编译指示,或到达文件结尾(外部指令),或到达复合语句的结尾(代码块指令)为止。
头文件定义了两种类型,在表B.7中显示。
表B.7 fenv.h类型
类 型 | 表 示 |
---|---|
fenv_t | 整个浮点数环境 |
fexcept_t | 浮点数状态标志的集合 |
头文件定义了表示一些可能的浮点异常和控制状态的宏。不同的实现可能定义更多的宏,但是它们要以FE_开头,后跟大写字符。表B.8说明了标准异常宏。
表B.8 fenv.h类型
宏 | 表 示 |
---|---|
FE_DIVBYZERO | 抛出被零除异常 |
FE_INEXACT | 抛出不精确值异常 |
FE_INVALID | 抛出非法值异常 |
FE_OVERFLOW | 抛出上溢异常 |
FE_UNDERFLOW | 抛出下溢异常 |
FE_ALL_EXCEPT | 位异常或被实现所支持的所有浮点数异常 |
FE_DOWNWARD | 向下舍入 |
FE_TONEAREST | 向最近的值舍入 |
FE_TOWARDZERO | 趋0舍入 |
FE_UPWARD | 向上舍入 |
FE_DFL_ENV | 表示默认的环境,类型为const fenv_t * |
表B.9说明了fenv.h头文件中的标准函数原型。注意,通常参数值和返回值与表B.8中的宏相符。例如,FE_UPWARD是fesetround()函数的一个适当参数。
表B.9 fenv.h类型
原 型 | 说 明 |
---|---|
void feclearexcept(int excepts); | 清除excepts表示的异常 |
void fegetexceptflag(t * flagp, int excepts); | 在flagp指向的对象中存储由excepts说明的浮点数状态标志 |
void feraiseexcept(int excepts); | 抛出excepts说明的异常 |
void fesetexceptflag(const fexcept.t * flagp, int excepts); | 把由excepts表明的浮点数状态标志设置为flagp提供的值,flagp应该通过事先调用fegetexceptflag()进行设置 |
int fetestexcept(int excepts); | excepts指明要查询的状态标志,函数返回指定的状态标志位 |
int fegetround(void); | 返回当前的舍入方向 |
int fesetround(int round); | 把舍入方向设置为round指定的值,当且仅当设置成功时函数返回0 |
void fegetenv(fenv_t * envp); | 在envp指向的位置中存储当前环境 |
int feholdexcept(fenv_t * envp); | 在envp指向的位置中存储当前的浮点数环境,清除浮点数状态标志,然后 如果可能的话就设置非停模式,在这种模式中即使发生异常也继续执行。 当且仅当执行成功时函数返回0 |
void fesetenv(const fenv_t * envp); | 建立envp表示的浮点数环境,envp应该指向一个数据对象,该对象通 过事先调用fegetenv()或feholdexcept()或一个浮点数环境宏进行 设置 |
void feupdateenv(const fenv_t * envp); | 函数在自动存储区中存储当前抛出的浮点数异常,建立由envp指向的对象 表示的浮点数环境,然后抛出所存储的浮点数异常,envp应该指向一个数 据对象,该对象通过事先调用fegetenv()或feholdexcept()或一个浮点 数环境宏进行设置 |
B.5.6 整数类型的格式转换:inttypes.h(C99)
这个头文件定义了一些宏,可以使用它们作为扩展的整数类型的格式说明符。这个头文件还声明了以下类型:
imaxdiv_t
这是一个结构类型,它表示idivmax()函数的返回值。
这个头文件还包含了stdint.h并声明了一些使用最大长度的整数类型的函数,这种整数类型在stdint.h中声明为intmax。表B.10列出了这些函数。
表B.10 使用最大长度整数的函数
原 型 | 说 明 |
---|---|
intmax_t imaxabs(intmax_t j); | 返回j的绝对值 |
imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom); | 在一个单独的运算中计算numer/denom的商和余数,并把这两个值存储 在一个返回结构中 |
intmax_t strtoimax(const char * restrict nptr, char ** restrict endptr, int base); | 除了把字符串转换为intmax_t类型并返回这个值之外,等价于strtol() 函数 |
uintmax_t strtoumax(const char * restrict nptr, char ** restrict endptr, int base); | 除了把字符串转换为uintmax_t类型并返回这个值之外,等价于strtoul ()函数 |
intmax_t wcstoimax(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base); | strtoimax()的wchar_t 版本 |
uintmax_t wcstoumax(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base); | strtoumax()的wchar_t版本 |
B.5.7 本地化:locale.h
场所(locale)是一组设置,它控制着例如小数点所使用的符号这样的事情。场所值被存放在一个类型为struct lconv的结构中,这个结构在locale.h头文件中定义。场所可以由一个字符串来指定,这个字符串指定了该结构成员值的一个特定集合。默认的场所由字符串“C”指示。表B.11列出了本地化函数,之后是一个简单的说明。
表B.11 本地化函数
原 型 | 说 明 |
---|---|
char * setlocale(int category, const char * locale); | 这个函数把一些场所值设置为由locale指定的值。category的值控制要设置哪些场 所值(请参见表B.5.11)。如果不能完成请求,函数就返回一个空指针;否则返回 与新场所中的指定类别相联系的指针 |
struct lconv * localeconv(void); | 返回一个指向结构struct lconv的指针,该结构由当前的场所值进行填充 |
setlocale()函数的locale参量要求的值可能是"C",它是默认的值;也可能是“”,它表示实现所定义的本地环境。实现可以定义更多的场所。setlocale()函数的category参量可能的值由表B.12中列出的宏来表示。
表B.12 category宏
宏 | 说 明 |
---|---|
NULL | 不改变场所,并返回指向当前场所的指针 |
LC_ALL | 改变所有的场所值 |
LC_COLLATE | 按strcoll()和strxfrm()使用的编码顺序改变场所值 |
LC_CTYPE | 对字符处理函数和多字节函数改变场所值 |
LC_MONETARY | 对货币格式信息改变场所值 |
LC_NUMERIC | 对小数点符号和由格式化I/O以及字符串转换函数使用的非货币格式改变场所值 |
LC-TIME | 对strftime()使用的时间格式改变场所值 |
表B.13列出了结构struct lconv要求的成员。
表B.13 结构struct lconv要求的成员
宏 | 说 明 |
---|---|
char * decimal_point | 非货币值的小数点字符 |
char * thousands_sep | 用来分隔非货币的数值中小数点前的数字组的字符 |
char * grouping | 一个字符串,它的元素用来表明非货币的数值中的每组数字的大小 |
char * int_curr_symbol | 国际货币符号 |
char * currency_symbol | 本地货币符号 |
char * mon_decimal_point | 货币值中的小数点字符 |
char * mon_thousands_sep | 用来分隔货币值中小数点前的数字组的字符 |
char * mon_grouping | 一个字符串,它的元素用来表明货币值中每组数字的大小 |
char * positive_sign | 用来表明非负格式化货币值的字符串 |
char * negative_sign | 用来表明负格式化货币值的字符串 |
char int_frac_digits | 国际格式化的货币值中小数点之后的数字个数 |
char f rac_digits | 本地格式化的货币值中小数点之后的数字个数 |
char p_cs_precedes | 根据currehcy_symbol是在一个非负格式化货币值前面还是后面设置为1或0 |
char p_sep_by_space | 根据currency_symbol是否用空格与一个非负格式化货币值分隔开设置为1或0 |
char n_cs_precedes | 根据currency_symbol是在一个负格式化货币值前面还是后面设置为1或0 |
char n_sep_by_space | 根据currency_symbol是否用空格与一个负格式化货币值分隔开设置为1或0 |
char p_sign_posn | 设置为表明positive_sign字符串的位置的值 0 说明数值和货币符号用圆括号括起来 1 说明字符串在数值和货币符号之前 2 说明字符串在数值和货币符号之后 3 说明字符串就在货币符号前面 4 说明字符串紧跟在货币符号后面 |
char n_sign_posn | 设置为表明字符串negative_sign位置的值,含义与char p_sign_posn相同 |
char int_p_cs_precedes | 根据int_currency_symbol在一个非负格式化货币值之前还是之后设置为1或0 |
char int_p_sep_by_space | 根据int_currency_symbol是否用空格与一个非负格式化货币值分隔开设置为1或0 |
char int_n_csjrecedes | 根据int_currency_symbol在一个负格式化货币值之前还是之后设置为1或0 |
char int_n_sep_by_space | 根据int_currency_symbol是否用空格与一个负格式化货币值分隔开设置为1或0 |
char int_p_sign_posn | 设置为一个表明positive_sign相对于一个非负国际格式化货币值的位置的值 |
char int_n_sign_posn | 设置为一个表明positive_sign相对于一个负国际格式化货币值的位置的值 |
B.5.8 数学库:math.h
在C99中,math.h头文件定义了两种类型:
这两种类型分别至少与float和double同样宽,而double_t至少与float_t同样宽。它们分别是进行float和double计算时效率最高的类型。
这个头文件也定义了一些宏,在表B.14中对它们进行了描述,其中除了HUGE_VAL之外的都是C99新增的。在“参考资料8:C99的数值计算增强”中会对其中一些进行更详细的讨论。
表B.14 math.h宏
宏 | 说 明 |
---|---|
HUGE_VAL | 一个正的双精度常量,不一定能用浮点数表示它;在过去,函数的结果大小超过了 可表示的最大值时就使用它来作为函数的返回值 |
HUGE_VALF | 与HUGE_VAL类似,但类型为float |
HUGE_VALL | 与HUGE_VAL类似,但类型为long double |
INFINITY | 如果有的话,就展开为一个表示正的或无符号的无穷大的常量float表达式;否则展 开为一个在编译时溢出的正的浮点数常量 |
NAN | 当且仅当实现支持float的NaN(一个表示“不是一个数”的值)时被定义 |
FP _INFINITE | 表示一个无穷大的浮点数值的分类号 |
FP_NAN | 表示不是一个数的浮点数值的分类号 |
FP_NORMAL | 表明一个正常的浮点数值的分类号 |
FP_SUBNORMAL | 表示一个低于正常(精度被降低)的浮点数值的分类号 |
FP_zero | 表示一个为0的浮点数值的分类号 |
FP_FAST_FMA | (可选)如果有定义,它就表示一个与double操作数的乘法和加法同样快或更快的 函数fma() |
FP_FAST_FMAF | (可选)如果有定义,它就表示一个与float操作数的乘法和加法同样快或更快的函 数fmaf() |
FP_FAST_FMAL | (可选)如果有定义,它就表示一个与long double操作数的乘法和加法同样快 或更快的函数fmal() |
FP_ILOGBO | 一个整数常量表达式,它表示ilogb(0)返回的值 |
FP_ILOGBNAN | —个整数常量表达式,它表示ilogb(NaN)返回的值 |
MATH_ERRNO | 展开为整数常量1 |
MATH_ERREXCEPT | 展开为整数常量2 |
math_errhandling | 值为MATH_ERRNO或MATH_ERREXCEPT或这两个值的按位或(OR) |
数学函数通常对类型为double的值进行操作。C99添加了这些函数的float和long double版本,分别在函数名前加上f前缀和1前缀来表示。例如,C99现在提供这些原型:
为了简短起见,表B.15只列出了数学库中这些函数的double版本。该表引用了FLT_RADIX。这个常量是在float.h中定义的,它用做内部浮点数表示中幂次的底数。最常用的值是2。
表B.15 ANSI C标准数学函数
原 型 | 说 明 |
---|---|
int classify(real-floating x); | 返回对x适当的浮点数分类值的C99宏 |
int isfinite(real-floating x); | 当且仅当x有穷时返回非0值的C99宏 |
int isfin(real-floating x); | 当且仅当x无穷时返回非0值的C99宏 |
int isnan(real-floating x); | 当且仅当x为NaN时返回非0值的C99宏 |
int isnormal(real-floating x); | 当且仅当x为正常数时返回非0值的C99宏 |
int signbit(real-floating x); | 当且仅当x的符号为负时返回非0值的C99宏 |
double acos(double x); | 返回余弦为x的角度(0到tc弧度) |
double asin(double x); | 返回正弦为x的角度(-π/2到π/2弧度) |
double atan(double x); | 返回正切为x的角度(-π/2到π/2弧度) |
double atan2(double y, double x); | 返回正切为y/x的角度(-π到π弧度) |
double cos(double x); | 返回x(弧度)的余弦值 |
double sin(double x); | 返回x(弧度)的正弦值 |
double tan(double x); | 返回x(弧度)的正切值 |
double cosh(double x); | 返回x的双曲余弦值 |
double sinh(double x); | 返回x的双曲正弦值 |
double tanh(double x); | 返回x的双曲正切值 |
double exp(double x); | 返回x的指数函数值(ex) |
double exp2(double x); | 返回2的x次幂(C99) |
double expml(double x); | 返回ex-l(C99) |
double frexp(double v, int * pt_e); | 把v的值分为两部分,一个是规范化小数,返回它的值;另一个是2的幂次, 它被放在pt_e指向的位置中 |
int ilogb(double x); | 用一个signed int返回x的指数(C99) |
double ldexp(double x, int p); | 返回2的p次幂乘以x的结果 |
double log(double x); | 返回x的自然对数 |
double log10(double x); | 返回x的以10为底的对数 |
double logpl(double x); | 返回log(1+x)(C99) |
double log2(double x); | 返回x的以2为底的对数(C99) |
double logb(double x); | 返回参数的有符号指数,底数是用来表示系统中的浮点数的值(FLT_RADIX) (C99) |
double modf(double x, double * p); | 把x分为整数部分和小数部分;它们的符号相同,返回小数部分,把整数部分 存储在p指向的位置中 |
double scalbn(double x, int n); | 返回xxFLT_RADIXn(C99) |
double scalbln(double x, long n); | 返回xxFLT_RADIXn(C99) |
double cbrt(double x); | 返回x的立方根(C99) |
double hypot(double x, double y); | 返回x的平方与y的平方之和的平方根(C99) |
double pow(double x, double y); | 返回x的y次幂 |
double sqrt(double x); | 返回x的平方根 |
double erf(double x); | 返回x的误差函数(C99) |
double erfc(double x); | 返回x的补余误差函数(C99) |
double lgamma(double x); | 返回x的gamma函数的绝对值的自然对数(C99) |
double tgamma(double x); | 返回x的gamma函数(C99) |
double ceil(double x); | 返回不小于x的最小的整数值 |
double f abs(double x); | 返回x的绝对值 |
double floor(double x); | 返回不大于x的最大整数值 |
double nearbyint(double x); | 以浮点数的形式把x舍入为最近的整数;使用由浮点数环境(如果可用)指定 方向。不会抛出"inexact"异常(C99) |
double rint(double x); | 除了会抛出"inexact"异常之外,与nearbyint()相同(C99) |
long int lrint(double x); | 以long int的形式把x舍入为最近的整数;使用由浮点数环境(如果可用)指定 的舍入方向(C99) |
long long int llrint(double x); | 以long long int的形式把x舍入为最近的整数;使用由浮点数环境(如果可用) 指定的舍入方向(C99) |
double round(double x); | 以浮点数的形式把x舍入为最近的整数,它总是进行“四舍五入”(C99) |
long int lround(double x); | 与round()类似,但是结果以long int类型返回(C99) |
long long int llround(double x); | 与round()类似,但是结果以long long int类型返回(C99) |
double trunc(double x); | 以浮点数的形式把x舍入为最近的整数,结果的绝对值不会大于x的绝对值(C99) |
int fmod(double x, double y); | 返回x/y的小数部分,如果y非0,结果的符号与x相同,它的绝对值要小于y 的绝对值 |
double remainder(doublex,double y); | 返回x除以y的余数,在IEC 60559中它定义为x_n*y, n是与x/y最接近的整 数,如果(n_x/y)的绝对值是1/2,则n应该取偶数(C99) |
double remquo(double x, double y, int * quo); | double返回值与remainer()相同,把与x/y符号相同的值放到quo指向的位置中,把 x/y的整数大小对2k取模,k是一个依赖于实现的整数,它的值至少为3(C99) |
double copysign(double x, double y); | 返回一个绝对值与x相同,符号与y相同的值(C99) |
double nan(const char * tagp); | 返回NaN的类型为double的表示;nan(“n-char-seq”)等价于strtod(“NAN (n-char-seq)”,(char**)NULL);nan(“”)等价于strtod(“NAN()”, (char **)NULL);对其他参数字符串来说,调用等价于strtod(“NAN”,(char**) NULL)。如果不支持NaN,那么函数返回0(C99) |
double nextafter(double x,double y); | 在y的方向上返回x之后下一个可表示的类型为double的值,如果x等于y返 回x(C99) |
double next toward(double x,double y); | long与nextafter()相同,只是第二个参数为long double类型,而且如果x等于y, 返回转换为double的y(C99) |
double fdim(double x, doubley); | 返回参数之间的差的绝对值(C99) |
double fmax(double x, double y); | 返回参数中最大的数值,如果参数是一个NaN和一个数字,就返回那个数字 (C99) |
double fmin(double x, doubley); | 返回参数中最小的数值,如果参数是一个NaN和一个数字,就返回那个数字 (C99) |
double fma(double x, double y, double z); | 作为一个三重运算,返回(x*y)+z的值,只在最后舍入一次(C99) |
int isgreater(real-floating x, real-floating y); | 一个C99宏,它返回(x)>(y)的值,如果有参数为NaN,它不会抛出“非 法浮点数”异常 |
int isgreaterequal (real-floatingx, real-floatingy); | 一个C99宏,它返回(x)>=(y)的值,如果有参数为NaN,它不会抛出“非 法浮点数”异常 |
int isless(real-floating x, real-floating y); | 一个C99宏,它返回(x)<(y)的值,如果有参数为NaN,它不会抛出“非 法浮点数”异常 |
int islessequal(real-floating X, real-floating y); | 一个C99宏,它返回(x)<=(y)的值,如果有参数为NaN,它不会抛出“非 法浮点数”异常 |
int islessgreaterCreal-floating x, real-floating y); | —个C99宏,它返回(x)<(y)II(x)>(y)的值,如果有参数为NaN,它 不会抛出“非法浮点数”异常 |
int isunordered(real-floating X, real-floating y); | 如果参数不是按序排列的(至少有一个NaN)函数返回1,否则返回0 |
B.5.9 非本地跳转:setjmp.h
setjmp.h头文件使您可以不遵守通常的函数调用和函数返回的顺序。setjmp()函数存储关于当前执行环境的信息。例如,在类型为jmp_buf的变量(这个头文件中定义的一个数组类型)中存储指向当前指令的指针,然后longjmp()函数使执行转到这个环境中。这些函数是有助于处理错误情况的,而不是作为通常的程序流控制的一部分。表B.16列出了这些函数。
表B.16 setjmp.h函数
原 型 | 说 明 |
---|---|
int set jump(jmp_buf env); | 在env数组中存储调用它时的环境;如果是直接调用那么返回0,如果是从对 longjmp()的调用中返回那么返回非0值 |
void longjmp(jmp_buf env, int vai); | 恢复由最近执行的setjmp()存储的环境;结束这个改变之后,程序继续执行, 除了不允许返回值为0(如果是0,会转换为1)之外,就好像setjmp()的执 行返回val—样 |
B.5.10 信号处理:signal.h
信号(signal)是在程序执行期间可以被报告的一种情形。它由正整数来表示。raise()函数发出(或抛出)一个信号,而signal()函数设置对特定信号的响应。
标准提供了在B.17中列出的宏,它们表示可能的信号;实现可以添加更多的值。它们可以用做raise()和signal()的参数。
表B.17 信号宏
宏 | 说 明 |
---|---|
SIGABRT | 异常终止,例如由abort()调用发出的信号 |
SIGFPE | 错误的数学运算 |
SIGILL | 检测到非法功能(例如非法的指令) |
SIGINT | 接收到交互式的注意信号(例如一个DOS中断) |
SIGSEGV | 对存储区的非法访问 |
SIGTERM | 发送给程序的终止请求 |
signal()函数的第二个参数是一个指针,它指向一个接受int参数的void函数。它也返回一个同样类型的指针。作为对信号的响应来调用的函数被称为信号处理器(signal handler)。标准定义了三个满足这种原型的宏:
表B.18列出了这些宏。
表B.18 void(* f)(int)类型宏
宏 | 说 明 |
---|---|
SIG_DFL | 当这个宏与一个信号值一起用做signal()的参数时,表示发生该信号时进行默认的处理 |
SIG_ERR | 如果signal()不能返回它的第二个参数,就用这个宏作为signal()的返回值 |
SIG_IGN | 当这个宏与一个信号值一起用做signal()的参数时,表示将忽略该信号 |
如果产生了信号sig而且func指向一个函数(请参见表B.19中的signal()原型),大多数情况下首先调用signal(sig, SIG_DFL)来把信号处理重置为默认的处理,然后调用(*func)(sig)。func指向的信号处理函数可以通过执行return语句来终止,也可以调用abort()、exit()或longjmp()来终止。
表B.19列出了信号函数。
表B.19 信号函数
原 型 | 说 明 |
---|---|
void(*signal(int sig, void (*func)(int) ) )(int); | 如果产生信号sig,就执行由func指向的函数;如果可能就返回func,否则返 回SIG_ERR |
int raise(int sig); | 向正在执行的程序发送信号sig;如果成功就返回0,否则返回非0值 |
B.5.11 可变参数:stdarg.h
stdarg.h头文件提供了一种方法来定义具有可变数目的参数的函数。这样的函数的原型应该具有一个参量列表,其中至少要有一个参量后面跟有省略号:
下面用parmN来表示省略号前面的最后一个参量的标识符。在前面的例子中,第一种情况里parmN为n,第二种情况parmN为k。
这个头文件声明了一个va_list类型,该类型表示用于存放对应于参量列表的省略号部分的参量的数据对象。表B.20列出了三个要用在具有可变参量列表的函数中的宏。在使用这些宏之前应该声明一个类型为va_list的对象。
表B.20 可变参数列表宏
原 型 | 说 明 |
---|---|
void va_start(va_list ap, parmN); | 这个宏在va_arg()和va_end()使用ap之前对ap进行初始化,parmN是参 数列表中最后一个命名参量的标识符 |
void va_copy(va_list dest,va_list src); | 这个宏把dest初始化为当前状态的src的一份拷贝(C99) |
type va_arg(va_list ap, type): | 这个宏展开为一个表达式,该表达式的值和类型都与由ap表示的参数列表中的下 一项相同;type就是该项的类型。每次调用这个宏都前进到ap中的下一项 |
void va_end(va_list ap); | 这个宏关闭这个过程,使ap在再次调用va_start()之前不可用 |
B.5.12 布尔支持:stdbool.h(C99)
这个头文件定义了表B.21中列出的4个宏。
表B.21 stdbool.h宏
宏 | 说 明 |
---|---|
bool | 展开为_Bool |
false | 展开为整数常量0 |
true | 展开为整数常量1 |
_bool_true_false_are_defined | 展开为整数常量1 |
B.5.13 通用定义:stddef.h
这个头文件定义了一些类型和宏,如表B.22和表B.23中所列。
表B.22 stddef.h类型
类 型 | 说 明 |
---|---|
ptrdiff_t | 一个有符号整数类型,表示一个指针减去另一个指针的结果 |
size_t | 一个无符号整数类型,表示sizeof运算符的结果 |
wchar_t | 一个整数类型,可以表示由支持场所来指定的最大的扩展字符集 |
表B.23 stddef.h宏
宏 | 说 明 |
---|---|
NULL | 一个由实现定义的常量,表示空指针 |
offsetof(type, member-designator) | 展开为一个size_t值,以字节来表示指定成员相对于类型为type的结构的开始 处的偏移量;如果指定成员是一个位字段,那么这个宏的行为没有定义 |
例子
B.5.14 整数类型:stdint.h
这个头文件使用typedef工具创建一些指定了整数属性的整数类型名。这个头文件被包含在inttypes.h头文件中,后者提供了在输入/输出函数调用中使用的宏。
一、确切长度类型
一组typedef定义标识了一些确切大小的类型。表B.24列出了它们的名字和大小,但是要注意不是所有的系统都能支持所有这些类型。
表B.24 确切长度类型
typedef名称 | 属 性 |
---|---|
int8_t | 8位有符号 |
int16_t | 16位有符号 |
int32_t | 32位有符号 |
int64_t | 64位有符号 |
unit8_t | 8位无符号 |
unit16_t | 16位无符号 |
unit32_t | 32位无符号 |
unit64_t | 64位无符号 |
二、最小长度类型
最小长度类型保证一种类型的大小至少为某个确定的位。表B.25列出了最小长度类型。这些类型总是存在的。
表B.25 最小长度类型
typedef名称 | 属 性 |
---|---|
int_least8_t | 至少8位有符号 |
int_leastl6_t | 至少16位有符号 |
int_least32_t | 至少32位有符号 |
int_least64_t | 至少64位有符号 |
uint_least8_t | 至少8位无符号 |
uint_leastl6_t | 至少16位无符号 |
uint_least32_t | 至少32位无符号 |
uint_least64_t | 至少64位无符号 |
三、最快最小长度类型
对于特定的系统,有些整数表示可以比其他整数表示更快。所以stdint.h也为表示至少某些特定的位定义了最快的类型。表B.26列出了最快最小长度类型。这些类型总是存在的。在有些情况下,哪种类型最快可能没有明显的选择,那么系统就简单地指定其中一种。
表B.26 最快最小长度类型
typedef名称 | 属 性 |
---|---|
int_fast8_t | 至少8位有符号 |
int_fastl6_t | 至少16位有符号 |
int_fast32_t | 至少32位有符号 |
int_fast64_t | 至少64位有符号 |
uint_fast8_t | 至少8位无符号 |
uint_fastl6_t | 至少16位无符号 |
uint_fast32_t | 至少32位无符号 |
uint_fast64_t | 至少64位无符号 |
四、最大长度类型
stdint.h头文件也定义了最大长度类型。这种类型的变量中可以存放系统中任何可能的整数值,它要考虑符号。表B.27列出了这些类型。
表B.27 最大长度类型
typedef名称 | 属 性 |
---|---|
intmax_t | 最长的有符号类型 |
uintmax_t | 最长的无符号类型 |
五、可以保存指针值的整数
这个头文件还具有在表B.28中列出的两种整数类型,它们可以精确地保存指针值。也就是说,如果您为这些类型之一赋一个void *的值,然后把这个整数再赋回给指针,不会丢失任何信息。这两种类型都有可能不存在。
表B.28 用于保存指针值的整数类型
typedef名称 | 属 性 |
---|---|
intptr_t | 可以保存指针值的有符号类型 |
uintptr_t | 可以保存指针值的无符号类型 |
六、已定义的常量
stdint.h头文件定义了一些常量,它们用来表示该头文件中所定义类型的限制值。这些常量是根据类型命名的。用_MIN或_MAX代替类型名中_t,然后大写所有的字符就得到了表示该类型的最小值或最大值的常量名。例如,int32_t类型的最小值为INT32_MIN, uint_fast16_t的最大值为UNIT_FAST16_MAX。表B.29总结了这些常量,其中N表示位数;表中还总结了与intptr_t、uintptr_t、intmax_t以及uintmax_t类型相关的已定义的常量。这些常量的绝对值应该等于或大于(除非指明了一定要等于)所列出的数的绝对值。
表B.29 整数常量
常量标识符 | 最小值(绝对值) |
---|---|
INTN_MIN | 等于−(2(N−1)−1) |
INTN_MAX | 等于 2(N−1)−1 |
UINTN_MAX | 等于 2N−1 |
INT_LEASTN_MIN | −(2(N−1))−1 |
INT_LEASTN_MAX | 2(N−1)−1 |
UINT_LEASTN_MAX | 2N−1 |
INT_FASTN_MIN | −(2(N−1)) |
INT_FASTN_MAX | 2(N−1)−1 |
UINT_FASTN_MAX | 2(N−1)−1 |
INTPTR_MIN | −(215−1) |
INTPTR_MAX | 215−1 |
UINTPTR_MAX | 216−1 |
INTMAX_MIN | −(215−1) |
INTMAX_MAX | 263−1 |
UINTMAX_MAX | 264−1 |
这个头文件也为一些在别处定义的类型定义了常量。表B.30列出了它们。
表B.30 更多整数常量
常量标识符 | 含 义 |
---|---|
PTRDIFF_MIN | ptrdiff_t类型的最小值 |
PTRDIFF_MAX | ptrdiff_t类型的最大值 |
SIG_ATOMIC_MIN | sig_atomic_t类型的最小值 |
SIG_ATOMIC_MAX | sig_atomic_t类型的最大值 |
WCHAR_MIN | wchar_t类型的最小值 |
WCHAR_MAX | wchar_t类型的最大值 |
WINT_MIN | wint_t类型的最小值 |
WINT_MAX | Wint_t类型的最大值 |
SIZE_MAX | size_t类型的最大值 |
七、扩展的整数常量
stdint.h头文件定义了一些宏来指定各种扩展整数类型的常量。从根本上说这些宏就是到底层类型的类型指派,即到在特定实现中代表扩展类型的基本类型的指派。
在类型名中用_C来代替_t,然后把所有的字母大写就形成了宏名。例如,要使1000为unit_least64_t类型的常量,使用表达式UINT_LEAST64_C(1000)。
B.5.15 标准I/O库:stdio.h
ANSI C的标准库包括了一些与流相关的标准I/O函数和stdio.h文件。表B.31列出了这些函数的ANSI原型以及对它们功能的简单解释(很多都在第13章“文件输入/输出”中进行了完整的描述)。这个头文件也定义了FILE类型、值EOF和NULL以及标准I/O流stdin、stdout和stderr,还有一些库中的函数所使用的常量。
表B.31 ANSI C的标准I/O函数
原 型 | 说 明 |
---|---|
void clearerr(FILE *); | 清除文件结尾和错误指示器 |
int fclose(FILE *); | 关闭指定的文件 |
int feof(FILE *); | 测试文件结尾 |
int ferror(FILE *); | 测试错误指示器 |
int fflush(FILE *); | 刷新指定的文件 |
int fgetc(FILE *); | 从指定的输入流中获取下一个字符 |
int fgetpos(FILE * restrict, fpos_t * restrict); | 存储文件位置指示器的当前值 |
char * fgets(char * restrict, FILE * restrict); | 从指定的流中获取下一行(或指定数目的字符) |
FILE * f open(const char * restrict, const char * restrict); | 打开指定的文件 |
int fprintf(FILE * restrict, const char * restrict,...); | 把格式化输出写到指定的流中 |
int fputc(int, FILE *); | 把指定的字符写到指定的流中 |
int fputs(const char * restrict, FILE * restrict); | 把第一个参数指向的字符串写到指定的流中 |
size_t fread(void * restrict, size_t, size_t, FILE * restrict); | 从指定的流中读取二进制数据 |
FILE * freopen(const char * restrict, const char * restrict, FILE * restrict); | 打开指定的文件并把它与指定的流相关联 |
int fscanf(FILE * restrict, const char * restrict,…); | 从指定的流中读取格式化输入 |
int fsetpos(FILE *,const fpos_t *); | 把文件位置指针设置为指定的值 |
int fseek(FILE *,long, int); | 把文件位置指针设置为指定的值 |
long ftell(FILE *); | 获得当前的文件位置 |
size_t fwrite(const void * restrict, size_t, size_t,FILE * restrict); | 把二进制数据写到指定的流中 |
int getc(FILE *); | 从指定的流中读取下一个字符 |
int getchar(); | 从标准输入中读取下一个字符 |
char * gets(char *); | 从标准输入中获取下一行 |
void perror(const char *); | 把系统错误信息写到标准错误中 |
int print f(const char * restrict, …); | 把格式化输出写到标准输出中 |
int putc(int, FILE *); | 把指定的字符写到指定的输出中 |
int putchar(int); | 把指定的字符写到标准输出中 |
int puts(const char *); | 把字符串写到标准输出中 |
int remove(const char *); | 删除指定的文件 |
int rename(const char *, constchar *); | 为指定的文件重命名 |
void rewind(FILE *); | 把文件位置指针设置到文件的开始 |
int scanf(const char * restrict, …); | 从标准输入中读取格式化输入 |
void setbuf(FILE * restrict, char * restrict); | 设置缓冲区大小和位置 |
int setvbuf(FILE * restrict, char * restrict, int, size_t); | 设置缓冲区大小、位置和模式 |
int snprintf(char * restrict, size_ t n, const char * restrict,…); | 把格式化输出的前n个字符写到指定的字符串中 |
int sprint f(char * restrict, const char * restrict, …); | 把格式化输出写到指定的字符串中 |
int sscanf(const char * restrict, const char * restrict, …); | 从指定的字符串中读取格式化输入 |
FILE * tmpfile(void); | 创建一个临时文件 |
char * tmpnam(char *); | 为临时文件产生一个惟一的名字 |
int ungetc(int, FILE *); | 把指定的字符放回到输入流中 |
int vfprintf(FILE * restrict, const char * restrict, va_list); | 与fprintf()类似;但它使用一个由va_start进行初始化的 va_list类型的列表参数,而不是一个变量参数列表 |
int vprintf(const char * restrict, va_list); | 与printf()类似;但它使用一个由va_start进行初始化的 va_list类型的列表参数,而不是一个变量参数列表 |
int vsprintf(char * restrict, size_t n, const char * restrict, va_list); | 与snprintf()类似;但它使用一个由va_start进行初始化 的va_list类型的列表参数,而不是一个变量参数列表 |
int vsprintf(char * restrict, const char * restrict, va_list); | 与sprintf()类似;但它使用一个由va_start进行初始化的 va_list类型的列表参数,而不是一个变量参数列表 |
B.5.16 通用工具:stdlib.h
ANSI C标准库包括了各种类型的实用函数,它们在stdlib.h中被定义。这个头文件定义了表B.32中列出的类型。
表B.32 stdlib.h中定义的类型
类 型 | 说 明 |
---|---|
size_t | sizeof运算符返回的整数类型 |
wchar_t | 用来表示宽字符的整数类型 |
div_t | div()返回的结构类型;它具有quot和rem成员,两个成员都为int类型 |
ldiv_t | ldiv()返回的结构类型,它具有quot和rem成员,两个成员都为long类型 |
lldiv_t | lldiv()返回的结构类型,它具有quot和rem成员,两个成员都为long long类型(C99) |
这个头文件还定义了表B.33中列出的常量。
表B.33 stdlib.h中定义的常量
类 型 | 函 数 |
---|---|
NULL | 空指针(等于0) |
EXIT_FAILURE | 可以作为exit()的参数来使用,表示没有成功地执行一个程序 |
EXIT_SUCCESS | 可以作为exit()的参数来使用,表示成功地执行了一个程序 |
RAND_MAX | rand()返回的最大值(一个整数) |
MB_CUR_MAX | 对应于当前场所的扩展字符集中的多字节字符的最大字节数 |
表B.34列出了stdlib.h中的函数原型。
表B.34 通用工具
原 型 | 说 明 |
---|---|
double atof(const char * nptr); | 返回把nptr的开始部分转换为double类型的值;在碰到第一个不是数字的字符时结 束转换;跳过开始的空格,如果没有数字则返回0 |
int atoi(const char * nptr); | 返回把nptr的开始部分转换为int类型的值;在碰到第一个不是数字的字符时结束 转换;跳过开始的空格;如果没有数字则返回0 |
int atol(const char * nptr); | 返回把nptr的开始部分转换为long类型的值;在碰到第一个不是数字的字符时结 束转换;跳过开始的空格;如果没有数字则返回0 |
double strtod(const char * restrict npt, char ** restrict ept); | 返回把nptr的开始部分转换为double类型的值;在碰到第一个不是数字的字符时结束转 换;跳过开始的空格;如果没有数字则返回0;如果转换成功,把数字之后第一个字符 的地址赋值给ept指向的位置;如果转换规,把npt赋值给ept指向的位置 |
float strtof(const char * restrict ipt, char ** restrict ept); | 与strtod()相同,只是把nptr指向的字符串转换为float类型的值(C99) |
long double strtols(const char * restrict npt, char ** restrict ept); | 与strtod()相同,只是把nptr指向的字符串转换为long double类型的值(C99) |
long strtol(const char * restrict npt, char ** restrict ept, int base); | 返回把字符串nptr的开始部分转换为long类型的值;在碰到第一个不是数字的字 符时结束转换;跳过开始的空格;如果没有数字则返回0;如果转换成功,把数字 之后第一个字符的地址赋值给ept指向的位置;如果转换失败,把npt赋值给ept 指向的位置。假定字符串中的数字是以base指定的数为基数的 |
long long strtoll(const char * restrict npt, char ** restrict ept, int base); | 与strtol()相同,只是把nptr指向的字符串转换为long long类型的值(C99) |
unsigned long strtoul(const char * restrict npt, char ** restrict ept, int base); | 返回把字符串nptr的开始部分转换为unsigned long类型的值;在碰到第一个不是数字 的字符时结束转换;跳过开始的空格;如果没有数字则返回0;如果转换成功,把数 字之后第一个字符的地址赋值给ept指向的位置;如果转换失败,把npt赋值给ept 指向的位置。假定字符串中的数字是以base指定的数为基数的 |
unsigned long long strtoull(const char * restrict npt,char ** restrict ept, int base); | 与strtoul()相同,只是把nptr指向的字符串转换为unsigned long long类型的值(C99) |
int rand(void); | 返回0到RAND—MAX范围内的一个伪随机整数 |
void srand(unsigned int seed); | 把seed设置为随机数生成器的种子;如果在调用srand()之前调用rand(),则 种子为1 |
void * calloc(size_t nmem, size_t size); | 为具有nmem个成员的数组分配空间,其中每个元素的大小都为size个字节;空间 中所有位都初始化为0;如果成功函数返回数组的地址,否则返回NULL |
void free(void * ptr); | 释放ptr指向的空间;ptr应该是以前对calloc()、malloc()或realloc()的调用 返回的值;ptr也可以是空指针,这种情况下不进行任何动作;如果是其他的指针值 则其行为没有定义 |
void * malloc(size_t size); | 在内存中分配一块大小为size字节的未初始化的块;如果成功函数返回数组的地址, 否则返回NULL |
void * realloc(void * ptr, size_t size); | 把ptr指向的内存块大小改变为size字节;从块开始一直到新旧大小中较小值的部 分中的内容不被改变;函数返回块的位置,它可能被移动。如果空间不能被重分 配,函数返回NULL并且不改变原始的块;如果ptr为空,就相当于调用参数为size 的malloc();如果size为0而ptr不为空,就相当于调用参数为ptr的free() 函数 |
void abort(void); | 除非信号SIGABRT被捕获而且对应的信号处理器没有返回,否则会使程序异常终 止;对I/O流和临时文件的关闭要依赖于实现;该函数执行raise(SIGABRT) |
int atexit(void(* func)(void)); | 注册ftinc指向的函数,使它在程序正常结束时被调用;实现应该至少支持注册32 (void));个函数,按照它们注册的相反顺序进行调用;如果注册成功,函数返回0,否则返 回一个非0值 |
void exit(int status); | 使程序正常退出:首先调用由atexit()注册的函数,然后刷新所有打开的输出流, 关闭所有的I/O流,关闭所有由tmpfile()创建的文件,然后把控制返回到主机环 境中。如果status为0或EXIT_SUCCESS,就向主机环境返回一个实现定义的表示 成功结束的值;如果status为EXIT_FAILURE,就向主机环境返回一个实现定义的 示不成功结束的值;其他status值的效果要由实现来定义 |
void _Exit(int status); | 类似于exit();只是不调用由atexit()注册的函数,也不调用signal()注册的 信号处理器,并且对已打开的流的处理方法要由实现定义(C99) |
char * getenv(const char * name); | 返回指向一个字符串的指针,这个字符串表示由name指向的环境变量的值;如果 没有相匹配的名字则返回NULL |
int system(const char * str); | 把str指向的字符串传递给由像DOS或UNIX这样的命令处理器执行的主机环境; 如果str是空指针,那么如#命令处理器可用,函数就返回一个非0值,否则返回0; 如果str不是空指针,返回k要依赖于实现 |
void * bsearch(const void * key, const void * base, size_t nmem, size_t size, int(* comp) (const void *,const void *) ) ; | 搜索由base指向的具有nmem个大小为size的元素的数组,来寻找与key指向的对 象相匹配的元素。项目的比较由comp指向的比较函数执行:如果key对象小于一 个数组元素,那么比较函数就返回一个小于0的值;如果它们相等则返回0;如果 key对象比数组元素大就返回一个大于0的值。函数返回指向匹配元素的指针;如 果没有匹配的元素,函数就返回NULL;如果有多个元素与key对象匹配,那么不 指定选中哪个匹配的元素 |
void qsort Cvoid * base, size_t nmem, size_t size, int(* comp) (const void *, const void * )); | 把base指向的数组按comp指向的函数提供的顺序进行排序,这个数组具有nmem 个大小为size个字节的元素;如果第一个参数指向的对象小于第二个参数指向的对 象比较函数返回一个小于0的值,如果两个对象相等返回0,如果第一个对象大就 返回一个大于0的值 |
int abs(int n); | 返回n的绝对值;如果n是一个负数而且没有与它对应的正数,那么返回值没有定 义,在两个数都用补码表示而n为INT_MIN时就会发生这种情况 |
div_t div(int numer, int denom); | 计算number除以denom的商和余数,把商放在一个div_t结构的quot成员中,把 余数放在它的rem成员中;对于不精确的除法,商是大小小于算术商而距离算术商 最近的整数(也就是说,趋零截尾) |
long labs(int n); | 返回n的绝对值;如果n是一个负数而、且没有与它对应的正数,那么返回值没有定 义,在两个数都用补码表示而n为LONG_MIN时就会发生这种情况 |
ldiv_t ldiv(long numer, long denom); | 计算number除以denom的商和余数,把商放在一个ldiv_t结构的quot成员中,把 余数放在它的rem成员中;对于不精确的除法,商是大小小于算术商而距离算术商 最近的整数(也就是说,趋零截尾) |
long long llabs(int n); | 返回n的绝对值;如果n是一个负数而且没有与它对应的正数,那么返回值没有定 义,在两个数都用补码表示而n为LONG_LONG_MIN时就会发生这种情况(C99) |
lldiv_t 1 Idiv(long numer, long denom); | 计算number除以denom的商和余数,把商放在一个lldiv_t结构的quot成员中,把 余数放在它的rem成员中;对于不精确的除法,商是大小小于算术商而距离算术商 最近的整数(也就是说,趋零截尾)(C99) |
int mblen(const char * s, size_t n); | 返回组成s指向的多字节字符的字节数(最大为n);如果s指向空字符返回0;如 果s没有指向一个多字节字符返回−1;如果s为NULL,那么如果多字节字符是根 据状态进行编码则返回非0值,否则返回0 |
int mbtowc(wchar_t * pw, const char * s, size_t n); | 如果s不为空,就确定组成s指向的多字节字符的字节数(最大为n),并确定这 个多字节字符的wchai_t编码类型;如果pw不是空指针,就把这个编码类型赋值 给pw指向的位置;返回与mblen(s, n)相同的值 |
int wctomb(char * s, wchar_t wc); | 把wc中的字符编码转换为对应的多字节字符表示,并把它存储在s指向的数组中 (除非s是空指针)。如果s不是空指针,那么如果wc不对应一个合法的多字节 字符,就返回−1;如果wc合法,就返回组成多字节字符的字节数。如果s是空指 针,那么如果多字节字符是根据状态进行编码就返回非0值,否则返回0 |
size_t mbstowcs(wchar_t * restrict pwcs, const char * s restrict, si2e_t n); | 把s指向的多字节字符数组转换为一个存储在从pwcs开始的位置中的宽字符编码 数组;转换过程在到达pwcs的第n个元素或碰到s数组中的空字节时停止;如果 碰到一个非法的多字节字符就返回(size_t)(−1),否贝『返回填充了的数组元素个 数(不包括空字符,如果有的话) |
size_t wcstombs(char * restrict s, const wchart_t * restrict pwcs, size_t n); | 把存储在pwcs指向的数组中的宽字符编码序列转换为一个多字节字符序列,并把 它复制到s指向的位置。在存储了n个字节或碰到空字符时停止转换过程。如果碰 到一个非法的宽字符编码,就返回(size_t)(−1),否则返回填充的数组字节数(不 包括空字符,如果有的话) |
B.5.17 字符串处理:string.h
Strhig.h库定义了sisze_t类型,并为空指针定义了NULL宏。它提供了一些分析和操作字符串的函数,其中的一些函数以更通用的方式处理内存。表B.35列出了这些函数。
表B.35 字符串函数
原 型 | 说 明 |
---|---|
void * memchr(const void * s, int c, size_t n); | 在s指向的对象的开始n个字符中搜索c(转换为unsigned char)的第一次出现; 返回指向第一次出现处的指针,如果没有找到则返回NULL |
int memcmpCconst void * s1, const void * s2, size_t n); | 比较s1指向对象的前n个字符与s2指向对象的前n个字符,把每个值都解释为 如果所有n个值都匹配就说两个对象相等;否则,对两个对象的 第一个不匹配的对进行比较:如果二者相等返回0,如果第一个在数值上小于第 二个则返回小于0的值,如果第一个较大则返回大于0的值 |
void * memcpyCvoid * restrict s1, const void * restrict s2, size_t n); | 从s2指向的位置复制n个字节到s1指向的位置,如果两个位置重叠则其行为没 有定义;返回s1的值 |
void * memmove(void * s1, const void * s2, size_t n); | 从s2指向的位置复制n个字节到s1指向的位置,行为类似于复制;首先把s2 的字节复制到一个临时位置,这样当源位置和目标位置有重叠时,仍可完成复 制;返回s1的值 |
void * memset(void * s, int v, size_t n); | 把v的值(转换为unsigned char类型)复制到s指向的前n个字节中;返回s1 |
char * strcat(char * restrict s1, const char * restrict s2); | 把s2指向的字符串(包含空字符)追加到s1指向的字符串之后,字符串s2的 第一个字符覆盖字符串s1中的空字符;返回s1 |
char * strncat(char * restrict s1, const char * restrict s2, size_t n); | 把s2指向的字符串中的前n个字符或直到空字符为止(由二者中最先得到满足 的那个决定)的一个拷贝添加到s1指向的字符串之后,s2的第一个字符覆盖s1 中的空字符;总是要在最后添加一个空字符;函数返回s1 |
char * strcpy(char * restrict s1,. const char * restrict s2); | 把s2指向的字符串(包括空字符)复制到s1指向的位置;返回s1 |
char * strncpy(char * restrict s1, const char * restrict s2, size_t n); | 把s2指向的字符串的前n个字符或直到空字符为止的字符(由二者中最先得到 满足的那个决定)复制到s1指向的位置。如果拷贝n个字符之前s2中出现了空 字符,就添加若干空字符以使总长度为m如果在达到空宇符之前拷贝了n个字 符,就不添加空字符。函数返回s1 |
int strncmp(const char * s1, const char * s2); | 比较s1和s2指向的字符串,如果完全匹配那么两个字符串相等,否则就比较两个字符串的第一个不匹配的字符对;使用字符编码值对字符进行比较;如果字符串相同,函数返回0;如果第一个字符串小于弟二个就返回一个小于0的值;如果第一个字符串较大就返回一个大于0的值 |
int strcoll(const char * s1, const char * s2); | 与strcmp()类似,不过该函数使用由当前场所的LC_COLLATE类别所指定的 编码顺序,它是由setlocale()函数进行设置的 |
int strncmp(const char * s1, const char * s2, size_t n); | 比较s1和s2指向的数组的前n个字符或直到第一个空字符为止;如果所有的 测试对都匹配就说这两个数组相等,否则就比较两个数组的第一对不匹配的字 符;字符使用字符编码值进行比较;如果数组相同,函数返回0;如果第一个 数组小于第二个就返回一个小于0的值;如果第一个数组较大就返回一个大于 0的值 |
size_t strxfrm(char * restrict s1, const char * restrict s2, size_t n); | 转换s2中的字符串,并把包括结束空字符在内的前n个字符拷贝到s1指向的数 组中;转换的标准是两个转换后的字符串按与strcmp()相同的顺序来放置,就 像strcoll()放置未转换的字符串那样;函数返回转换后的字符串长度(不包括 结束空字符) |
char * strchr(const char * s, int c); | 在s指向的字符串中搜索c(转换为char)的第一次出现;空指针是字符 串的一部分;函数返回指向第一个出现的c的指针,如果没有找到则返回 NULL |
size_t strcspn(const char * s1, const char * s2); | 返回不包含s2中任何字符的s1的最大起始段的长度 |
char * strpbrk(const char * s1, const char * s2); | 返回一个指针,它指向s1中第一个与s2中的任何字符相同的字符位置,如果没 有一个相同则返回NULL |
char * strrchr(const char * s, int c); | 在s指向的字符串中搜索c(转换为char)的最后一次出现;空指针是字符 串的一部分;函数返回指向最后一个出现的c的指针,如果没有找到则返回 NULL |
size_t strspn(const char * s1, const char * s2); | 返回s1中完全由s2中的字符组成的最大起始段的长度 |
char * strstr(const char * s1, const char * s2); | 返回一个指针,它指向s1中第一次出现s2中字符序列(不包括结束空字符)的 位置,如果没有匹配则返回NULL |
char * strtok(char * restrict s1, const char * restrict s2); | 这个函数把字符串s1分为单独的元组,s2包含着被用做元组分隔符的字符。这 个函数是顺序调用的,对开始的调用,s1应该指向要被分隔为元组的字符串。 函数查找非分隔符之后的第一个元组分隔符,并用一个空字符来替换它。它返 回指向保存着第一个元组的字符串的指针。如果没有找到任何元组就返回 NULL。要在字符串中找到更多的元组,要再次调用strtok(),但是使用NULL 作为第一个参数。每个调用都返回指向下一个元组的指针,如果没有更多的元 组就返回NULL。请参见本表后面的例子 |
char * strerror(int errnum); | 返回指向对应于存储在errnum中的错误号的错误信息字符串的指针,这个字符 串是依赖于实现的 |
int strlen(const char * s); | 返回字符串s中的字符数(不包括结束空字符) |
strtok()函数在使用方面有些不同寻常,所以下面给出一个简短的例子:
输出如下:
B.5.18 通用类型数学:tgmath.h(C99)
math.h和complex.h库提供了很多类型不同但功能类似的函数的例子。例如,下面的6个函数都是计算正弦的:
tgmath.h头文件定义了展开为通用调用的宏,这种调用可以根据参数类型来调用适当的函数。以下的代码说明了sin()宏的使用,它展开为正弦函数的不同形式。
这个头文件为三种类型的函数定义了通用的宏。第一类由在math.h和complex.h中定义的6个函数变种组成,它们就像前面的sin()例子中那样使用1、f后缀和c前缀。在这种情况中,通用宏的名字与该函数的类型为double的版本相同。
第二类由math.h中定义的3个函数变种组成,它们使用1和f后缀,没有对应的复数函数,例如erf()。这种情况中,宏的名字与没有后缀的函数相同,例如前面的函数例子的宏应为erf()。把这类宏用于复数参数的结果没有定义。
第三类由cmplex.h中定义的3个函数变种组成,它们使用1和f后缀,没有对应的实数函数,例如cimag()。这种情况中,宏的名字与例子中没有后缀的函数相同,例如前面的函数例子的宏应为cimag()。把这类宏用于实数参数的结果没有定义。
B.5.19 日期和时间:time.h
time.h头文件定义了两个宏。第一个是表示空指针的NULL,它也在很多其他的头文件中进行了定义。第二个宏是CLOCKS_PER_SEC;用这个宏去除clock()的返回值将产生以秒为单位的时间值。这个头文件定义了在表B.36中列出的类型。
表B.36 time.h中定义的类型
类 型 | 说 明 |
---|---|
size_t | sizeof运算符返回的整数类型 |
clock_t | 适合于表示时间的算术类型 |
time_t | 适合于表示时间的算术类型 |
struct tm | 用于保存组成日历时间各个部分的结构类型 |
日历的各个组成部分被称为分解时间(broken-down time)。表B.37列出了结构struct tm中所需的成员。
表B.37 结构struct tm的成员
成 员 | 说 明 |
---|---|
int tm_sec | 分后的秒(0-61) |
int tm_min | 小时后的分(0-59) |
int tm_hour | 午夜后的小时(0-23) |
int tm_mday | 月中的天(0-31) |
int tm_mon | 一月后的月数(0−11) |
int tm_year | 1900年后的年数 |
int tm_wday | 星期日以后的天数(0-6) |
int tm_yday | 一月一日后的天数(0-365) |
int tm_isdst | 夏令时标志(大于0的值说明夏令时有效,0说明无效,负数说明信息不可用) |
术语日历时间(calendar time)表示当前的日期和时间,例如它可以是自从1900年的第1秒以来经过的秒数。术语本地时间(local time)是表达为本地时区的日历时间。表B.38列出了时间函数。
表B.38 时间函数
原 型 | 说 明 |
---|---|
clock_ t clock(void); | 返回实现中自从调用程序以来经过的处理器时间的最近近似;除以 CLOCKS_PER_SEC可以得到以秒计算的时间,如果时间不可用或不能表示则返 回(clock_t)(−1) |
double difftime(time_t t1, time_t t0); | 计算两个日历时间之间的不同(t1-t0),结果以秒表示并返回该结果 |
time_t mktime(struct tm * tmptr); | 把tmptr指向的结构中的分解时间转换为日历时间;使用与time()函数相同 的编码,结构会被改变,以便对结构中超出范围的值进行调整(例如2分100 秒会变为3分40秒),并且tm_wday和tm_yday被设置为根据其他成员确定 的值;如果日历时间不可表示则返回(time_t)(−1),否则以time_t格式返 回日历时间 |
time_t time(time_t * ptm) | 如果ptm不为NULL,就返回当前日历时间,并且把它放在ptm指向的位置中, 如果日历时间不可用就返回(time_t)(−1) |
char * asctime(const struct tm * tmpt); | 把tmpt指向的结构中的分解时间转换为如下格式的字符串:Thu Feb 26 13:14: 33 1998\n\0,并返回指向该字符串的指针 |
char * ctime(const time_ t * ptm); | 把ptm指向的日历时间转换为如下格式的字符串:Wed Aug 11 10:48:24 1999\n\0,并返回指向该字符串的指针 |
struct tm * gmtime(const time_t * ptm); | 把ptm指向的日历时间转换为用国际标准时间(Coordinated Universal Time,UTC,更正规的名字叫做格林威治时间,Greenwich Mean Time,GMT)表示的 分解时间,并返回指向保存该信息的结构的指针;如果UTC不可用则返回NULL |
struct tm * localtime time_t * ptm); | 把ptm指向的日历时间转换为用本地时间表示的分解时间,结果存储在一个tm 结构中并返回指向该结构的指针 |
size_t strftime(char * restrict s,size _t max, const char * restrict fmt, const struct tm * restrict tmpt); | 把字符串fmt复制到字符串s中,使用由tmpt指向的结构中的分解时间得出的 适当数据来替换fmt中的格式说明符(请参见表RS.V.39);最多有max个字符 被放到s中;函数返回放入s的字符数(不包括空字符);如果结果字符串(包 括空字符)有多于max个字符,函数返回0,而且s的内容不能确定 |
表B.39列出了strftime()函数中使用的格式指定符。很多替换值,例如月名,都依赖于当前场所。
表B.39 strftime()函数使用的格式说明符
格式说明符 | 替 换 内 容 |
---|---|
%a | 场所中的缩写周日(weekday)名 |
%A | 场所中周日的全名 |
%b | 场所中的缩写月名 |
%B | 场所中月的全名 |
%c | 场所中适当的日期和时间表示 |
%d | 一个月中的日,用十进制数表示(01-31) |
%D | 等价于“%m/%d%y” |
%e | 一个月中的日,用十进制表示,单数字的日在数字前有一个空格 |
%F | 等价于“%Y-%m-%d” |
%g | 基于周的年的最后两位数字(00-99) |
%G | 基于周的年,用十进制数表示 |
%h | 等价于“%b” |
%H | 小时数(24小时制),用十进制数表示(00-23) |
%I | 小时数(12小时制),用十进制数表示(01-12) |
%j | 一年中的天,用十进制数表示(001-366) |
%m | 用十进制表示的月(01−12) |
%n | 字符 |
%M | 用十进制表示的分(00-59) |
%P | 在12小时制中am/pm的场所等价表示 |
%r | 场所的12小时制时间 |
%R | 等价于“%H: %M” |
%S | 用十进制数表示的秒(00-60) |
%t | 水平制表字符 |
%T | 等价于“%H: %M: %S” |
%u | ISO 8601的周日数(1-7),星期一为1 |
%U | 一年中的星期数,把星期日作为一周的第一天(00-53) |
%V | ISO 8601的一年中的星期数,把星期日作为一周的第一天(00-53) |
%w | 用十进制数表示的星期,从星期日开始(0-6) |
%W | 一中的星期数,把星期一作为一周的第一天(00-53) |
%x | 场所的日期表示 |
%X | 场所的时间表示 |
%Y | 用十进制数表示的不带世纪的年(00-99) |
%Y | 进制数表示的带有世纪的年 |
%z | 按照ISO 8601格式的相对CUT的偏移(“-800”意味着Greenwich之后8小时,这样就是向西8小时), 如果没有信息可用则没有字符 |
%Z | 时区名,如果没有信息可用则没有字符 |
%% | %(也就是百分号符号) |
B.5.20 扩展的多字节字符和宽字符工具:wchar.h(C99)
每种实现都有一个基本的字符集,要求C的char类型足够宽以便能处理这个集。实现可能也支持扩展的字符集,表示这些字符时可能要求每个字符使用多个字节。多字节字符可以与单字节字符一起存放在普通的char数组中,使用特定的字节值来指示一个多字节字符的存在并说明它的大小。多字节字符的解释要依赖于偏移状态(shift state)。在初始的偏移状态中,单字节字符保持它们通常的解释。特定的多字节字符可以改变偏移状态。在显式改变它之前一个特定的偏移状态保持有效。
wchar_t类型提供了表示扩展字符的另一种方法,这种类型足够宽,可以用来表示扩展字符集中任何成员的编码。这种宽字符表示允许单个字符存储在wchar_t变量中,宽字符的字符串存储在wchar_t数组中。一个字符的宽字符表示不需要与它的多字节表示相同,因为后者可能使用偏移状态而前者不使用。
wchar.h头文件提供了处理扩展字符的两种表示形式的工具。它定义了表B.40中列出的类型(其中一些类型也在其他头文件中进行了定义)。
表B.40 wchar.h中定义的类型
类 型 | 说 明 |
---|---|
wchar_t | 一种整数类型,可以表示支持的场所指定的最大扩展字符集 |
wint_t | —种整数类型,可以保存扩展字符集的任何值和至少一个不是扩展字符集成员的值 |
size_t | 由sizeof运算符返回的整数类型 |
mbstate_t | 一个非数组类型,可以保存在多字节字符和宽字符之间转换所需的转换状态信息 |
struct tm | 一个用来保存日历时间组成部分的结构类型 |
这个头文件也定义了表B.41中列出的一些宏。
表B.41 wchar.h中定义的宏
宏 | 说 明 |
---|---|
NULL | 空指针 |
WCHAR_MAX | wchar_t的最大值 |
WCHAR_MIN | wchar_t的最小值 |
WE0F | 类型为wint_t的一个常量表达式,不与任何扩展字符集成员对应;EOF的宽字符等价表示,它 用来表示宽字符输入的文件结尾 |
这个库提供了类似于stdiah中标准I/O函数的输入/输出函数。在标准I/O函数返回EOF的情况中,对应的宽字符函数返回WEOF。表B.42列出了这些函数。
表B.42 宽字符I/O函数
还有一个没有对应的标准I/O函数的宽字符I/O函数:
如果mode为正,它首先尝试把参量stream表示的流定位于宽字符;如果mode为负就首先尝试使流定位于单字节字符;如果mode为0,则不对流的定位进行改变。它只有在流开始没有定位时才改变它。在所有的情况下,如果流定位于宽字符函数返回一个正值,如果流定位于字节则返回一个负值,如果流没有定位就返回0。
这个头文件也按照string.h中的模式提供了一些字符串转换和操作函数。一般地,string.h中的str标识符被wcs替换,这样wcstod()就是strtod()函数的宽字符版本。表B.43列出了这些函数。
表B.43 宽字符字符串工具
这个头文件还按照time.h中的strftime()函数的模式声明了一个时间函数:
最后,这个头文件声明了一些函数来把宽字符字符串转换为多字节字符串以及进行相反方向的转换,在表B.44中列出了这些函数。
表B.44 宽字符和多字节字符的转换函数
原 型 | 说 明 |
---|---|
wint_t btowc(int c); | 如果在初始偏移状态中(unsigned char)c是合法的单字节字符,函数返回宽字符表 示,否则返回WEOF |
int wctob(wint_t c); | 如果c是扩展字符集的成员,它在初始偏移状态中的多字节字符表示是单字节,函数 就返回一个转换为int的unsigned char的单字节表示,否则返回EOF |
int mbsinit(const mbstate_t * ps); | 如果ps为空指针或指向一个指定初始转换状态的数据对象,函数返回非0值,否则 返回0 |
size_t mbrlen(const char * restrict s, size_t n, mbstate_t * restrict ps); | 除了由ps表示的表达式只计算一次,mbrlen()函数相当于调用mbrtowc(NULL, 其中internal是mbrlen()函数的mbstate_t对象 |
size_t mbrtowc(wchar_t * restrict pwc, const char * restrict s, size_t n, mbstate_t * restrict ps); | 如果s为空指针,函数等价于把pwc设置为空指针,把n设置为1。如果s非空,函 数检查最多n个字节来确定要结束下一个多字节字符所需的字节数(包括任何偏移序 列)。如果函数确定了下一个多字节字符的结束处而且合法,它就确定对应的宽字 的值,然后如果pwc不为空就把值存储在pwc指向的对象中。如果对应的宽字符为 空的宽字符,描述的结果状态就是初始转换状态。如果检测到空的宽字符,函数就返 回0;如果检测到另一个合法的宽字符就返回结束该字符需要的字节数;如果n个字 节不足以说明合法的宽字符,而像是一个宽字符的组成部分,函数返回如果有编 码错误,函数返回−1,在errno中存储EILSEQ,并且不存储任何值 |
size_t wcrtomb(char *restrict s, wchar_t wc, mbstate_t * restrict ps); | 如果s为空指针,调用等价于把wc设置为空的宽字符并为第一个参数使用内部缓冲区。 如果s不为空指针,wcrtomb()函数确定要表示对应于wc给出的宽字符的多字节字符 需要的字节数(包括任何偏移序列),并把这个多字节字符表示存放在由s指向其第一 个元素的数组中。最多存储MB_CUR_MAX个字节。如果wc是空的宽字符,就在存储 初始偏移状态所需要的任何偏移序列之后存储一个空字节;描述的结果状态是初始转换 状态。如果wc是一个合法的宽字符,函数返回存储它的多字节版本所需的字节数(包 括指定偏移状态的字节)。如果wc不合法,函数在emio中存储EILSEQ并返回−1 |
size_t mbsrtowcs(wchar_t * restrict dst, const char ** restrict src, size_t Ien, mbstate_t * restrict ps); | mbstrtowcs()函数对以ps指向_的对像所描述的转换状态开头的一系列多字节字符进 行转换,从由scr间接指向的数组转换为一个对应的宽字符序列。如果dst不为空, 转换过的字符就被存储在dst指向的数组中。转换继续进行到包括结束空字符,这个 空字符也要进行存储。在两种情况下停止进行转换:当遇到一个不能组成合法多字节 字符的字节序列或(如果dst不为空)已经在dst指向的数组中存储了Ien个宽字符 时。每次发生的转换都好像是对mbrtowc()函数的调用。如果dst不为空,src指向 的指针对象就被赋值为空指针(如果转换是由于到达结束空字符而停止)或最后一个 转换的多字节字符的地址。如果转换是由于到达结束空字符而停止而且dst不为空, 描述的结果状态就为初始转换状态。如果执行成功,函数就返回成功转换的多字节字 符个数(不包括空字符)否则返回−1 |
size_t wcsrtombs(char * restrict dst, const wchar_t ** restrict src, size_t Ien, mbstate_t * restrict ps); | wcsrtombs()函数把src间接指向的数组中的宽字符序列转换为对应的以ps指向的 对象所描述的转换状态开头的多字节字符序列。如果dst不为空,转换后的字符就被 存储在dst指向的数组中。转换继续进行到包括结束空字符,这个空字符也要进行存 储。在两种情况下停止进行转换:当遇到一个不能对应于合法的多字节字符的宽字符 或(如果dst不为空)存储在由dst指向的数组中的下一个多字节字符会超过Ien个 字节的限制。每次发生的转换都好像是对wcrtomb()函数的调用。如果dst不为空, src指向的指针对象就被赋值为空指针(如果转换是由于到达结束空字符而停止)或 最后一个转换的宽字符地址。如果转换是由于到达结束空字符而停止,描述的结果状 态就为初始转换状态。如果执行成功,函数就返回结果多字节序列中的多字节字符个 数(不包括空字符),否则返回−1 |
B.5.21 宽字符分类和映射工具:wctype.h(C99 )
wctype.h库提供了类似于ctype.h中的字符函数的一些宽字符函数,以及其他一些函数。它也定义了表B.45中列出的三种类型和宏。
表B.45 wctype.h中的类型和宏
宏 | 说 明 |
---|---|
wint_t | 一个整数类型,可以保存扩展字符集的任何值,还至少可以保存一个不是扩展字符集 成员的值 |
wctrans_t | 一种标量类型,可以表示场所特定的字符映射 |
wctype_t | 一种标量类型,可以表示场所特定的字符分类 |
WEOF | 一个类型为wint_t的常量表达式,它不对应于扩展字符集中的任何成员,宽字符中与 之对应的是EOF,它用来表示宽字符输入的文件结尾 |
这个库中的字符分类函数在宽字符参数满足函数所说 明的条件时返回真(非0值)。一般地说,因为单字节字符对应于宽字符,所以在对应的ctype.h函数返回真时宽字符函数也返回真。表B. 46列出了这些函数。
表B.46 宽字符分类函数
原 型 | 说 明 |
---|---|
int iswalnum(wint_t wc); | 如果wc是表示字母数字(字母或数字)的字符则返回真 |
int iswalpha(wint_t wc); | 如果wc是表示字母的字符则返回真 |
int iswblank(wint_t wc); | 如果wc表示空白则返回真 |
int iswcntrl(wint_t wc); | 如果wc表示控制字符则返回真 |
int iswdigit(wint_t wc); | 如果wc是表示数字的字符则返回真 |
int iswgraph(wint_t wc); | 如果iswprint(wc)为真而iswspace(wc)为假则返回真 |
int iswlower(wint_t wc); | 如果wc表示小写字符则返回真 |
int iswprint(wint_t wc); | 如果wc表示可打印字符则返回真 |
int iswpunct(wint_t wc); | 如果wc表示标点字符则返回真 |
int iswspace(wint_t wc); | 如果wc表示制表、空格或换行符则返回真 |
int iswupper(wint_t wc); | 如果wc对应于大写字符则返回真 |
int iswxdigit(wint_t wc); | 如果wc表示十六进制数字则返回真 |
这个库也包括了两个可扩展(extensible)的分类函数,因为它们使用当前场所的LC_CTYPE值来对字符进行分类。表B.47列出了这些函数。
表B.47 可扩展的宽字符分类函数
原 型 | 说 明 |
---|---|
int iswctype(wint_t wc, wctype_t desc); | 如果wc具有desc所描述的属性则返回真(请参见正文中的相关讨论) |
??? Awctype_t wctype(const char *)) property: | wctype函数建立了一个类型为wctype_t的值,它描述了由字符串参数property 所确定的宽字符种类。如果根据当前场所的LCLCTYPE类别,property表示一 个合法的宽字符类别,wctype()函数就返回一个非0值,它可以作为iswctype ()函数的第二个参数,否则函数返回0 |
wctype()的合法参数由宽字符分类函数名去掉isw前缀组成。例如,wctype(“alpha”)就表现为由iswalpha()函数进行判断的字符类别。因此,调用:
就等价于调用:
除了其中的字符使用LC_CTYPE类别进行分类之外。
这个库提供了 4个与转换相关的函数。两个是ctype.h库中toupper()和tolower()的对应函数。第3个是一个可扩展的版本,使用场所中的LC_CTYPE设置来确定字符是大写还是小写。第4个则提供了适用于第3个函数的分类参数。表B.48列出了这些函数。
表B.48 宽字符转换函数
原 型 | 说 明 |
---|---|
wint_t towlower(wint_t wc); | 如果wc为大写则返回它的小写形式,否则返回wc |
wint_t towupper(wint_t wc); | 如果wc为小写则返回它的大写形式,否则返回wc |
wint_t towctrans(wint_t wc, wctrans_t desc); | 如果desc等于wctrans(“lower”)的返回值则返回wc的小写形式(由LC_CTYPE M设置确定),如果desc等于wctrans(“upper”)的返回值则返回wc的大写形式 (由LC_CTYPE设置确定) |
wctrans_t wctrans(const char * property); | 如果参数为"upper"或"lower",函数返回一个wctrans_t值,它可用作towctrans() 的参数并反映LC_CTYPE设置,否则函数返回0 |