Appearance
C 标准库 - <stdlib.h>
概述
<stdlib.h> 头文件提供了通用工具函数,包括内存分配、进程控制、类型转换、随机数生成、排序和搜索等功能。这是 C 语言中最常用的标准库之一。
内存管理
malloc()
c
void *malloc(size_t size);分配指定大小的内存块。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
int* ptr = (int*)malloc(10 * sizeof(int));
if (ptr == NULL) {
printf("内存分配失败\n");
return 1;
}
for (int i = 0; i < 10; i++) {
ptr[i] = i * 10;
}
for (int i = 0; i < 10; i++) {
printf("%d ", ptr[i]);
}
printf("\n");
free(ptr);
return 0;
}calloc()
c
void *calloc(size_t nmemb, size_t size);分配并初始化内存块为零。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
int* ptr = (int*)calloc(10, sizeof(int));
if (ptr == NULL) {
printf("内存分配失败\n");
return 1;
}
for (int i = 0; i < 10; i++) {
printf("%d ", ptr[i]);
}
printf("\n");
free(ptr);
return 0;
}realloc()
c
void *realloc(void *ptr, size_t size);重新分配内存块大小。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
int* ptr = (int*)malloc(5 * sizeof(int));
if (ptr == NULL) {
return 1;
}
for (int i = 0; i < 5; i++) {
ptr[i] = i;
}
printf("原始数组: ");
for (int i = 0; i < 5; i++) {
printf("%d ", ptr[i]);
}
printf("\n");
ptr = (int*)realloc(ptr, 10 * sizeof(int));
if (ptr == NULL) {
return 1;
}
for (int i = 5; i < 10; i++) {
ptr[i] = i;
}
printf("扩展数组: ");
for (int i = 0; i < 10; i++) {
printf("%d ", ptr[i]);
}
printf("\n");
free(ptr);
return 0;
}free()
c
void free(void *ptr);释放之前分配的内存块。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
int* ptr = (int*)malloc(10 * sizeof(int));
if (ptr != NULL) {
free(ptr);
printf("内存已释放\n");
}
return 0;
}进程控制
exit()
c
void exit(int status);正常终止程序。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("程序开始\n");
printf("程序即将退出\n");
exit(EXIT_SUCCESS);
printf("这行不会执行\n");
return 0;
}abort()
c
void abort(void);异常终止程序。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("程序开始\n");
abort();
printf("这行不会执行\n");
return 0;
}atexit()
c
int atexit(void (*func)(void));注册程序正常退出时调用的函数。
c
#include <stdio.h>
#include <stdlib.h>
void cleanup1() {
printf("清理函数 1\n");
}
void cleanup2() {
printf("清理函数 2\n");
}
int main() {
atexit(cleanup1);
atexit(cleanup2);
printf("程序运行中\n");
exit(EXIT_SUCCESS);
}类型转换
atoi()
c
int atoi(const char *str);将字符串转换为整数。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
const char* str = "12345";
int value = atoi(str);
printf("字符串 '%s' 转换为整数: %d\n", str, value);
return 0;
}atol()
c
long atol(const char *str);将字符串转换为长整数。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
const char* str = "1234567890";
long value = atol(str);
printf("字符串 '%s' 转换为长整数: %ld\n", str, value);
return 0;
}atof()
c
double atof(const char *str);将字符串转换为浮点数。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
const char* str = "3.14159";
double value = atof(str);
printf("字符串 '%s' 转换为浮点数: %f\n", str, value);
return 0;
}strtol()
c
long strtol(const char *str, char **endptr, int base);将字符串转换为长整数,支持错误检测。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
const char* str = "12345abc";
char* endptr;
long value = strtol(str, &endptr, 10);
printf("转换值: %ld\n", value);
printf("剩余字符串: %s\n", endptr);
return 0;
}strtod()
c
double strtod(const char *str, char **endptr);将字符串转换为浮点数,支持错误检测。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
const char* str = "3.14159abc";
char* endptr;
double value = strtod(str, &endptr);
printf("转换值: %f\n", value);
printf("剩余字符串: %s\n", endptr);
return 0;
}随机数
rand()
c
int rand(void);生成伪随机数。
c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand(time(NULL));
for (int i = 0; i < 10; i++) {
printf("%d ", rand() % 100);
}
printf("\n");
return 0;
}srand()
c
void srand(unsigned int seed);设置随机数种子。
c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand(time(NULL));
printf("随机数: %d\n", rand() % 100);
printf("随机数: %d\n", rand() % 100);
printf("随机数: %d\n", rand() % 100);
return 0;
}排序和搜索
qsort()
c
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));快速排序算法。
c
#include <stdio.h>
#include <stdlib.h>
int compare(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
}
int main() {
int arr[] = {5, 2, 8, 1, 9, 3};
int n = sizeof(arr) / sizeof(arr[0]);
printf("排序前: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
qsort(arr, n, sizeof(int), compare);
printf("排序后: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}bsearch()
c
void *bsearch(const void *key, const void *base,
size_t nmemb, size_t size,
int (*compar)(const void *, const void *));二分查找算法。
c
#include <stdio.h>
#include <stdlib.h>
int compare(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
}
int main() {
int arr[] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
int n = sizeof(arr) / sizeof(arr[0]);
int key = 7;
int* result = (int*)bsearch(&key, arr, n, sizeof(int), compare);
if (result != NULL) {
printf("找到 %d 在数组中\n", *result);
} else {
printf("未找到 %d\n", key);
}
return 0;
}整数运算
abs()
c
int abs(int x);计算整数的绝对值。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
int x = -10;
printf("abs(-10) = %d\n", abs(x));
return 0;
}labs()
c
long labs(long x);计算长整数的绝对值。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
long x = -100000;
printf("labs(-100000) = %ld\n", labs(x));
return 0;
}div()
c
div_t div(int numer, int denom);整数除法,返回商和余数。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
int numer = 17;
int denom = 5;
div_t result = div(numer, denom);
printf("%d / %d = %d 余 %d\n",
numer, denom, result.quot, result.rem);
return 0;
}ldiv()
c
ldiv_t ldiv(long numer, long denom);长整数除法,返回商和余数。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
long numer = 100000;
long denom = 3000;
ldiv_t result = ldiv(numer, denom);
printf("%ld / %ld = %ld 余 %ld\n",
numer, denom, result.quot, result.rem);
return 0;
}环境变量
getenv()
c
char *getenv(const char *name);获取环境变量的值。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
char* path = getenv("PATH");
if (path != NULL) {
printf("PATH: %s\n", path);
}
char* home = getenv("HOME");
if (home != NULL) {
printf("HOME: %s\n", home);
}
return 0;
}setenv()
c
int setenv(const char *name, const char *value, int overwrite);设置环境变量的值(POSIX)。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
setenv("MY_VAR", "Hello, World!", 1);
char* value = getenv("MY_VAR");
if (value != NULL) {
printf("MY_VAR: %s\n", value);
}
return 0;
}unsetenv()
c
int unsetenv(const char *name);删除环境变量(POSIX)。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
setenv("MY_VAR", "Hello, World!", 1);
char* value = getenv("MY_VAR");
if (value != NULL) {
printf("MY_VAR: %s\n", value);
}
unsetenv("MY_VAR");
value = getenv("MY_VAR");
if (value == NULL) {
printf("MY_VAR 已删除\n");
}
return 0;
}系统命令
system()
c
int system(const char *command);执行系统命令。
c
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("执行系统命令\n");
int result = system("ls -l");
if (result == -1) {
printf("命令执行失败\n");
} else {
printf("命令执行成功,返回值: %d\n", result);
}
return 0;
}实际应用示例
1. 动态数组
c
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int* data;
size_t size;
size_t capacity;
} DynamicArray;
DynamicArray* create_array(size_t initial_capacity) {
DynamicArray* array = malloc(sizeof(DynamicArray));
if (array == NULL) {
return NULL;
}
array->data = malloc(initial_capacity * sizeof(int));
if (array->data == NULL) {
free(array);
return NULL;
}
array->size = 0;
array->capacity = initial_capacity;
return array;
}
void push_back(DynamicArray* array, int value) {
if (array->size >= array->capacity) {
array->capacity *= 2;
array->data = realloc(array->data,
array->capacity * sizeof(int));
}
array->data[array->size++] = value;
}
void free_array(DynamicArray* array) {
free(array->data);
free(array);
}
int main() {
DynamicArray* array = create_array(5);
if (array == NULL) {
return 1;
}
for (int i = 1; i <= 10; i++) {
push_back(array, i);
}
printf("数组内容: ");
for (size_t i = 0; i < array->size; i++) {
printf("%d ", array->data[i]);
}
printf("\n");
free_array(array);
return 0;
}2. 随机密码生成
c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
void generate_password(char* password, int length) {
const char charset[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*";
int charset_size = strlen(charset);
srand(time(NULL));
for (int i = 0; i < length; i++) {
password[i] = charset[rand() % charset_size];
}
password[length] = '\0';
}
int main() {
char password[17];
generate_password(password, 16);
printf("生成的密码: %s\n", password);
return 0;
}3. 学生成绩排序
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[50];
int score;
} Student;
int compare_students(const void* a, const void* b) {
Student* sa = (Student*)a;
Student* sb = (Student*)b;
return sb->score - sa->score;
}
int main() {
Student students[] = {
{"张三", 85},
{"李四", 92},
{"王五", 78},
{"赵六", 95},
{"钱七", 88}
};
int n = sizeof(students) / sizeof(students[0]);
printf("排序前:\n");
for (int i = 0; i < n; i++) {
printf("%s: %d\n", students[i].name, students[i].score);
}
qsort(students, n, sizeof(Student), compare_students);
printf("\n排序后:\n");
for (int i = 0; i < n; i++) {
printf("%s: %d\n", students[i].name, students[i].score);
}
return 0;
}4. 配置文件解析
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE 256
void parse_config(const char* filename) {
FILE* file = fopen(filename, "r");
if (file == NULL) {
perror("无法打开配置文件");
return;
}
char line[MAX_LINE];
while (fgets(line, sizeof(line), file) != NULL) {
if (line[0] == '#' || line[0] == '\n') {
continue;
}
char key[100], value[100];
if (sscanf(line, "%99[^=]=%99s", key, value) == 2) {
printf("配置: %s = %s\n", key, value);
}
}
fclose(file);
}
int main() {
parse_config("config.txt");
return 0;
}5. 内存池
c
#include <stdio.h>
#include <stdlib.h>
typedef struct {
void* pool;
size_t pool_size;
size_t used;
} MemoryPool;
MemoryPool* create_pool(size_t size) {
MemoryPool* pool = malloc(sizeof(MemoryPool));
if (pool == NULL) {
return NULL;
}
pool->pool = malloc(size);
if (pool->pool == NULL) {
free(pool);
return NULL;
}
pool->pool_size = size;
pool->used = 0;
return pool;
}
void* pool_alloc(MemoryPool* pool, size_t size) {
if (pool->used + size > pool->pool_size) {
return NULL;
}
void* ptr = (char*)pool->pool + pool->used;
pool->used += size;
return ptr;
}
void free_pool(MemoryPool* pool) {
free(pool->pool);
free(pool);
}
int main() {
MemoryPool* pool = create_pool(1024);
if (pool == NULL) {
return 1;
}
int* a = pool_alloc(pool, sizeof(int));
double* b = pool_alloc(pool, sizeof(double));
char* c = pool_alloc(pool, 100);
if (a != NULL) *a = 42;
if (b != NULL) *b = 3.14;
if (c != NULL) strcpy(c, "Hello");
printf("a = %d\n", *a);
printf("b = %f\n", *b);
printf("c = %s\n", c);
printf("内存池使用: %zu/%zu\n", pool->used, pool->pool_size);
free_pool(pool);
return 0;
}6. 命令行参数解析
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void print_help() {
printf("用法: program [选项]\n");
printf("选项:\n");
printf(" -h, --help 显示帮助信息\n");
printf(" -v, --version 显示版本信息\n");
printf(" -f, --file 指定文件\n");
}
int main(int argc, char* argv[]) {
char* filename = NULL;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0 ||
strcmp(argv[i], "--help") == 0) {
print_help();
return 0;
} else if (strcmp(argv[i], "-v") == 0 ||
strcmp(argv[i], "--version") == 0) {
printf("版本: 1.0.0\n");
return 0;
} else if (strcmp(argv[i], "-f") == 0 ||
strcmp(argv[i], "--file") == 0) {
if (i + 1 < argc) {
filename = argv[i + 1];
i++;
}
}
}
if (filename != NULL) {
printf("处理文件: %s\n", filename);
} else {
printf("未指定文件\n");
print_help();
}
return 0;
}7. 进程监控
c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void monitor_process(int duration) {
time_t start_time = time(NULL);
time_t current_time;
printf("开始监控进程\n");
do {
current_time = time(NULL);
double elapsed = difftime(current_time, start_time);
printf("运行时间: %.0f 秒\n", elapsed);
sleep(1);
} while (difftime(current_time, start_time) < duration);
printf("监控结束\n");
}
int main() {
monitor_process(5);
return 0;
}注意事项
1. 检查内存分配
c
#include <stdio.h>
#include <stdlib.h>
void good_practice() {
int* ptr = malloc(100 * sizeof(int));
if (ptr == NULL) {
printf("内存分配失败\n");
return;
}
free(ptr);
}
void bad_practice() {
int* ptr = malloc(100 * sizeof(int));
free(ptr);
}2. 释放内存
c
#include <stdio.h>
#include <stdlib.h>
void good_practice() {
int* ptr = malloc(100 * sizeof(int));
if (ptr != NULL) {
free(ptr);
}
}
void bad_practice() {
int* ptr = malloc(100 * sizeof(int));
}3. 避免内存泄漏
c
#include <stdio.h>
#include <stdlib.h>
void good_practice() {
int* ptr = malloc(100 * sizeof(int));
if (ptr != NULL) {
free(ptr);
}
}
void bad_practice() {
int* ptr = malloc(100 * sizeof(int));
ptr = malloc(200 * sizeof(int));
free(ptr);
}4. 初始化随机数种子
c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void good_practice() {
srand(time(NULL));
printf("随机数: %d\n", rand() % 100);
}
void bad_practice() {
printf("随机数: %d\n", rand() % 100);
}总结
<stdlib.h> 提供的通用工具函数是 C 语言编程的基础:
- 功能全面 - 涵盖内存管理、进程控制、类型转换等
- 易于使用 - 提供了简单直观的接口
- 广泛应用 - 几乎所有 C 程序都会使用
记住:
- 始终检查内存分配是否成功
- 记得释放分配的内存
- 避免内存泄漏
- 使用 srand() 初始化随机数种子
- 检查函数的返回值