locale.h
简介
locale.h是程序的本地化设置,主要影响以下的行为。
数字格式
货币格式
字符集
日期和时间格式
它设置了以下几个宏。
LC_COLLATE:影响字符串比较函数strcoll()和strxfrm()。
LC_CTYPE:影响字符处理函数的行为。
LC_MONETARY:影响货币格式。
LC_NUMERIC:影响printf()的数字格式。
LC_TIME:影响时间格式strftime()和wcsftime()。
LC_ALL:将以上所有类别设置为给定的语言环境。
setlocale()
setlocale()用来设置当前的地区。
1char* setlocal(int category, const char* locale);
它接受两个参数。第一个参数表示影响范围,如果值为前面五个表示类别的宏之一,则只影响该宏对应的类别,如果值为LC_ALL,则影响所有类别。第二个参数通常只为"C"(正常模式)或""(本地模式)。
任意程序开始时,都隐含下面的调用。
1setlocale(LC_ALL, "C");
下面的语句将格式本地化 ...
limits.h
limits.h提供了用来定义各种整数类型(包括字符类型)取值范围的宏。
CHAR_BIT:每个字符包含的二进制位数。
SCHAR_MIN:signed char 类型的最小值。
SCHAR_MAX:signed char 类型的最大值。
UCHAR_MAX:unsiged char 类型的最大值。
CHAR_MIN:char 类型的最小值。
CHAR_MAX:char 类型的最大值。
MB_LEN_MAX:多字节字符最多包含的字节数。
SHRT_MIN:short int 类型的最小值。
SHRT_MAX:short int 类型的最大值。
USHRT_MAX:unsigned short int 类型的最大值。
INT_MIN:int 类型的最小值。
INT_MAX:int 类型的最大值。
UINT_MAX:unsigned int 类型的最大值。
LONG_MIN:long int 类型的最小值。
LONG_MAX:long int 类型的最大值。
ULONG_MAX:unsigned long int 类型的最大值。
LLONG_MIN:long long ...
iso646.h
iso646.h头文件指定了一些常见运算符的替代拼写。比如,它用关键字and代替逻辑运算符&&。
123if (x > 6 and x < 12)// 等同于if (x > 6 && x < 12)
它定义的替代拼写如下。
and 替代 &&
and_eq 替代 &=
bitand 替代 &
bitor 替代 |
compl 替代 ~
not 替代 !
not_eq 替代 !=
or 替代 ||
or_eq 替代 |=
xor 替代 ^
xor_eq 替代 ^=
inttypes.h
C 语言还在头文件 inttypes.h 里面,为 stdint.h
定义的四类整数类型,提供了printf()和scanf()的占位符。
固定宽度整数类型,比如 int8_t。
最小宽度整数类型,比如 int_least8_t。
最快最小宽度整数类型,比如 int_fast8_t。
最大宽度整数类型,比如 intmax_t。
printf()的占位符采用PRI + 原始占位符 + 类型关键字/宽度的形式构成。举例来说,原始占位符为%d,则对应的占位符如下。
PRIdn (固定宽度类型)
PRIdLEASTn (最小宽度类型)
PRIdFASTn (最快最小宽度类型)
PRIdMAX (最大宽度类型)
上面占位符中的n,可以用8、16、32、64代入。
下面是用法示例。
12345678#include <stdio.h>#include <stdint.h>#include <inttypes.h>int main(void) { int_least16_t x = 3490; printf(" ...
float.h
float.h定义了浮点数类型 float、double、long double
的一些宏,规定了这些类型的范围和精度。
FLT_ROUNDS
宏FLT_ROUNDS表示当前浮点数加法的四舍五入方向。
它有以下可能的值。
-1:不确定。
0:向零舍入。
1:向最近的整数舍入。
2:向正无穷方向舍入。
3:向负无穷方向舍入。
(2)FLT_RADIX
宏FLT_RADIX表示科学计数法的指数部分的底(base),一般总是2。
(3)浮点数类型的最大值
FLT_MAX
DBL_MAX
LDBL_MAX
(4)浮点数类型的最小正值
FLT_MIN
DBL_MIN
LDBL_MIN
(5)两个同类型浮点数之间可表示的最小差值(最小精度)
FLT_EPSILON
DBL_EPSILON
LDBL_EPSILON
(6)DECIMAL_DIG
宏DECIMAL_DIG表示十进制有效位数。
(7)FLT_EVAL_METHOD
宏FLT_EVAL_METHOD表示浮点数运算时的类型转换。
它可能有以下值。
-1:不确定。
0:在当前类型中运算。
1:float ...
errno.h
errno 变量
errno.h声明了一个 int 类型的 errno
变量,用来存储错误码(正整数)。
如果这个变量有非零值,表示已经执行的程序发生了错误。
12345678910int x = -1;errno = 0;int y = sqrt(x);if (errno != 0) { fprintf(stderr, "sqrt error; program terminated.\n"); exit(EXIT_FAILURE);}
上面示例中,计算一个负值的平方根是不允许的,会导致errno不等于0。
如果要检查某个函数是否发生错误,必须在即将调用该函数之前,将errno的值置为0,防止其他函数改变errno的值。
宏
变量errno的值通常是两个宏EDOM或ERANGE。这两个宏都定义在errno.h。它们表示调用数学函数时,可能发生的两种错误。
定义域错误(EDOM):传递给函数的一个参数超出了函数的定义域。例如,负数传入sqrt()作为参数。
取值范围错误(ERANGE):函数的返回值太大,无法用返回类型表示。 ...
ctype.h
ctype.h头文件定义了一系列字符处理函数的原型。
字符测试函数
这些函数用来判断字符是否属于某种类型。
isalnum():是否为字母数字
isalpha():是否为字母
isdigit():是否为数字
isxdigit():是否为十六进制数字符
islower():是否为小写字母
isupper():是否为大写字母
isblank():是否为标准的空白字符(包含空格、水平制表符或换行符)
isspace():是否为空白字符(空格、换行符、换页符、回车符、垂直制表符、水平制表符等)
iscntrl():是否为控制字符,比如 Ctrl + B
isprint():是否为可打印字符
isgraph():是否为空格以外的任意可打印字符
ispunct():是否为标点符号(除了空格、字母、数字以外的可打印字符)
它们接受一个待测试的字符作为参数。注意,参数类型为int,而不是char,因为它们允许
EOF 作为参数。
如果参数字符属于指定类型,就返回一个非零整数(通常是1,表示为真),否则返回0(表示为伪)。
下面是一个例子,用户输入一个字符,程序判断是否为英文字母。
...
assert.h
assert()
assert.h头文件定义了宏assert(),用于在运行时确保程序符合指定条件,如果不符合,就报错终止运行。这个宏常常被称为“断言”。
1assert(PI > 3);
上面代码在程序运行到这一行语句时,验证变量PI是否大于3。如果确实大于3,程序继续运行,否则就会终止运行,并且给出报错信息提示。
assert()宏接受一个表达式作为参数。如果该表达式为真(返回值非零),assert()不会产生任何作用,程序继续运行。如果该表达式为假(返回值为零),assert()就会报错,在标准错误流stderr中写入一条错误信息,显示没有通过的表达式,以及包含这个表达式的文件名和行号。最后,调用abort()函数终止程序(abort()函数的原型在stdlib.h头文件中)。
12z = x * x - y * y;assert(z >= 0);
上面的assert()语句类似于下面的代码。
1234if (z < 0) { puts("z less than 0"); abort();}
如 ...
多字节字符
本章介绍 C 语言如何处理非英语字符。
Unicode 简介
C 语言诞生时,只考虑了英语字符,使用7位的 ASCII 码表示所有字符。ASCII
码的范围是0到127,也就是100多个字符,所以char类型只占用一个字节。
但是,如果处理非英语字符,一个字节就不够了,单单是中文,就至少有几万个字符,字符集就势必使用多个字节表示。
最初,不同国家有自己的字符编码方式,这样不便于多种字符的混用。因此,后来就逐渐统一到
Unicode 编码,将所有字符放入一个字符集。
Unicode 为每个字符提供一个号码,称为码点(code
point),其中0到127的部分,跟 ASCII
码是重合的。通常使用“U+十六进制码点”表示一个字符,比如U+0041表示字母A。
Unicode 编码目前一共包含了100多万个字符,码点范围是 U+0000 到
U+10FFFF。完整表达整个 Unicode
字符集,至少需要三个字节。但是,并不是所有文档都需要那么多字符,比如对于
ASCII
码就够用的英语文档,如果每个字符使用三个字节表示,就会比单字节表示的文件体积大出三倍。
为了适应不同的使用 ...
命令行环境
命令行参数
C 语言程序可以从命令行接收参数。
1$ ./foo hello world
上面示例中,程序foo接收了两个命令行参数hello和world。
程序内部怎么拿到命令行参数呢?C
语言会把命令行输入的内容,放在一个数组里面。main()函数的参数可以接收到这个数组。
1234567#include <stdio.h>int main(int argc, char* argv[]) { for (int i = 0; i < argc; i++) { printf("arg %d: %s\n", i, argv[i]); }}
上面示例中,main()函数有两个参数argc(argument
count)和argv(argument
variable)。这两个参数的名字可以任意取,但是一般来说,约定俗成就是使用这两个词。
第一个参数argc是命令行参数的数量,由于程序名也被计算在内,所以严格地说argc是参数数量
+ 1。
第二个参数argv是一个数组,保存了所有的命令行输 ...