C 标准库速览

C 的强大很大程度上来自它的标准库——一组随编译器附带的、覆盖常见任务的函数。本篇是 C 标准库的速览地图,帮你建立"遇到什么问题用什么库"的索引。每个库前面章节基本都细讲过,这里做个汇总,方便日后查阅。

一、stdio.h — 标准输入输出

最常用的库,提供屏幕打印、键盘读取、文件 I/O。前面语法篇文件 I/O 篇都详细讲过:

#include <stdio.h>

// stdio.h - 标准输入输出
int main(void) {
    // 输出
    printf("格式化输出\n");
    fprintf(stderr, "错误输出\n");
    putchar('A');
    fputs("字符串\n", stdout);

    // 输入
    int n;
    scanf("%d", &n);
    char line[100];
    fgets(line, sizeof(line), stdin);

    // 文件 I/O
    FILE *fp = fopen("x.txt", "r");
    fclose(fp);

    // 其他
    sprintf(line, "n=%d", n);          // 写入字符串
    sscanf(line, "n=%d", &n);          // 从字符串解析
    remove("临时文件.txt");              // 删除文件
    rename("旧名.txt", "新名.txt");      // 重命名
    return 0;
}

核心函数:printf/scanf(屏幕)、fopen/fread/fclose(文件)、sprintf/sscanf(字符串解析)。三个标准流:stdin(键盘)、stdout(屏幕)、stderr(错误)。

二、stdlib.h — 通用工具

杂七杂八的实用函数都在这里:内存管理、随机数、排序、字符串转数字、程序控制。

#include <stdio.h>
#include <stdlib.h>      // 通用工具库

int compare(const void *a, const void *b) {
    return *(int*)a - *(int*)b;       // 升序比较函数
}

int main(void) {
    // 1. 内存管理(详见 memory 篇)
    int *arr = malloc(10 * sizeof(int));
    free(arr);

    // 2. 随机数
    srand(time(NULL));                // 播种子(只调一次)
    int r = rand() % 100;             // 0~99 的随机数
    printf("随机: %d\n", r);

    // 3. qsort:快速排序(对任意类型数组)
    int nums[] = {5, 2, 8, 1, 9, 3};
    int n = sizeof(nums) / sizeof(nums[0]);
    qsort(nums, n, sizeof(int), compare);
    // nums 现在是 {1, 2, 3, 5, 8, 9}

    // 4. 字符串转数字
    int i = atoi("42");               // 字符串转 int
    long l = atol("1000000");         // 转 long
    double d = atof("3.14");          // 转 double
    // 推荐用更安全的 strtol/strtod(能检测错误)
    char *end;
    long val = strtol("123abc", &end, 10);
    printf("val=%ld, 剩余=%s\n", val, end);  // val=123, 剩余=abc

    // 5. 程序控制
    // exit(0);     // 立即退出程序(0 正常, 非0 错误)
    // abort();     // 异常终止(产生 core dump)
    // atexit(fn);  // 注册退出时调用的函数

    // 6. 绝对值
    printf("%d\n", abs(-5));          // int 绝对值
    return 0;
}

重点掌握:

三、string.h — 字符串与内存

前面字符串篇细讲过。除了字符串函数,还有几个对任意内存操作的函数:

#include <stdio.h>
#include <string.h>     // 字符串函数(详见 strings 篇)

int main(void) {
    // 1. 长度
    size_t len = strlen("hello");     // 5

    // 2. 复制
    char buf[20];
    strcpy(buf, "hello");
    strncpy(buf, "hello", sizeof(buf) - 1);

    // 3. 拼接
    strcat(buf, " world");
    strncat(buf, "!", 1);

    // 4. 比较
    if (strcmp("a", "b") < 0) printf("a < b\n");
    if (strncmp("abc", "abd", 2) == 0) printf("前2个相同\n");

    // 5. 查找
    char *p = strchr("hello", 'l');   // 找字符
    char *sub = strstr("hello world", "world");   // 找子串

    // 6. 内存操作(对任意数据,不止字符串)
    int a[5] = {1, 2, 3, 4, 5};
    int b[5];
    memcpy(b, a, sizeof(a));          // 内存拷贝
    memset(b, 0, sizeof(b));          // 清零

    // 7. 分割
    char str[] = "a,b,c,d";
    char *tok = strtok(str, ",");
    while (tok != NULL) {
        printf("%s\n", tok);
        tok = strtok(NULL, ",");
    }
    return 0;
}

关键函数:

四、math.h — 数学函数

提供数学运算函数。注意编译时要加 -lm 链接数学库(gcc hello.c -lm):

#include <stdio.h>
#include <math.h>       // 数学函数(编译时要加 -lm 链接库)
#include <stdlib.h>

int main(void) {
    // 基本运算
    printf("%.2f\n", pow(2, 10));      // 1024.00 (2的10次方)
    printf("%.2f\n", sqrt(16));        // 4.00    (平方根)
    printf("%.2f\n", cbrt(27));        // 3.00    (立方根)
    printf("%.2f\n", fabs(-3.14));     // 3.14    (绝对值)

    // 取整
    printf("%.2f\n", ceil(3.2));       // 4.00    (向上取整)
    printf("%.2f\n", floor(3.8));      // 3.00    (向下取整)
    printf("%ld\n", lround(3.6));      // 4       (四舍五入)

    // 对数与指数
    printf("%.2f\n", log(2.71828));    // 1.00    (自然对数)
    printf("%.2f\n", log10(1000));     // 3.00    (常用对数)
    printf("%.2f\n", exp(1));          // 2.72    (e的1次方)

    // 三角函数(参数是弧度,不是度)
    printf("%.4f\n", sin(3.14159 / 2));   // 1.0000
    printf("%.4f\n", cos(0));              // 1.0000
    printf("%.4f\n", tan(0.785));          // 接近 1(45度)

    // 常量
    printf("PI = %.6f\n", M_PI);        // 3.141593 (GNU 扩展)
    printf("E  = %.6f\n", M_E);         // 2.718282

    // 浮点特殊值
    printf("%f\n", INFINITY);           // inf
    printf("%f\n", NAN);                // nan
    return 0;
}

分类记忆:

五、time.h — 时间日期

提供时间获取、格式化、计时功能:

#include <stdio.h>
#include <time.h>       // 时间函数

int main(void) {
    // 1. 时间戳(Unix 时间,从 1970-01-01 起的秒数)
    time_t now = time(NULL);
    printf("当前时间戳: %ld\n", now);

    // 2. 转成可读格式
    char *s = ctime(&now);
    printf("ctime: %s", s);     // 如:Tue Aug  5 15:30:00 2025

    // 3. 拆解成结构体
    struct tm *local = localtime(&now);
    printf("%d-%02d-%02d %02d:%02d:%02d\n",
        local->tm_year + 1900,    // 年份从 1900 开始
        local->tm_mon + 1,        // 月份从 0 开始
        local->tm_mday,
        local->tm_hour, local->tm_min, local->tm_sec);

    // 4. 格式化输出
    char buf[100];
    strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", local);
    printf("格式化: %s\n", buf);

    // 5. 计时(测代码运行时间)
    clock_t start = clock();
    // ... 一些操作 ...
    for (volatile int i = 0; i < 1000000; i++);
    clock_t end = clock();
    double elapsed = (double)(end - start) / CLOCKS_PER_SEC;
    printf("耗时: %.3f 秒\n", elapsed);

    return 0;
}

常见用途:

六、其他常用头文件

#include <stdio.h>
#include <ctype.h>      // 字符判断
#include <assert.h>     // 断言
#include <stdbool.h>    // bool 类型(C99)
#include <stdint.h>     // 固定宽度整数(C99)
#include <errno.h>      // 错误码

int main(void) {
    // ctype.h:字符处理
    printf("%d\n", isdigit('5'));       // 非0(真)
    printf("%d\n", isalpha('A'));       // 非0(真)
    printf("%c\n", toupper('a'));       // A
    printf("%c\n", tolower('Z'));       // z

    // assert.h:断言(调试利器)
    int x = 10;
    assert(x > 0);              // 条件为假时程序终止并打印信息
    // NDEBUG 宏定义时 assert 失效(#define NDEBUG)
    // 发布版本常用 -DNDEBUG 关闭所有 assert

    // stdbool.h:布尔类型(C99)
    bool ok = true;
    if (!ok) printf("失败\n");

    // stdint.h:固定宽度整数(C99)
    int32_t i32 = 100;          // 保证 32 位
    uint64_t u64 = 1000ULL;     // 保证 64 位无符号
    size_t sz = sizeof(i32);    // 内存大小类型

    // limits.h / float.h:类型范围
    // INT_MAX, INT_MIN, UINT_MAX, DBL_MAX ...

    return 0;
}

七、几个进阶库(知道存在即可)

八、查文档的方法

C 标准库函数很多,没人能全记住。学会查文档:

九、C 标准库 vs 第三方库

C 标准库很小——没有网络、没有正则(直到 C11 加了 stdregex,但几乎没人用)、没有 JSON、没有 HTTP。这些需求都要第三方库:

这也是 C 的"哲学":标准库只提供最基础的积木,其他交给你选择。这种灵活也意味着 C 项目的依赖管理比 Node(pnpm)或 Python(pip)复杂——通常用 autotools/cmake/meson 等构建系统处理。

系列完结

恭喜你完成了 C 语言的 16 篇入门系列!现在你应该能:

下一步建议:读 K&R《C 程序设计语言》(经典)、读 Redis 源码(极优雅的 C)、学操作系统(CSAPP)、或转 C++ 学面向对象和 STL。无论选哪条路,C 给你打的地基都会让你受益终身。

← 上一篇 C 文件 I/O

返回 C 语言教程目录

✈️💬