Skip to content

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 语言编程的基础:

  1. 功能全面 - 涵盖内存管理、进程控制、类型转换等
  2. 易于使用 - 提供了简单直观的接口
  3. 广泛应用 - 几乎所有 C 程序都会使用

记住:

  • 始终检查内存分配是否成功
  • 记得释放分配的内存
  • 避免内存泄漏
  • 使用 srand() 初始化随机数种子
  • 检查函数的返回值