欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > C 标准库总结

C 标准库总结

2024/12/22 16:40:54 来源:https://blog.csdn.net/pumpkin84514/article/details/144318954  浏览:    关键词:C 标准库总结

C 标准库总览表

下表按功能类别列出了常用头文件。您可根据需求先在表中找到相应功能与头文件,再查看后续的示例与注意事项。

功能类别头文件主要功能/特性常用函数例子
标准输入输出(I/O)<stdio.h>标准输入输出、文件操作printf(), scanf(), fopen(), fgets(), fprintf()
内存与工具函数<stdlib.h>内存分配、程序退出、转换函数、随机数malloc(), free(), exit(), atoi(), strtol(), rand()
字符串与内存操作<string.h>字符串处理、内存块操作strlen(), strcpy(), strncpy(), strcat(), memcmp()
字符分类与转换<ctype.h>字符分类检查与大小写转换isalpha(), isdigit(), isspace(), toupper(), tolower()
时间与日期<time.h>获取系统时间、格式化日期时间、计时time(), localtime(), gmtime(), strftime(), clock()
数学函数<math.h>基本数学运算与函数sin(), cos(), tan(), log(), sqrt(), pow()
错误处理与断言<errno.h>, <assert.h>错误码 errno 与断言调试辅助assert(), perror(), strerror()
类型限制与定长整数<limits.h>, <float.h>, <stdint.h>, <inttypes.h>基本类型范围、浮点限制、定长整数类型及格式化宏INT_MAX, DBL_MAX, int32_t, PRId32
布尔类型支持<stdbool.h>布尔类型 bool, true, false(无函数,仅宏与类型定义)
本地化与宽字符支持<locale.h>, <wchar.h>, <wctype.h>, <uchar.h>地域化设置、宽字符与Unicode支持setlocale(), wprintf(), iswalpha()
信号与非局部跳转<signal.h>, <setjmp.h>信号处理与非局部跳转signal(), raise(), setjmp(), longjmp()
可变参数处理<stdarg.h>可变参数函数支持(如实现printf风格函数)va_list, va_start(), va_arg(), va_end()
原子与多线程(C11)<stdatomic.h>, <threads.h>原子操作、多线程API(C11引入)atomic_store(), thrd_create(), thrd_join(), mtx_lock()
对齐与不可返回函数(C11)<stdalign.h>, <stdnoreturn.h>内存对齐与不可返回函数说明alignof(), _Noreturn关键字
复数与特殊数学(C99)<complex.h>, <fenv.h>, <tgmath.h>复数操作、浮点环境控制、类型泛型数学宏cabs(), fesetround(), 使用tgm宏自动选择数学函数版本

深入示例与注意事项

1. 标准输入输出(<stdio.h>)

典型场景:文件读写、标准输入输出、格式化打印。

示例:将文本写入文件并读出

#include <stdio.h>
#include <stdlib.h>int main() {FILE *fp = fopen("data.txt", "w");if (!fp) {perror("Open for writing failed");return EXIT_FAILURE;}fprintf(fp, "Hello, world!\n");fclose(fp);fp = fopen("data.txt", "r");if (!fp) {perror("Open for reading failed");return EXIT_FAILURE;}char buf[100];if (fgets(buf, sizeof(buf), fp)) {printf("Read: %s", buf);}fclose(fp);return 0;
}

注意事项

  • 使用 fgets() 而非 gets() 来避免缓冲区溢出。
  • 打开文件后需记得 fclose()
  • 格式化输出时,确保格式说明符匹配传入参数类型。

2. 内存分配与通用工具(<stdlib.h>)

典型场景:动态分配数组,转换字符串为数值,生成随机数。

示例:动态分配与随机数

#include <stdio.h>
#include <stdlib.h>
#include <time.h>int main() {int *arr = malloc(5 * sizeof(int));if (!arr) {fprintf(stderr, "malloc failed\n");return EXIT_FAILURE;}for (int i = 0; i < 5; i++) arr[i] = i*i;srand((unsigned)time(NULL));int r = rand() % 100;printf("Random: %d\n", r);free(arr);return 0;
}

注意事项

  • 每次 malloc()/calloc() 分配的内存必须 free()
  • 对转换类函数如 atoi(),若需严谨错误检测,用 strtol()替代。

3. 字符串与内存(<string.h>)

典型场景:字符串复制、拼接、比较,内存块拷贝清零。

示例:安全字符串拷贝与搜索

#include <stdio.h>
#include <string.h>int main() {char src[] = "Hello C";char dest[20];// 使用strncpy以避免溢出,并手动添加'\0'strncpy(dest, src, sizeof(dest)-1);dest[sizeof(dest)-1] = '\0';printf("Copied: %s\n", dest);char *pos = strstr(dest, "C");if (pos) {printf("Found 'C' at index %ld\n", pos - dest);}return 0;
}

注意事项

  • 始终确保目标缓冲区足够大,并在需要时手动添加终止符'\0'
  • 对二进制数据用 memcpy()/memmove() 而非 strcpy()

4. 字符类型检查(<ctype.h>)

典型场景:判断字符是否字母、数字,转换大小写。

示例

#include <stdio.h>
#include <ctype.h>int main() {char c = '9';if (isdigit((unsigned char)c)) {printf("%c is a digit\n", c);}c = 'a';printf("Uppercase: %c\n", toupper((unsigned char)c));return 0;
}

注意事项

  • char转为unsigned char传给isxxx()函数,以避免负值出现未定义行为。

5. 时间与日期(<time.h>)

典型场景:获取当前时间、格式化输出、统计运行时间。

示例:打印当前时间

#include <stdio.h>
#include <time.h>int main() {time_t now = time(NULL);struct tm *lt = localtime(&now);char buf[100];strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", lt);printf("Local time: %s\n", buf);return 0;
}

注意事项

  • localtime()返回静态存储区指针,下次调用会覆盖,使用前若需保存结果请复制数据。
  • C标准不提供复杂日期处理,需要自行处理闰年等逻辑或使用第三方库。

6. 数学函数(<math.h>)

典型场景:计算三角函数、对数、指数、开方、幂。

示例:计算圆面积

#include <stdio.h>
#include <math.h>int main() {double radius = 2.0;double area = M_PI * pow(radius, 2);printf("Area: %f\n", area);return 0;
}

注意事项

  • 确保定义 _USE_MATH_DEFINES(在某些编译器中)或自己定义PI来使用M_PI
  • 浮点精度有限,比较时需考虑误差。

7. 错误处理与断言(<errno.h>, <assert.h>)

典型场景:检查函数调用失败原因,调试时检查不变条件。

示例

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <assert.h>int main() {FILE *fp = fopen("nonexist.txt", "r");if (!fp) {fprintf(stderr, "Error: %s\n", strerror(errno));}int x = 10;assert(x == 10); // 若不满足则程序中断return 0;
}

注意事项

  • 发布版本可#define NDEBUG禁用assert()
  • errno只在特定函数失败时有意义。

8. 类型限制与定长整数

典型场景:确定整数范围、使用定长类型确保跨平台一致性。

示例

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <limits.h>int main() {printf("INT_MAX = %d\n", INT_MAX);int32_t val = 12345;printf("val = %" PRId32 "\n", val);return 0;
}

注意事项

  • 使用<stdint.h>确保整数位宽固定。
  • <inttypes.h>提供打印定长整数的安全格式化宏。

9. 布尔与本地化支持(<stdbool.h>, <locale.h>等)

典型场景:使用布尔类型代码更清晰,或设置地域化格式。

示例(布尔类型):

#include <stdio.h>
#include <stdbool.h>int main() {bool flag = true;if (flag) {printf("Flag is true\n");}return 0;
}

示例(locale):

#include <stdio.h>
#include <locale.h>int main() {setlocale(LC_ALL, "");// 输出可能在特定语言环境下启用特殊格式printf("%'.2f\n", 1234567.89); return 0;
}

注意事项

  • 地域化支持依赖系统环境,setlocale()设置地区后相关函数的行为(如数字分组符)才会改变。
  • <wchar.h><wctype.h> 用于宽字符处理,多语言字符需使用Unicode知识。

10. 信号处理与非局部跳转(<signal.h>, <setjmp.h>)

典型场景:捕捉Ctrl+C中断或在深层函数中发生错误时跳回上层函数。

示例(signal):

#include <stdio.h>
#include <signal.h>void handler(int sig) {printf("Caught signal %d\n", sig);
}int main() {signal(SIGINT, handler);while (1) {// 按 Ctrl+C 看效果}return 0;
}

注意事项

  • 信号处理函数中只能调用异步信号安全函数。
  • 非局部跳转setjmp()longjmp()不推荐滥用,影响代码可读性和可维护性。

11. 可变参数(<stdarg.h>)

典型场景:实现自定义变参函数,比如日志函数。

示例

#include <stdio.h>
#include <stdarg.h>void print_numbers(int count, ...) {va_list args;va_start(args, count);for (int i = 0; i < count; i++) {int num = va_arg(args, int);printf("%d ", num);}va_end(args);printf("\n");
}int main() {print_numbers(3, 10, 20, 30);return 0;
}

注意事项

  • 需约定参数类型顺序,无类型安全检查。
  • 如果能固定参数数量或使用变参安全框架更好。

12. 原子与多线程(C11)(<stdatomic.h>, <threads.h>)

典型场景:使用标准原子操作、跨平台基础多线程。

示例(简单线程):

#include <stdio.h>
#include <threads.h>int func(void *arg) {printf("In thread: %d\n", *(int*)arg);return 0;
}int main() {int val = 42;thrd_t t;if (thrd_create(&t, func, &val) == thrd_success) {thrd_join(t, NULL);}return 0;
}

注意事项

  • 功能不如Java Thread和并发库丰富。仅适合简单多线程场景。
  • <stdatomic.h>提供类似C++原子操作功能,保证数据访问的原子性。

13. 对齐与不可返回函数(C11)

典型场景:特殊场景下需指定类型对齐或标识函数不返回。

示例

#include <stdalign.h>
#include <stdnoreturn.h>
#include <stdio.h>
#include <stdlib.h>_Noreturn void fail(const char *msg) {fprintf(stderr, "%s\n", msg);exit(EXIT_FAILURE);
}int main() {struct {alignas(16) int x; } s;s.x = 10;// fail("This function never returns");return 0;
}

注意事项

  • 大部分日常开发无需显式使用对齐特性。
  • _Noreturn函数不能返回,否则未定义行为。

14. 复数与特殊数学(C99)(<complex.h>, <fenv.h>, <tgmath.h>)

典型场景:科学计算,处理复数或控制浮点环境(如舍入方式)。

示例(复数):

#include <stdio.h>
#include <complex.h>
#include <math.h>int main() {double complex z = 1.0 + 2.0*I;double r = cabs(z);printf("|1+2i| = %f\n", r);return 0;
}

注意事项

  • 日常通用开发中很少使用。
  • <fenv.h>控制浮点异常、舍入等,需要特殊场景。

总结与建议

  • 安全性与内存管理:C无自动内存管理和越界检查,需格外小心。
  • 错误处理:充分利用errnoperror(), 并在调试期使用assert()确保逻辑正确。
  • 国际化与复杂场景:对于多语言文本、时区、本地化格式等,高级功能需<locale.h><wchar.h><wctype.h>支持,且平台相关性更高。
  • 扩展与第三方库:C标准库提供基础功能,如需高级数据结构、网络编程、图形界面等,需第三方库或操作系统API。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com