<stdlib.h> 是 C 标准库中最重要的头文件之一,它的名字是 "standard library"(标准库)的缩写,它提供了大量用于内存管理、程序控制、数字转换、排序和搜索等功能的通用函数。

(图片来源网络,侵删)
下面我将 <stdlib.h> 中的核心功能分门别类地进行介绍,并提供代码示例。
内存管理函数
这是 <stdlib.h> 最基础也是最常用的功能,用于在程序运行时动态地分配和释放内存。
void *malloc(size_t size)
- 功能: 分配一块指定大小的内存块。
- 参数:
size是需要分配的字节数。 - 返回值: 成功时返回指向分配内存块起始地址的
void*指针;失败时返回NULL。 - 特点: 分配的内存是未初始化是随机的(垃圾值)。
- 注意: 使用后必须用
free()释放,否则会造成内存泄漏。
#include <stdio.h>
#include <stdlib.h> // 包含 malloc 和 free
int main() {
int *ptr;
int n = 5;
// 分配 5 个 int 大小的内存
ptr = (int*)malloc(n * sizeof(int));
if (ptr == NULL) {
printf("内存分配失败!\n");
return 1;
}
// 使用分配的内存
for (int i = 0; i < n; i++) {
ptr[i] = i + 1; // 手动初始化
printf("%d ", ptr[i]);
}
printf("\n");
// 释放内存
free(ptr);
ptr = NULL; // 良好习惯:将指针置为 NULL,防止悬垂指针
return 0;
}
void *calloc(size_t num, size_t size)
- 功能: 分配一块内存,并将其中的每一位都初始化为零。
- 参数:
num是元素的数量,size是每个元素的大小(以字节为单位)。 - 返回值: 成功时返回指向分配内存块起始地址的
void*指针;失败时返回NULL。 - 特点: 自动清零,通常用于分配数组、结构体等需要初始为零的内存。
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
int n = 5;
// 分配 5 个 int 大小的内存,并初始化为 0
ptr = (int*)calloc(n, sizeof(int));
if (ptr == NULL) {
printf("内存分配失败!\n");
return 1;
}
// 打印,可以看到所有值都是 0
for (int i = 0; i < n; i++) {
printf("%d ", ptr[i]);
}
printf("\n");
free(ptr);
ptr = NULL;
return 0;
}
void free(void *ptr)
- 功能: 释放之前由
malloc、calloc或realloc分配的内存。 - 参数:
ptr是指向要释放的内存块的指针。 - 返回值:
void,无返回值。 - 注意: 传递给
free的指针必须是之前动态分配的内存地址,或者为NULL,对NULL指针调用free是安全的,但不会产生任何效果。
程序控制函数
void exit(int status)
- 功能: 立即终止正在执行的程序。
- 参数:
status是程序退出状态。0或EXIT_SUCCESS表示成功,非零值或EXIT_FAILURE表示失败。 - 特点: 会先执行所有已注册的
atexit函数,然后刷新所有缓冲的 I/O 流,最后终止程序。
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
fp = fopen("non_existent_file.txt", "r");
if (fp == NULL) {
perror("打开文件失败"); // 打印错误信息
exit(EXIT_FAILURE); // 退出程序,状态码为 1
}
// ... 其他代码 ...
fclose(fp);
return 0;
}
int atexit(void (*func)(void))
- 功能: 注册一个函数,当程序通过
exit()正常终止时调用该函数。 - 参数:
func是一个函数指针,指向没有参数也没有返回值的函数。 - 返回值: 成功返回
0,失败返回非零值。 - 注意:
main函数执行return语句时,也会调用atexit注册的函数。
#include <stdio.h>
#include <stdlib.h>
void cleanup() {
printf("程序即将退出,执行清理工作...\n");
}
int main() {
if (atexit(cleanup) != 0) {
fprintf(stderr, "注册清理函数失败!\n");
return 1;
}
printf("程序正在运行...\n");
// ... 程序主要逻辑 ...
return 0; // 程序结束时会调用 cleanup()
}
数值转换函数
这些函数用于将字符串表示的数字转换为对应的数值类型。
int atoi(const char *str)
- 功能: 将字符串转换为
int类型。 - 参数:
str要转换的字符串。 - 返回值: 转换后的整数值,如果转换失败(字符串不以数字开头),则返回
0。 - 注意: 无法检测转换错误,
atoi("123abc")会返回123。
#include <stdio.h>
#include <stdlib.h>
int main() {
char str1[] = "12345";
char str2[] = "-9876";
char str3[] = "hello";
int num1 = atoi(str1);
int num2 = atoi(str2);
int num3 = atoi(str3);
printf("'%s' -> %d\n", str1, num1); // '12345' -> 12345
printf("'%s' -> %d\n", str2, num2); // '-9876' -> -9876
printf("'%s' -> %d\n", str3, num3); // 'hello' -> 0
return 0;
}
double atof(const char *str)
- 功能: 将字符串转换为
double类型。 - 参数:
str要转换的字符串。 - 返回值: 转换后的双精度浮点数,如果转换失败,返回
0。
long strtol(const char *restrict str, char **restrict endptr, int base)
- 功能: 将字符串转换为
long类型,比atoi更强大、更安全。 - 参数:
str: 要转换的字符串。endptr: 一个指针,用于存储转换停止后的位置,可以设为NULL。base: 数字的进制。10表示十进制,16表示十六进制。0表示自动检测(如0x开头为16进制,0开头为8进制)。
- 返回值: 转换后的
long值。 - 特点: 可以检测转换错误,如果转换失败,
endptr会指向字符串的开头。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h> // 使用 strtol 需要包含 errno.h
int main() {
char str[] = " -12345abc 987";
char *endptr;
long num;
errno = 0; // 在调用前重置 errno
num = strtol(str, &endptr, 10);
// 检查是否发生错误
if (errno == ERANGE) {
printf("错误:数值超出 long 范围!\n");
} else if (endptr == str) {
printf("错误:没有数字被转换!\n");
} else {
printf("转换成功: %ld\n", num);
printf("转换停止在字符: '%c'\n", *endptr);
}
return 0;
}
随机数生成函数
int rand(void)
- 功能: 生成一个伪随机整数。
- 返回值: 一个在
0到RAND_MAX之间的整数(RAND_MAX是<stdlib.h>中定义的宏,通常至少是 32767)。 - 特点: 伪随机:每次运行程序时,如果种子相同,生成的随机数序列也相同。
void srand(unsigned int seed)
- 功能: 为
rand()函数设置随机数种子。 - 参数:
seed种子值。 - 特点: 通常使用当前时间作为种子,以确保每次运行程序时生成的随机数序列都不同。
#include <stdio.h>
#include <stdlib.h>
#include <time.h> // 用于 time() 函数
int main() {
// 使用当前时间作为随机数种子
srand((unsigned int)time(NULL));
printf("生成 5 个 1 到 100 之间的随机数:\n");
for (int i = 0; i < 5; i++) {
// rand() % (max - min + 1) + min
int random_num = rand() % 100 + 1;
printf("%d ", random_num);
}
printf("\n");
return 0;
}
搜索和排序函数
这些函数通常需要与 <stdlib.h> 中定义的比较函数和交换函数一起使用。

(图片来源网络,侵删)
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *))
- 功能: 使用快速排序算法对数组进行排序。
- 参数:
base: 指向要排序的数组的第一个元素的指针。nmemb: 数组中元素的数量。size: 每个元素的大小(以字节为单位)。compar: 一个指向比较函数的指针,该函数定义了元素的排序规则。
- 比较函数
compar的规则:- 返回负值:第一个参数应排在第二个参数之前。
- 返回零:两个参数相等。
- 返回正值:第一个参数应排在第二个参数之后。
#include <stdio.h>
#include <stdlib.h>
// 用于 qsort 的比较函数 (升序)
int compare_ints(const void *a, const void *b) {
int arg1 = *(const int*)a;
int arg2 = *(const int*)b;
if (arg1 < arg2) return -1;
if (arg1 > arg2) return 1;
return 0;
}
int main() {
int values[] = { 88, 56, 100, 2, 25 };
size_t n = sizeof(values) / sizeof(values[0]);
qsort(values, n, sizeof(int), compare_ints);
printf("排序后的数组: ");
for (size_t i = 0; i < n; i++) {
printf("%d ", values[i]);
}
printf("\n");
return 0;
}
void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *))
- 功能: 使用二分查找算法在已排序的数组中查找元素。
- 参数:
key: 指向要查找的元素的指针。base: 指向已排序数组的第一个元素的指针。nmemb: 数组中元素的数量。size: 每个元素的大小。compar: 与qsort相同的比较函数。
- 返回值: 如果找到,返回指向匹配元素的指针;否则返回
NULL。 - 注意: 必须对数组进行排序后才能使用
bsearch。
#include <stdio.h>
#include <stdlib.h>
// 与 qsort 相同的比较函数
int compare_ints(const void *a, const void *b) {
int arg1 = *(const int*)a;
int arg2 = *(const int*)b;
if (arg1 < arg2) return -1;
if (arg1 > arg2) return 1;
return 0;
}
int main() {
int values[] = { 2, 25, 56, 88, 100 };
int key = 56;
size_t n = sizeof(values) / sizeof(values[0]);
// 数组必须是已排序的
int *item = (int*)bsearch(&key, values, n, sizeof(int), compare_ints);
if (item != NULL) {
printf("找到了元素 %d\n", *item);
} else {
printf("未找到元素 %d\n", key);
}
return 0;
}
其他常用函数
int system(const char *command)
- 功能: 将字符串
command传递给宿主环境的命令处理器(通常是 shell)执行。 - 参数:
command是要执行的命令字符串。 - 返回值: 返回值依赖于系统,通常是命令执行后的退出状态。
- 注意: 这是一个非常强大的函数,但也可能带来安全风险(如命令注入),应谨慎使用。
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("系统将执行 'dir' 命令 (Windows) 或 'ls' 命令 (Linux/macOS)...\n");
// #ifdef _WIN32
// system("dir");
// #else
// system("ls -l");
// #endif
// 为了跨平台演示,这里只打印信息
printf("请根据您的操作系统手动执行相应的命令,\n");
return 0;
}
<stdlib.h> 是 C 语言编程的基石,提供了大量底层但至关重要的功能,掌握这些函数是成为一名合格 C 程序员的关键一步。
| 功能类别 | 核心函数 | 描述 |
|---|---|---|
| 内存管理 | malloc, calloc, free |
动态分配和释放内存 |
| 程序控制 | exit, atexit |
终止程序和注册退出处理函数 |
| 数值转换 | atoi, atof, strtol |
字符串与数字类型间的转换 |
| 随机数 | rand, srand |
生成伪随机数 |
| 搜索排序 | qsort, bsearch |
快速排序和二分查找 |
| 系统调用 | system |
执行系统命令 |
希望这份详细的讲解能帮助你全面理解 C 语言中的 std function。

(图片来源网络,侵删)
