←
常见坑汇总

💀 C/C++ 常见坑汇总(面试前必看)

共 38 条,按来源章节归类
没有匹配的坑点。

C 语言

  1. 4.3 <ctype.h> —— 字符判断与转换

    C参数是 int,char 为负数时可能出问题,建议转 unsigned char:

  2. 4.4 <string.h> —— C 风格字符串操作

    Cstrcpy、strcat 不检查缓冲区大小,易造成缓冲区溢出。

  3. 5.1 <math.h> —— 数学函数(C89 起)

    Cmath.h 所有三角函数参数是 弧度 radian ,非角度。deg → rad 公式:rad = deg * PI / 180。

  4. 15.1 <stdio.h> —— C 风格输入输出

    C1. scanf 的变量必须加 &(取地址),否则会崩溃。 2. 正确:scanf("%d", &x); 错误:scanf("%d", x); 2. printf 的格式化符和参数类型必须匹配,否则结果未定义。 3. 比如用 %d 输出 double 会得到乱码。 4. 3. sprintf 不检查缓冲区大小,容易溢出,推荐用 snprintf。 5. 4. fopen 可能失败(文件不存在、权限不足),一定要检查返回值 是否为 NULL,不要直接使用。 6. 5. 打

  5. 15.2 <errno.h> —— 错误码

    C1. 函数成功时通常不会把 errno 置0,所以调用前要手动 errno = 0。 2. errno 是全局变量,多线程中每个线程有自己的 errno(线程局部存储)。

  6. 15.5 <locale.h> —— 本地化

    C1. setlocale 会影响全局状态,多线程中要小心。 2. 可用的本地化名称因平台而异,Windows 和 Linux 不同。

  7. 15.7 <signal.h> —— 信号处理

    C1. 信号处理函数中只能做安全的操作(如设置标志位),不能调用 非异步信号安全的函数(如 printf、malloc),否则可能死锁。 2. 信号处理是全局的,会影响整个进程。 3. C++ 中信号处理和异常不能混用,信号处理函数中不能抛异常。 4. SIGKILL 和 SIGSTOP 不能被捕获或忽略。

  8. 15.8 <stdarg.h> —— 可变参数

    C1. 可变参数函数不知道参数的个数和类型,必须通过固定参数约定 (比如第一个参数传个数,或用特殊结束标记如 NULL)。 2. va_arg 的类型必须和实际参数类型匹配,否则未定义行为。 4. 省略号 ... 必须是最后一个参数。

  9. 15.9 <stddef.h> —— 常用类型定义

    C1. size_t 是无符号类型,和 int 比较时要小心(比如 size_t i; i >= 0 永远为真)。 2. C++11 后用 nullptr 替代 NULL,类型更安全。 3. offsetof 只能用于标准布局类型(standard-layout type)。 4. 这个头文件通常被其他头文件自动包含,很少需要手动 #include。

  10. 15.10 <fenv.h> —— 浮点环境控制(fenv.h,C99)

    C1. 浮点异常不是 C++ 异常,不会被 try/catch 捕获,只是设置标志位。 2. 修改舍入模式会影响整个线程的所有浮点运算,用完记得恢复。 3. 某些编译器需要开启特定选项才能完整支持(如 #pragma STDC FENV_ACCESS ON)。 4. 初学者一般用不到,了解有这个东西就行。

  11. 15.11 <inttypes.h> —— 定宽整数格式化(inttypes.h,C99)

    C1. PRId32 等宏展开后是字符串字面量,要和前面的 "%" 写在一起,中间不能有空格。 3. 这个头文件通常和 一起使用。

  12. 15.12 <stdint.h> —— 固定宽度整数(stdint.h,C99)

    C1. 不是所有平台都支持 int8_t 等精确宽度类型(比如某些DSP没有8位类型), 但主流平台(x86、ARM)都支持。 2. 用 printf 输出这些类型需要配合 的 PRId32 等宏。 3. C++ 中用 std::cout 输出不需要特殊处理。

  13. 15.13 <wchar.h> —— 宽字符工具

    C1. wchar_t 的大小因平台而异(Windows 上是2字节,Linux 上通常是4字节)。 3. 宽字符和普通 char 字符串不能直接混用。

  14. 15.14 <wctype.h> —— 宽字符判断

    C1. 参数是 wint_t 类型(通常是 wchar_t 的无符号版本),传 wchar_t 即可。 2. 这些函数的行为受当前本地化(locale)影响。

  15. 15.15 <uchar.h> —— Unicode 字符转换(uchar.h,C11)

    C1. 这些函数在不同编译器上的支持程度不同,MSVC 早期版本支持不完善。 2. C++ 中还有 头文件提供更面向对象的编码转换(但 C++17 已弃用)。 3. char16_t 和 char32_t 是 C++11 内置类型,不需要 也能用。 4. 转换失败时返回 (size_t)-1,并设置 errno。

  16. 15.16 <iso646.h> —— 运算符别名宏

    C1. C++ 中 and、or、not 等是关键字,不需要包含 。 2. 这个头文件在 C++17 中已弃用,C++20 中已移除。 3. 纯 C 语言中必须包含 才能使用这些宏。

  17. 15.18 <stdbool.h> —— 布尔类型(stdbool.h,C99)

    C1. C++ 中 bool、true、false 是关键字,不需要包含 。 2. 在 C++17 中已弃用,C++20 中已移除。 3. C 语言中 _Bool 是内置类型,stdbool.h 只是提供 bool/true/false 的宏定义。 4. C 语言中 bool 变量只能存 0 或 1,赋值非 0 值会被转为 1。

  18. 15.19 <tgmath.h> —— 泛型数学宏(tgmath.h,C99)

    C1. C++ 中通过函数重载自动实现类型通用,不需要 。 2. 在 C++17 中已弃用,C++20 中已移除。 3. tgmath.h 的宏是通过 C11 的 _Generic 实现的(C99 用编译器内置支持)。

  19. 15.20 <stdalign.h> —— 对齐控制宏(stdalign.h,C11)

    C1. C++11 中 alignas 和 alignof 是关键字,不需要包含 。 2. 在 C++17 中已弃用,C++20 中已移除。 3. alignas 的值必须是 2 的幂(1、2、4、8、16、32...)。 4. 过大的对齐可能浪费内存,一般用默认对齐即可。

  20. 15.21 <stdnoreturn.h> —— 不返回函数标记(stdnoreturn.h,C11)

    C1. C++11 中用 [[noreturn]] 属性,不需要包含 。 2. 在 C++17 中已弃用,C++20 中已移除。 3. 如果标记了 noreturn 的函数实际上返回了,行为是未定义的(可能崩溃)。 4. main 函数不能标记为 noreturn。

  21. 15.17 <complex.h> —— 复数运算(complex.h,C99)

    C📚 C 语言中用 _Complex 关键字定义复数,C++ 中用 std::complex 类。 📚 是 C++ 对 C 语言 的兼容版本。 ⚠️ 注意:下面的代码示例使用 C 语言语法(double complex、I 宏),因为 是 C 兼容头文件。

C++ 标准库

  1. 1.1 <iostream> —— 最基础的输入输出

    C++cin >> 遇到空格、回车、Tab 就会停下来,一次只读一个"词"。

  2. 1.2 <iomanip> —— 控制输出格式(排版美化)

    C++单独用 setprecision 控制"有效数字"总位数;配合 fixed 才控制"小数点后"位数。

  3. 1.3 <fstream> —— 读写文件

    C++默认会清空文件原有内容!想追加用 ios::app 模式。

  4. 2.1 <vector> —— 动态数组(最常用!)

    C++[] 越界访问是未定义行为,可能崩溃;at() 越界会抛异常,更安全。

  5. 2.10 <map> / <multimap> —— 有序字典

    C++[] 有副作用:key 不存在时会自动插入并设为默认值。

  6. 3.1 <algorithm> —— 通用算法

    C++remove 不会真正删除,只是把要保留的移到前面,返回新末尾迭代器。

  7. 4.1 <string> —— 字符串(最常用!)

    C++1. - 下标从 0 开始 - 中文 UTF-8 编码下一个字占3字节,size() 返回字节数不是字数 - 大量拼接用 += 或 append,不要用 s = s + "..."(会创建临时对象)

  8. 4.2 <string_view> —— 字符串视图(C++17)

    C++string_view 不拥有数据,原字符串销毁后它就失效(悬空)。

  9. 4.3 <cctype> —— 字符判断与转换

    C++参数是 int,char 为负数时可能出问题,建议转 unsigned char:

  10. 4.4 <cstring> —— C 风格字符串操作

    C++strcpy、strcat 不检查缓冲区大小,易造成缓冲区溢出。

  11. 5.1 <cmath> —— 数学函数

    C++三角函数用弧度不是角度。

  12. 5.2 <cstdlib> —— 随机数与通用工具

    C++rand() 随机性不太好,C++11 推荐用 。

  13. 8.1 <thread> —— 线程

    C++创建了线程必须 join 或 detach,否则程序崩溃。

  14. 8.3 <condition_variable> —— 条件变量

    C++wait 可能被虚假唤醒,一定要用带条件判断的版本(第二个参数)。

  15. 9.5 <variant> —— 类型安全联合体(C++17)

    C++get<类型>() 类型不对会抛 bad_variant_access。

  16. 11.1 <typeinfo> —— 运行时类型识别

    C++typeid 的 name() 返回字符串不标准,GCC 下可能是 "i"、"NSt7..." 等不太可读。

  17. 12.1 <regex> —— 正则表达式

    C++C++字符串中 \ 要写成 \\,或用原始字符串 R"(\d+)"

← 返回首页