跳到主要内容

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)