C Library
C 语言标准库
C89有 15 个头文件, C99 新增了 9 个,一共 24个。
标识符命名限制
- 由一个下划线和一个大写字母或两个下划线开头的标识符是标准库保留的
- 由一个下划线开头的是文件作用域保留的
- 标准库中的外部链接标识符都是保留的
输入/输出
绝大部分内容都在 <stdio.h>
头中
流
流(stream) 表示任意输入/输出的源或目的地,一般程序都是从一个流获得输入,再通过另一个流输出。
文件指针
C中访问流是通过文件指针实现的,类型为 FILE *
标准流
-
stdin
标准输入 -
stdout
标准输出 -
stderr
标准错误
文件类型
c中支持两种文件类型
- 文本文件,可分为若干行,并在文件末尾可以有一个特殊标记
- 二进制文件
文件操作
打开文件
FILE *fopen(const char * restrict filename, const char * restrict mode);
- 当文件无法打开时返回
NULL
- 模式中有 "b" 说明是二进制文件
模式说明
- "r" 读
- "w" 写
- "a" 追加
- "r+" 从文件头开始读和写
- "w+" 读和写文件,覆盖
-
"a+" 读和写文件,追加
常用模式
if ((fp = fopen(filename, "r")) == NULL) {}
关闭文件
int fclose(FILE *stream);
- 成功关闭返回 0,否则返回错误代码
EOF
为流重新指定文件
FILE *freopen(const char * restrict filename,
const char * restrict mode,
FILE * restrict stream);
临时文件
/* 创建临时文件 */
FILE *tmpfile(void);
/* 获取临时文件的名字 */
char *tmpnam(char *s);
文件缓冲
/* 清洗缓冲区 */
int fflush(FILE *stream);
/* 设置缓冲流 */
int setvbuf(FILE * restrict stream, char * restrict buf, int mode, size_t size);
删除文件
/* 删除文件 */
int remove(const char *filename);
/* 重命名文件 */
int rename(const char *old, const char *new);
数学与数值计算
- <float.h> 定义浮点类型的范围和精度,其中没有类型和函数
- <limits.h> 定义整数类型的取值范围,其中没有类型和函数
- <math.h> 定义数学计算的函数
- <stdint.h> 整数类型
- <inttypes.h> 整数类型的格式转换
- <complex.h> 复数
- <tgmath.h> 泛型数学
- <fenv.h> 浮点环境
错误
当发生错误时,大多数函数会将一个错误码存储到 errno
变量中。此外,如果函数返回值大于double类型最大值会返回 HUGE_VAL
值。
- 定义域错误。当函数的参数超出定义域,会将
EDOM
存储到errno
中 - 取值范围错误。当函数返回值超出double范围时,会将
ERANGE
存储到errno
中
紧缩(constraction)
C99中新增加了融合乘加 (fused multiply-add) 函数,即
a = b * c + d;
a = fma(b, c, d);
这种合并可能会速度更快一点,编译器是否自动进行紧缩可以由 #pragma STDC FP_CONTRACT ON/OFF/DEFAULT
来控制。
字符、字符串与国际化
- <ctype.h> 处理字符
- <string.h> 处理字符串
- <locale.h> 本地化
- <iso646.h> 拼写替换
- <wchar.h> 多字节和宽字符工具
- <wctype.h> 宽字符分类和映射工具
<string.h>
提供了5种函数
- 复制: memcpy, memmove, strcpy, strncpy
- 拼接: strcat, strncat
- 比较: memcmp, strcmp, strcoll, strncmp, strxfrm
- 搜索: memchr, strchr, strcpn, strpbrk, strrchr, strspn, strstr, strtok
- 其它(初始化、长度): memset, strlen
错误处理
- <assert.h> 诊断
- <errno.h> 错误
- <signal.h> 信号处理
- <setjmp.h> 非局部跳转
<assert.h> 诊断
assert 是一个宏。当参数值为 0 时,assert 会向 stderr 写消息,并调用 abort 函数中止程序。
void assert(scalar expression);
<errno.h> 错误
错误代码存储在 errno 变量中,每次使用都要把它置零
errno 主要作用是说明错误类型,而不是发生错误
<signal.h> 信号处理
信号宏
UNIX 系统提供了更多信号宏,都是 SIG开头
- SIGABRT: 异常终止(可能来自abort)
- SIGFPE: 算术错误(除0或溢出)
- SIGILL: 无效指令
- SIGINT: 中断
- SIGSEGV: 无效存储访问
- SIGTERM: 终止请求
signal 函数
void (*signal(int sig, void (*func)(int)))(int);
signal(SIG, handler);
指定信号的处理函数
信号处理函数
- SIGDFL: 按默认方式处理,实现定义,大多数时候是终止程序
- SIGIGN: 忽略信号
raise 函数
int raise(int sig);
产生一个信号,0表示调用成功。
<setjmp.h> 非局部跳转
/* 设置跳转位置 */
int setjmp(jmp_buf env);
/* 跳转到 val 位置 */
void longjmp(jmp_buf env, int val);
可以实现跨函数的跳转
可变参数
<stdarg.h> 头
/* 可变参数类型,其中保存所有的可变参数 */
va_list ap;
/* 将 src 中的参数复制到 dest 中 */
void va_copy(va_list dest, va_list src);
/* 开始读取参数列表, parmN 为保存参数个数的变量名 */
void va_start(va_list ap, parmN);
/* 获取一个类型为 type 的参数,类似出栈 */
type va_arg(va_list ap; type);
/* 清理参数列表, 每次函数结束前都要用 */
void va_end(va_list ap);
日期和时间
<time.h> 中提供三种类型
- clockt 按时钟度量
- timet 日历时间
- struct tm 分解时间
时间处理函数
clock_t clock(void);
double difftime(time_t time1, time_t time0);
time_t mktime(struct tm *timeptr);
time_t time(time_t *timer);
时间转换函数
char *asctime(const struct tm *timeptr);
char *ctime(const time_t *timer);
struct tm *gmtime(const time_t *timer);
struct tm *localtime(const time_t *timer);
size_t strftime(char * restrict s, size_t maxsize,
const char * restrict format,
const struct tm * restrict timeptr);
实用工具
包括
- 数值转换函数: atof, atoi, atol, strtod, strtol, strtoul, atoll, strtof, strtold, strtoll, strtoull
- 伪随机序列生成函数: rand, srand
- 内存管理函数: malloc, calloc, realloc, free
- 与外部通信: abort, atexit, exit, _Exit, getenv, system
- 搜索与排序: bsearch, qsort
- 整数运算函数: abs, labs, llabs, div, ldiv, lldiv
- 多字节/宽字符转换函数
- 多字节/宽字符串转换函数
评论
Comments powered by Disqus