2. stdlib.h — 通用工具
提供通用工具函数,按功能分组说明。
头文件说明:本章按功能分组,下面几节的内容需要包含其他头文件:
- 2.3 的
strtoimax/strtoumax、2.4 的wcstoimax/wcstoumax、2.5 的imaxabs/imaxdiv:声明在<inttypes.h>。- 2.4 的
wcsto*系列、2.8 的多字节/宽字符转换:声明在<wchar.h>。
GNU99 方言:
-std=gnu99(或显式定义_DEFAULT_SOURCE)时,<stdlib.h>会额外暴露alloca/random/srandom等 POSIX/BSD 声明;-std=c99下这些声明默认不可见(alloca需显式#include <alloca.h>)。详见 10.8。
2.1 内存分配
void* malloc(size_t size)
分配内存。
- 输入: size 字节数
- 输出: void* 内存指针或 NULL
void* calloc(size_t nmemb, size_t size)
分配并清零内存。
- 输入: nmemb 元素数, size 元素大小
- 输出: void* 内存指针或 NULL
void* realloc(void *ptr, size_t size)
重新分配内存。
- 输入: ptr 原指针(可为 NULL), size 新大小
- 输出: void* 新内存指针或 NULL
- 注意: 原 ptr 在失败时不被释放
void free(void *ptr)
释放内存。
- 输入: ptr 内存指针(可为 NULL)
- 输出: 无
2.2 程序控制
void exit(int status)
正常终止程序。
- 输入: status 退出状态码
- 输出: 无(不返回)
- 注意: 调用已注册的 atexit 处理函数
void _Exit(int status)
立即终止程序(不清理)
- 输入: status 退出状态码
- 输出: 无(不返回)
- 注意: 不调用 atexit,不刷新流缓冲区
void abort(void)
异常终止程序。
- 输入: 无
- 输出: 无(不返回)
- 注意: 产生 SIGABRT 信号,不调用 atexit
int atexit(void (*func)(void))
注册退出处理函数。
- 输入: func 退出处理函数指针
- 输出: int 0 成功,非零失败
- 注意: 注册多个函数按 LIFO 顺序执行
int system(const char *command)
执行系统命令。
- 输入: command 命令字符串(为 NULL 时检查是否有 shell)
- 输出: int 命令退出状态或 -1
2.3 字符串转数值
int atoi(const char *nptr)
字符串转 int。
- 输入: nptr 数字字符串
- 输出: int 转换结果(无错误检测)
long atol(const char *nptr)
字符串转 long。
- 输入: nptr 数字字符串
- 输出: long 转换结果
long long atoll(const char *nptr)
字符串转 long long。
- 输入: nptr 数字字符串
- 输出: long long 转换结果
double atof(const char *nptr)
字符串转 double。
- 输入: nptr 数字字符串
- 输出: double 转换结果
long strtol(const char *nptr, char **endptr, int base)
字符串转 long(带错误检测)
- 输入: nptr 字符串, endptr 结束指针(可为 NULL), base 进制(0 表示自动推断)
- 输出: long 转换结果
- 注意: errno 设为 ERANGE 表示溢出
long long strtoll(const char *nptr, char **endptr, int base)
字符串转 long long。
- 输入: nptr 字符串, endptr 结束指针, base 进制
- 输出: long long 转换结果
unsigned long strtoul(const char *nptr, char **endptr, int base)
字符串转 unsigned long。
- 输入: nptr 字符串, endptr 结束指针, base 进制
- 输出: unsigned long 转换结果
unsigned long long strtoull(const char *nptr, char **endptr, int base)
字符串转 unsigned long long。
- 输入: nptr 字符串, endptr 结束指针, base 进制
- 输出: unsigned long long 转换结果
intmax_t strtoimax(const char *nptr, char **endptr, int base)
字符串转最大有符号整数。
- 输入: nptr 字符串, endptr 结束指针, base 进制
- 输出: intmax_t 转换结果
uintmax_t strtoumax(const char *nptr, char **endptr, int base)
字符串转最大无符号整数。
- 输入: nptr 字符串, endptr 结束指针, base 进制
- 输出: uintmax_t 转换结果
double strtod(const char *nptr, char **endptr)
字符串转 double。
- 输入: nptr 字符串, endptr 结束指针(可为 NULL)
- 输出: double 转换结果
float strtof(const char *nptr, char **endptr)
字符串转 float。
- 输入: nptr 字符串, endptr 结束指针
- 输出: float 转换结果
long double strtold(const char *nptr, char **endptr)
字符串转 long double。
- 输入: nptr 字符串, endptr 结束指针
- 输出: long double 转换结果
2.4 宽字符转数值
long wcstol(const wchar_t *nptr, wchar_t **endptr, int base)
宽字符串转 long。
- 输入: nptr 宽字符串, endptr 结束指针, base 进制
- 输出: long 转换结果
long long wcstoll(const wchar_t *nptr, wchar_t **endptr, int base)
宽字符串转 long long。
- 输入: nptr 宽字符串, endptr 结束指针, base 进制
- 输出: long long 转换结果
unsigned long wcstoul(const wchar_t *nptr, wchar_t **endptr, int base)
宽字符串转 unsigned long。
- 输入: nptr 宽字符串, endptr 结束指针, base 进制
- 输出: unsigned long 转换结果
unsigned long long wcstoull(const wchar_t *nptr, wchar_t **endptr, int base)
宽字符串转 unsigned long long。
- 输入: nptr 宽字符串, endptr 结束指针, base 进制
- 输出: unsigned long long 转换结果
intmax_t wcstoimax(const wchar_t *nptr, wchar_t **endptr, int base)
宽字符串转 intmax_t。
- 输入: nptr 宽字符串, endptr 结束指针, base 进制
- 输出: intmax_t 转换结果
uintmax_t wcstoumax(const wchar_t *nptr, wchar_t **endptr, int base)
宽字符串转 uintmax_t。
- 输入: nptr 宽字符串, endptr 结束指针, base 进制
- 输出: uintmax_t 转换结果
double wcstod(const wchar_t *nptr, wchar_t **endptr)
宽字符串转 double。
- 输入: nptr 宽字符串, endptr 结束指针
- 输出: double 转换结果
float wcstof(const wchar_t *nptr, wchar_t **endptr)
宽字符串转 float。
- 输入: nptr 宽字符串, endptr 结束指针
- 输出: float 转换结果
long double wcstold(const wchar_t *nptr, wchar_t **endptr)
宽字符串转 long double。
- 输入: nptr 宽字符串, endptr 结束指针
- 输出: long double 转换结果
2.5 整数运算
int abs(int j)
整数绝对值。
- 输入: j 整数
- 输出: int 绝对值
long labs(long j)
long 绝对值。
- 输入: j long 值
- 输出: long 绝对值
long long llabs(long long j)
long long 绝对值。
- 输入: j long long 值
- 输出: long long 绝对值
intmax_t imaxabs(intmax_t j)
intmax_t 绝对值。
- 输入: j intmax_t 值
- 输出: intmax_t 绝对值
div_t div(int numer, int denom)
整数除法。
- 输入: numer 分子, denom 分母
- 输出: div_t 含 quot(商)和 rem(余数)
ldiv_t ldiv(long numer, long denom)
long 除法。
- 输入: numer 分子, denom 分母
- 输出: ldiv_t 商和余数
lldiv_t lldiv(long long numer, long long denom)
long long 除法。
- 输入: numer 分子, denom 分母
- 输出: lldiv_t 商和余数
imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom)
intmax_t 除法。
- 输入: numer 分子, denom 分母
- 输出: imaxdiv_t 商和余数
2.6 随机数
int rand(void)
生成伪随机数。
- 输入: 无
- 输出: int 0 ~ RAND_MAX
void srand(unsigned int seed)
设置随机数种子。
- 输入: seed 种子值
- 输出: 无
- 注意: 默认种子为 1
2.7 环境变量
char* getenv(const char *name)
获取环境变量值。
- 输入: name 变量名
- 输出: char* 值字符串或 NULL
- 注意: 返回的字符串不应被修改
2.8 多字节/宽字符转换
int mblen(const char *s, size_t n)
获取多字节字符长度。
- 输入: s 多字节字符(可为 NULL), n 最大检查字节数
- 输出: int 字节数、0(空字符) 或 -1(无效)
int mbtowc(wchar_t *pwc, const char *s, size_t n)
多字节转宽字符。
- 输入: pwc 宽字符指针(可为 NULL), s 多字节字符, n 最大字节数
- 输出: int 字节数、0 或 -1
int wctomb(char *s, wchar_t wchar)
宽字符转多字节。
- 输入: s 多字节缓冲区(可为 NULL), wchar 宽字符
- 输出: int 字节数、0 或 -1
- 注意: s 为 NULL 时返回编码是否依赖状态
size_t mbstowcs(wchar_t *dest, const char *src, size_t n)
多字节字符串转宽字符串。
- 输入: dest 宽字符缓冲区(可为 NULL), src 多字节字符串, n 最大宽字符数
- 输出: size_t 转换的宽字符数
size_t wcstombs(char *dest, const wchar_t *src, size_t n)
宽字符串转多字节字符串。
- 输入: dest 多字节缓冲区(可为 NULL), src 宽字符串, n 最大字节数
- 输出: size_t 转换的字节数
size_t mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
可重启多字节转宽字符。
- 输入: pwc 宽字符指针, s 多字节字符, n 长度, ps 转换状态
- 输出: size_t 字节数、0、-1(无效) 或 -2(不完整)
size_t wcrtomb(char *s, wchar_t wc, mbstate_t *ps)
可重启宽字符转多字节。
- 输入: s 多字节缓冲区, wc 宽字符, ps 转换状态
- 输出: size_t 字节数、0 或 -1
size_t mbrlen(const char *s, size_t n, mbstate_t *ps)
可重启获取多字节长度。
- 输入: s 多字节字符, n 长度, ps 转换状态
- 输出: size_t 字节数、0、-1 或 -2
size_t mbsrtowcs(wchar_t *dest, const char **src, size_t n, mbstate_t *ps)
可重启多字节字符串转宽字符串。
- 输入: dest 宽缓冲区, src 源字符串指针(会被更新), n 数量, ps 状态
- 输出: size_t 转换的宽字符数
size_t wcsrtombs(char *dest, const wchar_t **src, size_t n, mbstate_t *ps)
可重启宽字符串转多字节字符串。
- 输入: dest 多字节缓冲区, src 源宽字符串指针(会被更新), n 字节数, ps 状态
- 输出: size_t 转换的字节数
int mbsinit(const mbstate_t *ps)
检查转换状态是否初始。
- 输入: ps 状态指针
- 输出: int 非零表示初始状态
wint_t btowc(int c)
单字节转宽字符。
- 输入: c 单字节字符(EOF 或 unsigned char)
- 输出: wint_t 宽字符或 WEOF
int wctob(wint_t c)
宽字符转单字节。
- 输入: c 宽字符
- 输出: int 单字节字符或 EOF
2.9 搜索与排序
void* bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*cmp)(const void*, const void*))
二分查找。
- 输入: key 关键字, base 已排序数组(升序), nmemb 元素数, size 元素大小, cmp 比较函数
- 输出: void* 找到的元素指针或 NULL
- 注意: 数组必须已排序
void qsort(void *base, size_t nmemb, size_t size, int (*cmp)(const void*, const void*))
快速排序。
- 输入: base 数组, nmemb 元素数, size 元素大小, cmp 比较函数
- 输出: 无
- 注意: 不稳定排序,最坏 O(n^2),平均 O(n log n)