文章目录
- [📋 本周学习地图](#📋 本周学习地图)
- [1️⃣ 整型家族:不是"都是整数"就一样](#1️⃣ 整型家族:不是"都是整数"就一样)
-
- [1.1 整型全景表](#1.1 整型全景表)
- [1.2 用 `<cstdint>` 固定宽度(工程必备)](#1.2 用
<cstdint>固定宽度(工程必备)) - [1.3 溢出:有符号是 UB,无符号是回绕](#1.3 溢出:有符号是 UB,无符号是回绕)
- [2️⃣ 浮点类型:精度是永恒的敌人](#2️⃣ 浮点类型:精度是永恒的敌人)
-
- [2.1 三种浮点对比](#2.1 三种浮点对比)
- [2.2 经典陷阱:`0.1 + 0.2 != 0.3`](#2.2 经典陷阱:
0.1 + 0.2 != 0.3) - [2.3 特殊值:inf 与 NaN](#2.3 特殊值:inf 与 NaN)
- [3️⃣ 字符与编码:`char` 不只是"字符"](#3️⃣ 字符与编码:
char不只是"字符") -
- [3.1 四种字符类型](#3.1 四种字符类型)
- [3.2 `char` 的符号性陷阱](#3.2
char的符号性陷阱) - [3.3 UTF-8 字面量(C++20)](#3.3 UTF-8 字面量(C++20))
- [4️⃣ `auto` 类型推导:方便但有坑](#4️⃣
auto类型推导:方便但有坑) -
- [4.1 基本用法](#4.1 基本用法)
- [4.2 三个必须知道的推导规则](#4.2 三个必须知道的推导规则)
- [5️⃣ 运算符与优先级:括号永远不嫌多](#5️⃣ 运算符与优先级:括号永远不嫌多)
-
- [5.1 优先级速查(从高到低,只列常用)](#5.1 优先级速查(从高到低,只列常用))
- [5.2 经典优先级坑](#5.2 经典优先级坑)
- [5.3 短路求值:`&&` 和 `||` 的顺序很重要](#5.3 短路求值:
&&和||的顺序很重要)
- [6️⃣ 类型转换:隐式是坑,显式是德](#6️⃣ 类型转换:隐式是坑,显式是德)
-
- [6.1 隐式转换的四个危险场景](#6.1 隐式转换的四个危险场景)
- [6.2 四种显式转换对比](#6.2 四种显式转换对比)
- [6.3 推荐写法:`static_cast` + `size_t` 字面量](#6.3 推荐写法:
static_cast+size_t字面量)
- [7️⃣ 本周高频面试题(5 道)](#7️⃣ 本周高频面试题(5 道))
- [8️⃣ 本周项目验收:类型安全计算器](#8️⃣ 本周项目验收:类型安全计算器)
- [9️⃣ 本周避坑速查表(贴墙版)](#9️⃣ 本周避坑速查表(贴墙版))
📚 本文是「C++ 全栈开发 30 周课程」阶段一第 2 周的详细讲义。本周目标:彻底搞懂 C++ 的类型系统、运算符规则和类型转换,写出不会因为"类型"而出 Bug 的代码。
📋 本周学习地图
#mermaid-svg-gRmMVZvZaepcGMP3{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gRmMVZvZaepcGMP3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gRmMVZvZaepcGMP3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gRmMVZvZaepcGMP3 .error-icon{fill:#552222;}#mermaid-svg-gRmMVZvZaepcGMP3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gRmMVZvZaepcGMP3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gRmMVZvZaepcGMP3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gRmMVZvZaepcGMP3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gRmMVZvZaepcGMP3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gRmMVZvZaepcGMP3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gRmMVZvZaepcGMP3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gRmMVZvZaepcGMP3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gRmMVZvZaepcGMP3 .marker.cross{stroke:#333333;}#mermaid-svg-gRmMVZvZaepcGMP3 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gRmMVZvZaepcGMP3 p{margin:0;}#mermaid-svg-gRmMVZvZaepcGMP3 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-gRmMVZvZaepcGMP3 .cluster-label text{fill:#333;}#mermaid-svg-gRmMVZvZaepcGMP3 .cluster-label span{color:#333;}#mermaid-svg-gRmMVZvZaepcGMP3 .cluster-label span p{background-color:transparent;}#mermaid-svg-gRmMVZvZaepcGMP3 .label text,#mermaid-svg-gRmMVZvZaepcGMP3 span{fill:#333;color:#333;}#mermaid-svg-gRmMVZvZaepcGMP3 .node rect,#mermaid-svg-gRmMVZvZaepcGMP3 .node circle,#mermaid-svg-gRmMVZvZaepcGMP3 .node ellipse,#mermaid-svg-gRmMVZvZaepcGMP3 .node polygon,#mermaid-svg-gRmMVZvZaepcGMP3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gRmMVZvZaepcGMP3 .rough-node .label text,#mermaid-svg-gRmMVZvZaepcGMP3 .node .label text,#mermaid-svg-gRmMVZvZaepcGMP3 .image-shape .label,#mermaid-svg-gRmMVZvZaepcGMP3 .icon-shape .label{text-anchor:middle;}#mermaid-svg-gRmMVZvZaepcGMP3 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-gRmMVZvZaepcGMP3 .rough-node .label,#mermaid-svg-gRmMVZvZaepcGMP3 .node .label,#mermaid-svg-gRmMVZvZaepcGMP3 .image-shape .label,#mermaid-svg-gRmMVZvZaepcGMP3 .icon-shape .label{text-align:center;}#mermaid-svg-gRmMVZvZaepcGMP3 .node.clickable{cursor:pointer;}#mermaid-svg-gRmMVZvZaepcGMP3 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-gRmMVZvZaepcGMP3 .arrowheadPath{fill:#333333;}#mermaid-svg-gRmMVZvZaepcGMP3 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gRmMVZvZaepcGMP3 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gRmMVZvZaepcGMP3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gRmMVZvZaepcGMP3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-gRmMVZvZaepcGMP3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gRmMVZvZaepcGMP3 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-gRmMVZvZaepcGMP3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gRmMVZvZaepcGMP3 .cluster text{fill:#333;}#mermaid-svg-gRmMVZvZaepcGMP3 .cluster span{color:#333;}#mermaid-svg-gRmMVZvZaepcGMP3 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gRmMVZvZaepcGMP3 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-gRmMVZvZaepcGMP3 rect.text{fill:none;stroke-width:0;}#mermaid-svg-gRmMVZvZaepcGMP3 .icon-shape,#mermaid-svg-gRmMVZvZaepcGMP3 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gRmMVZvZaepcGMP3 .icon-shape p,#mermaid-svg-gRmMVZvZaepcGMP3 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-gRmMVZvZaepcGMP3 .icon-shape .label rect,#mermaid-svg-gRmMVZvZaepcGMP3 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gRmMVZvZaepcGMP3 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-gRmMVZvZaepcGMP3 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-gRmMVZvZaepcGMP3 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 第2周 · 数据类型与表达式
- 整型家族
- 浮点类型
- 字符与编码
- auto 类型推导
- 运算符与优先级
- 类型转换
避坑:溢出 / 符号比较
避坑:精度丢失 / 浮点比较
避坑:char 有符号性
避坑:auto 推导出引用/const
避坑:优先级误判 / 短路求值
避坑:隐式窄化 / static_cast
本周项目:类型安全计算器
1️⃣ 整型家族:不是"都是整数"就一样
1.1 整型全景表
| 类型 | 最小保证位数 | 常见平台位数(x86_64) | 典型范围 | 建议用途 |
|---|---|---|---|---|
short |
16 | 16 | -32768 ~ 32767 | 极少用,省内存时考虑 |
int |
16 | 32 | -21亿 ~ 21亿 | 默认整数类型 |
long |
32 | 32(Windows)/ 64(Linux) | 视平台 | 跨平台慎用 |
long long |
64 | 64 | ±9.2×10¹⁸ | 需要 64 位时用 |
unsigned 系列 |
同上 | 同上 | 0 ~ 2ⁿ-1 | 位运算、计数、size_t |
⚠️ 关键认知 :C++ 标准只规定最小位数 ,不规定具体大小。
long在 Windows 是 32 位,在 Linux 是 64 位------这就是跨平台 Bug 的经典来源。
1.2 用 <cstdint> 固定宽度(工程必备)
cpp
#include <cstdint>
#include <iostream>
int8_t a = -128; // 精确 8 位有符号
uint8_t b = 255; // 精确 8 位无符号
int32_t c = -100000; // 精确 32 位
uint64_t d = 0xFFFFFFFFFFFFFFFFULL;
int main()
{
// 输出类型大小(字节)
std::cout << sizeof(int32_t) << "\n"; // 4
std::cout << sizeof(uint64_t) << "\n"; // 8
return 0;
}
💡 工程原则 :涉及序列化、网络协议、文件格式、硬件寄存器时,一律用
<cstdint>的固定宽度类型 ,不要用int/long。
1.3 溢出:有符号是 UB,无符号是回绕
cpp
#include <iostream>
#include <climits>
int main() {
int maxInt = INT_MAX; // 2147483647
// maxInt + 1 是未定义行为(UB),不同编译器结果可能不同
std::cout << maxInt + 1 << "\n"; // 可能输出 -2147483648(回绕),也可能被优化掉
unsigned int u = 0;
u = u - 1; // 无符号回绕,结果是 4294967295
std::cout << u << "\n";
}
#mermaid-svg-1e6a7WPNGMljbFsg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1e6a7WPNGMljbFsg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1e6a7WPNGMljbFsg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1e6a7WPNGMljbFsg .error-icon{fill:#552222;}#mermaid-svg-1e6a7WPNGMljbFsg .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1e6a7WPNGMljbFsg .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1e6a7WPNGMljbFsg .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1e6a7WPNGMljbFsg .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1e6a7WPNGMljbFsg .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1e6a7WPNGMljbFsg .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1e6a7WPNGMljbFsg .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1e6a7WPNGMljbFsg .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1e6a7WPNGMljbFsg .marker.cross{stroke:#333333;}#mermaid-svg-1e6a7WPNGMljbFsg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1e6a7WPNGMljbFsg p{margin:0;}#mermaid-svg-1e6a7WPNGMljbFsg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-1e6a7WPNGMljbFsg .cluster-label text{fill:#333;}#mermaid-svg-1e6a7WPNGMljbFsg .cluster-label span{color:#333;}#mermaid-svg-1e6a7WPNGMljbFsg .cluster-label span p{background-color:transparent;}#mermaid-svg-1e6a7WPNGMljbFsg .label text,#mermaid-svg-1e6a7WPNGMljbFsg span{fill:#333;color:#333;}#mermaid-svg-1e6a7WPNGMljbFsg .node rect,#mermaid-svg-1e6a7WPNGMljbFsg .node circle,#mermaid-svg-1e6a7WPNGMljbFsg .node ellipse,#mermaid-svg-1e6a7WPNGMljbFsg .node polygon,#mermaid-svg-1e6a7WPNGMljbFsg .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-1e6a7WPNGMljbFsg .rough-node .label text,#mermaid-svg-1e6a7WPNGMljbFsg .node .label text,#mermaid-svg-1e6a7WPNGMljbFsg .image-shape .label,#mermaid-svg-1e6a7WPNGMljbFsg .icon-shape .label{text-anchor:middle;}#mermaid-svg-1e6a7WPNGMljbFsg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-1e6a7WPNGMljbFsg .rough-node .label,#mermaid-svg-1e6a7WPNGMljbFsg .node .label,#mermaid-svg-1e6a7WPNGMljbFsg .image-shape .label,#mermaid-svg-1e6a7WPNGMljbFsg .icon-shape .label{text-align:center;}#mermaid-svg-1e6a7WPNGMljbFsg .node.clickable{cursor:pointer;}#mermaid-svg-1e6a7WPNGMljbFsg .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-1e6a7WPNGMljbFsg .arrowheadPath{fill:#333333;}#mermaid-svg-1e6a7WPNGMljbFsg .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-1e6a7WPNGMljbFsg .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-1e6a7WPNGMljbFsg .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1e6a7WPNGMljbFsg .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-1e6a7WPNGMljbFsg .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1e6a7WPNGMljbFsg .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-1e6a7WPNGMljbFsg .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-1e6a7WPNGMljbFsg .cluster text{fill:#333;}#mermaid-svg-1e6a7WPNGMljbFsg .cluster span{color:#333;}#mermaid-svg-1e6a7WPNGMljbFsg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-1e6a7WPNGMljbFsg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-1e6a7WPNGMljbFsg rect.text{fill:none;stroke-width:0;}#mermaid-svg-1e6a7WPNGMljbFsg .icon-shape,#mermaid-svg-1e6a7WPNGMljbFsg .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1e6a7WPNGMljbFsg .icon-shape p,#mermaid-svg-1e6a7WPNGMljbFsg .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-1e6a7WPNGMljbFsg .icon-shape .label rect,#mermaid-svg-1e6a7WPNGMljbFsg .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1e6a7WPNGMljbFsg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-1e6a7WPNGMljbFsg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-1e6a7WPNGMljbFsg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} int 溢出
有符号:未定义行为 UB
编译器可任意处理
无符号:定义良好的回绕
模 2ⁿ 运算
❌ 必须避免
⚠️ 可用于哈希/位运算
但业务逻辑慎用
检测溢出 :编译加 -fsanitize=unsigned-integer-overflow,signed-integer-overflow(GCC/Clang),运行时报错定位。
2️⃣ 浮点类型:精度是永恒的敌人
2.1 三种浮点对比
| 类型 | 常见位数 | 有效十进制位 | 典型用途 |
|---|---|---|---|
float |
32 | ~7 位 | 图形、嵌入式、省内存 |
double |
64 | ~15-16 位 | 默认选择 |
long double |
80/128 | ≥15 位 | 高精度科学计算(平台差异大) |
2.2 经典陷阱:0.1 + 0.2 != 0.3
cpp
#include <iostream>
#include <cmath>
#include <iomanip>
int main() {
double a = 0.1, b = 0.2;
std::cout << std::setprecision(17) << (a + b) << "\n";
// 输出:0.30000000000000004
if (a + b == 0.3) {
std::cout << "相等\n"; // ❌ 不会执行
}
// ✅ 正确做法:用 epsilon 做近似比较
const double eps = 1e-9;
if (std::fabs((a + b) - 0.3) < eps) {
std::cout << "近似相等\n"; // ✅ 会执行
}
}
#mermaid-svg-xTNYYAs1a6rO7AJI{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xTNYYAs1a6rO7AJI .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xTNYYAs1a6rO7AJI .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xTNYYAs1a6rO7AJI .error-icon{fill:#552222;}#mermaid-svg-xTNYYAs1a6rO7AJI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xTNYYAs1a6rO7AJI .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xTNYYAs1a6rO7AJI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xTNYYAs1a6rO7AJI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xTNYYAs1a6rO7AJI .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xTNYYAs1a6rO7AJI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xTNYYAs1a6rO7AJI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xTNYYAs1a6rO7AJI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xTNYYAs1a6rO7AJI .marker.cross{stroke:#333333;}#mermaid-svg-xTNYYAs1a6rO7AJI svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xTNYYAs1a6rO7AJI p{margin:0;}#mermaid-svg-xTNYYAs1a6rO7AJI .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-xTNYYAs1a6rO7AJI .cluster-label text{fill:#333;}#mermaid-svg-xTNYYAs1a6rO7AJI .cluster-label span{color:#333;}#mermaid-svg-xTNYYAs1a6rO7AJI .cluster-label span p{background-color:transparent;}#mermaid-svg-xTNYYAs1a6rO7AJI .label text,#mermaid-svg-xTNYYAs1a6rO7AJI span{fill:#333;color:#333;}#mermaid-svg-xTNYYAs1a6rO7AJI .node rect,#mermaid-svg-xTNYYAs1a6rO7AJI .node circle,#mermaid-svg-xTNYYAs1a6rO7AJI .node ellipse,#mermaid-svg-xTNYYAs1a6rO7AJI .node polygon,#mermaid-svg-xTNYYAs1a6rO7AJI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xTNYYAs1a6rO7AJI .rough-node .label text,#mermaid-svg-xTNYYAs1a6rO7AJI .node .label text,#mermaid-svg-xTNYYAs1a6rO7AJI .image-shape .label,#mermaid-svg-xTNYYAs1a6rO7AJI .icon-shape .label{text-anchor:middle;}#mermaid-svg-xTNYYAs1a6rO7AJI .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-xTNYYAs1a6rO7AJI .rough-node .label,#mermaid-svg-xTNYYAs1a6rO7AJI .node .label,#mermaid-svg-xTNYYAs1a6rO7AJI .image-shape .label,#mermaid-svg-xTNYYAs1a6rO7AJI .icon-shape .label{text-align:center;}#mermaid-svg-xTNYYAs1a6rO7AJI .node.clickable{cursor:pointer;}#mermaid-svg-xTNYYAs1a6rO7AJI .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-xTNYYAs1a6rO7AJI .arrowheadPath{fill:#333333;}#mermaid-svg-xTNYYAs1a6rO7AJI .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-xTNYYAs1a6rO7AJI .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-xTNYYAs1a6rO7AJI .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xTNYYAs1a6rO7AJI .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xTNYYAs1a6rO7AJI .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xTNYYAs1a6rO7AJI .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-xTNYYAs1a6rO7AJI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-xTNYYAs1a6rO7AJI .cluster text{fill:#333;}#mermaid-svg-xTNYYAs1a6rO7AJI .cluster span{color:#333;}#mermaid-svg-xTNYYAs1a6rO7AJI div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-xTNYYAs1a6rO7AJI .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xTNYYAs1a6rO7AJI rect.text{fill:none;stroke-width:0;}#mermaid-svg-xTNYYAs1a6rO7AJI .icon-shape,#mermaid-svg-xTNYYAs1a6rO7AJI .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xTNYYAs1a6rO7AJI .icon-shape p,#mermaid-svg-xTNYYAs1a6rO7AJI .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-xTNYYAs1a6rO7AJI .icon-shape .label rect,#mermaid-svg-xTNYYAs1a6rO7AJI .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xTNYYAs1a6rO7AJI .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-xTNYYAs1a6rO7AJI .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-xTNYYAs1a6rO7AJI :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
是
否
比较两个浮点数
是否用 == ?
❌ 几乎永远为假
二进制无法精确表示 0.1
用 fabs(a-b) < eps ?
✅ 推荐做法
考虑 std::abs / 相对误差
或改用整数分(如金额用分)
💡 金额计算 :永远不要用
float/double存钱。用long long存"分",或专门的十进制库。
2.3 特殊值:inf 与 NaN
inf是计数出来无限大。
NaN是计数出来无意义,如:0.0/0.0。
cpp
#include <iostream>
int main() {
char c = 200; // ⚠️ char 是否有符号由实现决定
// 在 x86 GCC 上 char 默认有符号,200 溢出变成 -56
std::cout << (int)c << "\n"; // 可能是 -56 或 200
unsigned char uc = 200; // 明确无符号,安全
std::cout << (int)uc << "\n"; // 200
}
3️⃣ 字符与编码:char 不只是"字符"
3.1 四种字符类型
| 类型 | 大小 | 编码 | 引入标准 | 用途 |
|---|---|---|---|---|
char |
1 字节 | 实现定义(通常 ASCII/UTF-8 单元) | C++98 | 字节、ASCII 字符 |
char8_t |
1 字节 | UTF-8 码元 | C++20 | UTF-8 字符串 |
char16_t |
2 字节 | UTF-16 码元 | C++11 | Windows/Java 生态 |
char32_t |
4 字节 | UTF-32 码元 | C++11 | 完整 Unicode 码点 |
wchar_t |
2/4 字节 | 实现定义 | C++98 | Windows API 宽字符 |
3.2 char 的符号性陷阱
cpp
#include <iostream>
int main() {
char c = 200; // ⚠️ char 是否有符号由实现决定
// 在 x86 GCC 上 char 默认有符号,200 溢出变成 -56
std::cout << (int)c << "\n"; // 可能是 -56 或 200
unsigned char uc = 200; // 明确无符号,安全
std::cout << (int)uc << "\n"; // 200
}
💡 规则 :处理二进制数据/字节 时用
unsigned char或std::byte(C++17),不要用裸char。
3.3 UTF-8 字面量(C++20)
这个只有c++29可以使用,不然会报错哦。
cpp
#include <string>
#include <iostream>
int main() {
const char* s8 = u8"你好"; // C++20 起类型是 const char8_t*
std::u8string u8s = u8"你好, C++";
std::cout << u8s.size() << "\n"; // 字节数(UTF-8 中文 3 字节/字)
}
4️⃣ auto 类型推导:方便但有坑
4.1 基本用法
cpp
auto i = 42; // int
auto d = 3.14; // double(不是 float!)
auto f = 3.14f; // float
auto c = 'A'; // char
auto s = std::string("hi"); // std::string
4.2 三个必须知道的推导规则
规则 1:auto 会丢掉顶层 const 和引用
如果推导的指针本身const,auto自动推导将去除const。如果推导的指针指向的值是const,推导后的值仍然是const。
如果auto推导的值是引用,将丢掉引用。示例如下:
bash
#include <iostream>
int main() {
int x = 10;
int& ref = x; // ref 是 int&,和 x 是同一块内存
auto a = ref; // ❌ a 是 int(引用被丢掉),复制了 x 的值
a = 100; // 改 a 不影响 x
std::cout << "x = " << x << "\n"; // 10
std::cout << "a = " << a << "\n"; // 100
std::cout << "&x = " << &x << "\n";
std::cout << "&a = " << &a << "\n"; // 地址不同 → 证明是副本
}
规则 2:想要引用必须显式写 &
规则 3:auto 推导初始化列表会失败(C++17 起)
cpp
#include <vector>
#include <string>
int main() {
std::vector<int> v = {1, 2, 3};
const std::string name = "C++";
// 规则 1:auto 会丢掉顶层 const 和引用
auto a = name; // std::string(const 被丢弃,发生拷贝!)
const auto b = name; // const std::string
// 规则 2:想要引用必须显式写 &
auto& r = v[0]; // int&(可修改 v)
const auto& cr = v[0]; // const int&(只读,零拷贝)
// 规则 3:auto 推导初始化列表会失败(C++17 起)
// auto x = {1, 2, 3}; // std::initializer_list<int>
// auto y = {1, 2.0}; // ❌ 编译错误,类型不一致
}
#mermaid-svg-J7YCmmpu8cqmuwgJ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-J7YCmmpu8cqmuwgJ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-J7YCmmpu8cqmuwgJ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-J7YCmmpu8cqmuwgJ .error-icon{fill:#552222;}#mermaid-svg-J7YCmmpu8cqmuwgJ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-J7YCmmpu8cqmuwgJ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-J7YCmmpu8cqmuwgJ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-J7YCmmpu8cqmuwgJ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-J7YCmmpu8cqmuwgJ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-J7YCmmpu8cqmuwgJ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-J7YCmmpu8cqmuwgJ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-J7YCmmpu8cqmuwgJ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-J7YCmmpu8cqmuwgJ .marker.cross{stroke:#333333;}#mermaid-svg-J7YCmmpu8cqmuwgJ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-J7YCmmpu8cqmuwgJ p{margin:0;}#mermaid-svg-J7YCmmpu8cqmuwgJ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-J7YCmmpu8cqmuwgJ .cluster-label text{fill:#333;}#mermaid-svg-J7YCmmpu8cqmuwgJ .cluster-label span{color:#333;}#mermaid-svg-J7YCmmpu8cqmuwgJ .cluster-label span p{background-color:transparent;}#mermaid-svg-J7YCmmpu8cqmuwgJ .label text,#mermaid-svg-J7YCmmpu8cqmuwgJ span{fill:#333;color:#333;}#mermaid-svg-J7YCmmpu8cqmuwgJ .node rect,#mermaid-svg-J7YCmmpu8cqmuwgJ .node circle,#mermaid-svg-J7YCmmpu8cqmuwgJ .node ellipse,#mermaid-svg-J7YCmmpu8cqmuwgJ .node polygon,#mermaid-svg-J7YCmmpu8cqmuwgJ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-J7YCmmpu8cqmuwgJ .rough-node .label text,#mermaid-svg-J7YCmmpu8cqmuwgJ .node .label text,#mermaid-svg-J7YCmmpu8cqmuwgJ .image-shape .label,#mermaid-svg-J7YCmmpu8cqmuwgJ .icon-shape .label{text-anchor:middle;}#mermaid-svg-J7YCmmpu8cqmuwgJ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-J7YCmmpu8cqmuwgJ .rough-node .label,#mermaid-svg-J7YCmmpu8cqmuwgJ .node .label,#mermaid-svg-J7YCmmpu8cqmuwgJ .image-shape .label,#mermaid-svg-J7YCmmpu8cqmuwgJ .icon-shape .label{text-align:center;}#mermaid-svg-J7YCmmpu8cqmuwgJ .node.clickable{cursor:pointer;}#mermaid-svg-J7YCmmpu8cqmuwgJ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-J7YCmmpu8cqmuwgJ .arrowheadPath{fill:#333333;}#mermaid-svg-J7YCmmpu8cqmuwgJ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-J7YCmmpu8cqmuwgJ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-J7YCmmpu8cqmuwgJ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-J7YCmmpu8cqmuwgJ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-J7YCmmpu8cqmuwgJ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-J7YCmmpu8cqmuwgJ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-J7YCmmpu8cqmuwgJ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-J7YCmmpu8cqmuwgJ .cluster text{fill:#333;}#mermaid-svg-J7YCmmpu8cqmuwgJ .cluster span{color:#333;}#mermaid-svg-J7YCmmpu8cqmuwgJ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-J7YCmmpu8cqmuwgJ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-J7YCmmpu8cqmuwgJ rect.text{fill:none;stroke-width:0;}#mermaid-svg-J7YCmmpu8cqmuwgJ .icon-shape,#mermaid-svg-J7YCmmpu8cqmuwgJ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-J7YCmmpu8cqmuwgJ .icon-shape p,#mermaid-svg-J7YCmmpu8cqmuwgJ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-J7YCmmpu8cqmuwgJ .icon-shape .label rect,#mermaid-svg-J7YCmmpu8cqmuwgJ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-J7YCmmpu8cqmuwgJ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-J7YCmmpu8cqmuwgJ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-J7YCmmpu8cqmuwgJ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
auto 声明
初始化表达式是
const / 引用吗?
顶层 const / 引用被丢弃
除非显式写 const auto / auto&
按值推导,发生拷贝
✅ 大对象用 const auto& 零拷贝
⚠️ 小对象(int/double)按值即可
💡 实战口诀 :小对象用
auto,大对象用const auto&,要修改用auto&。
5️⃣ 运算符与优先级:括号永远不嫌多
5.1 优先级速查(从高到低,只列常用)
| 优先级 | 运算符 | 说明 |
|---|---|---|
| 1 | :: |
作用域 |
| 2 | () [] . -> |
调用、下标、成员 |
| 3 | ++ --(后缀) |
后置自增 |
| 4 | ++ --(前缀) ! ~ -(负号) *(解引用) &(取址) sizeof |
一元 |
| 5 | * / % |
乘除模 |
| 6 | + - |
加减 |
| 7 | << >> |
移位(注意:优先级低于加减!) |
| 8 | < <= > >= |
关系 |
| 9 | == != |
相等 |
| 10 | & |
按位与 |
| 11 | ^ |
按位异或 |
| 12 | ` | ` |
| 13 | && |
逻辑与(短路) |
| 14 | ` | |
| 15 | ?: |
三目 |
| 16 | = += -= 等 |
赋值(右结合) |
| 17 | , |
逗号 |
5.2 经典优先级坑
cpp
#include <iostream>
int main() {
int a = 1, b = 2, c = 3;
// 坑 1:位移优先级低于加减
int x = a + b << 2; // 等价于 a + (b << 2) = 9
int y = (a + b) << 2; // 显式括号,12
// 坑 2:& 低于 ==
int flags = 0b1010;
// if (flags & 0b1000 == 0) // ❌ 等价于 flags & (0b1000 == 0) = flags & 0 = 0
if ((flags & 0b1000) == 0) { // ✅
std::cout << "bit3 未设置\n";
}
// 坑 3:赋值右结合
int p, q, r;
p = q = r = 0; // 等价于 p = (q = (r = 0))
}
💡 工程规范 :任何混合了
<<、&、|、==、?:的表达式,一律加括号。 代码可读性 > 少打两个字符。
5.3 短路求值:&& 和 || 的顺序很重要
cpp
#include <iostream>
bool safeCheck(int* p) {
// ✅ 先判空再解引用,短路保证安全
if (p != nullptr && *p > 0) {
return true;
}
return false;
}
int main() {
int x = 5;
safeCheck(&x); // true
safeCheck(nullptr); // false,不会崩溃
}
#mermaid-svg-aTrbYg3TiSlYxJoD{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-aTrbYg3TiSlYxJoD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-aTrbYg3TiSlYxJoD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-aTrbYg3TiSlYxJoD .error-icon{fill:#552222;}#mermaid-svg-aTrbYg3TiSlYxJoD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-aTrbYg3TiSlYxJoD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-aTrbYg3TiSlYxJoD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-aTrbYg3TiSlYxJoD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-aTrbYg3TiSlYxJoD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-aTrbYg3TiSlYxJoD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-aTrbYg3TiSlYxJoD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-aTrbYg3TiSlYxJoD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-aTrbYg3TiSlYxJoD .marker.cross{stroke:#333333;}#mermaid-svg-aTrbYg3TiSlYxJoD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-aTrbYg3TiSlYxJoD p{margin:0;}#mermaid-svg-aTrbYg3TiSlYxJoD .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-aTrbYg3TiSlYxJoD .cluster-label text{fill:#333;}#mermaid-svg-aTrbYg3TiSlYxJoD .cluster-label span{color:#333;}#mermaid-svg-aTrbYg3TiSlYxJoD .cluster-label span p{background-color:transparent;}#mermaid-svg-aTrbYg3TiSlYxJoD .label text,#mermaid-svg-aTrbYg3TiSlYxJoD span{fill:#333;color:#333;}#mermaid-svg-aTrbYg3TiSlYxJoD .node rect,#mermaid-svg-aTrbYg3TiSlYxJoD .node circle,#mermaid-svg-aTrbYg3TiSlYxJoD .node ellipse,#mermaid-svg-aTrbYg3TiSlYxJoD .node polygon,#mermaid-svg-aTrbYg3TiSlYxJoD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-aTrbYg3TiSlYxJoD .rough-node .label text,#mermaid-svg-aTrbYg3TiSlYxJoD .node .label text,#mermaid-svg-aTrbYg3TiSlYxJoD .image-shape .label,#mermaid-svg-aTrbYg3TiSlYxJoD .icon-shape .label{text-anchor:middle;}#mermaid-svg-aTrbYg3TiSlYxJoD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-aTrbYg3TiSlYxJoD .rough-node .label,#mermaid-svg-aTrbYg3TiSlYxJoD .node .label,#mermaid-svg-aTrbYg3TiSlYxJoD .image-shape .label,#mermaid-svg-aTrbYg3TiSlYxJoD .icon-shape .label{text-align:center;}#mermaid-svg-aTrbYg3TiSlYxJoD .node.clickable{cursor:pointer;}#mermaid-svg-aTrbYg3TiSlYxJoD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-aTrbYg3TiSlYxJoD .arrowheadPath{fill:#333333;}#mermaid-svg-aTrbYg3TiSlYxJoD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-aTrbYg3TiSlYxJoD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-aTrbYg3TiSlYxJoD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aTrbYg3TiSlYxJoD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-aTrbYg3TiSlYxJoD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aTrbYg3TiSlYxJoD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-aTrbYg3TiSlYxJoD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-aTrbYg3TiSlYxJoD .cluster text{fill:#333;}#mermaid-svg-aTrbYg3TiSlYxJoD .cluster span{color:#333;}#mermaid-svg-aTrbYg3TiSlYxJoD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-aTrbYg3TiSlYxJoD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-aTrbYg3TiSlYxJoD rect.text{fill:none;stroke-width:0;}#mermaid-svg-aTrbYg3TiSlYxJoD .icon-shape,#mermaid-svg-aTrbYg3TiSlYxJoD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aTrbYg3TiSlYxJoD .icon-shape p,#mermaid-svg-aTrbYg3TiSlYxJoD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-aTrbYg3TiSlYxJoD .icon-shape .label rect,#mermaid-svg-aTrbYg3TiSlYxJoD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aTrbYg3TiSlYxJoD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-aTrbYg3TiSlYxJoD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-aTrbYg3TiSlYxJoD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} false
true
p != nullptr
短路,不再计算 *p > 0
✅ 避免空指针解引用
继续计算 *p > 0
6️⃣ 类型转换:隐式是坑,显式是德
6.1 隐式转换的四个危险场景
cpp
#include <iostream>
#include <vector>
int main() {
// 危险 1:窄化(大范围 → 小范围,丢精度)
double pi = 3.14159;
int truncated = pi; // 3,小数被截断(不是四舍五入!)
// 危险 2:有符号 ↔ 无符号
int i = -1;
unsigned int u = 1;
if (i < u) { // ❌ i 被转成 unsigned,变成 4294967295,条件为假
std::cout << "不会执行\n";
}
// 危险 3:vector.size() 返回 size_t(无符号)
std::vector<int> v = {1, 2, 3};
for (int k = 0; k < v.size(); ++k) { // ⚠️ int 与 size_t 比较,编译器可能警告
// ...
}
// 危险 4:bool 转换
int* ptr = nullptr;
if (ptr) { /* 等价于 ptr != nullptr */ }
}
6.2 四种显式转换对比
| 转换 | 用途 | 安全性 | 示例 |
|---|---|---|---|
static_cast<T> |
相关类型间转换(数值、继承上行) | ⚠️ 中 | static_cast<int>(3.14) |
dynamic_cast<T> |
多态类型下行转换(运行时检查) | ✅ 高 | dynamic_cast<Derived*>(base) |
const_cast<T> |
去掉/加上 const | ❌ 低 | const_cast<char*>(cstr) |
reinterpret_cast<T> |
位模式重解释(指针↔整数) | ❌ 极低 | reinterpret_cast<uintptr_t>(p) |
6.3 推荐写法:static_cast + size_t 字面量
cpp
#include <iostream>
#include <vector>
#include <cstddef>
int main() {
double value = 9.99;
int safe = static_cast<int>(value); // ✅ 意图明确,编译器会检查
std::vector<int> v = {10, 20, 30};
// C++23:size_t 字面量后缀 uz,彻底避开符号比较陷阱
for (auto idx = 0uz; idx < v.size(); ++idx) {
std::cout << v[idx] << "\n";
}
// 或者直接用范围 for(最推荐)
for (const auto& x : v) {
std::cout << x << "\n";
}
}
#mermaid-svg-GxjseqZX3YZpPmc0{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-GxjseqZX3YZpPmc0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-GxjseqZX3YZpPmc0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-GxjseqZX3YZpPmc0 .error-icon{fill:#552222;}#mermaid-svg-GxjseqZX3YZpPmc0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-GxjseqZX3YZpPmc0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-GxjseqZX3YZpPmc0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-GxjseqZX3YZpPmc0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-GxjseqZX3YZpPmc0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-GxjseqZX3YZpPmc0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-GxjseqZX3YZpPmc0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-GxjseqZX3YZpPmc0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-GxjseqZX3YZpPmc0 .marker.cross{stroke:#333333;}#mermaid-svg-GxjseqZX3YZpPmc0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-GxjseqZX3YZpPmc0 p{margin:0;}#mermaid-svg-GxjseqZX3YZpPmc0 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-GxjseqZX3YZpPmc0 .cluster-label text{fill:#333;}#mermaid-svg-GxjseqZX3YZpPmc0 .cluster-label span{color:#333;}#mermaid-svg-GxjseqZX3YZpPmc0 .cluster-label span p{background-color:transparent;}#mermaid-svg-GxjseqZX3YZpPmc0 .label text,#mermaid-svg-GxjseqZX3YZpPmc0 span{fill:#333;color:#333;}#mermaid-svg-GxjseqZX3YZpPmc0 .node rect,#mermaid-svg-GxjseqZX3YZpPmc0 .node circle,#mermaid-svg-GxjseqZX3YZpPmc0 .node ellipse,#mermaid-svg-GxjseqZX3YZpPmc0 .node polygon,#mermaid-svg-GxjseqZX3YZpPmc0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-GxjseqZX3YZpPmc0 .rough-node .label text,#mermaid-svg-GxjseqZX3YZpPmc0 .node .label text,#mermaid-svg-GxjseqZX3YZpPmc0 .image-shape .label,#mermaid-svg-GxjseqZX3YZpPmc0 .icon-shape .label{text-anchor:middle;}#mermaid-svg-GxjseqZX3YZpPmc0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-GxjseqZX3YZpPmc0 .rough-node .label,#mermaid-svg-GxjseqZX3YZpPmc0 .node .label,#mermaid-svg-GxjseqZX3YZpPmc0 .image-shape .label,#mermaid-svg-GxjseqZX3YZpPmc0 .icon-shape .label{text-align:center;}#mermaid-svg-GxjseqZX3YZpPmc0 .node.clickable{cursor:pointer;}#mermaid-svg-GxjseqZX3YZpPmc0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-GxjseqZX3YZpPmc0 .arrowheadPath{fill:#333333;}#mermaid-svg-GxjseqZX3YZpPmc0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-GxjseqZX3YZpPmc0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-GxjseqZX3YZpPmc0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GxjseqZX3YZpPmc0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-GxjseqZX3YZpPmc0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GxjseqZX3YZpPmc0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-GxjseqZX3YZpPmc0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-GxjseqZX3YZpPmc0 .cluster text{fill:#333;}#mermaid-svg-GxjseqZX3YZpPmc0 .cluster span{color:#333;}#mermaid-svg-GxjseqZX3YZpPmc0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-GxjseqZX3YZpPmc0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-GxjseqZX3YZpPmc0 rect.text{fill:none;stroke-width:0;}#mermaid-svg-GxjseqZX3YZpPmc0 .icon-shape,#mermaid-svg-GxjseqZX3YZpPmc0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GxjseqZX3YZpPmc0 .icon-shape p,#mermaid-svg-GxjseqZX3YZpPmc0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-GxjseqZX3YZpPmc0 .icon-shape .label rect,#mermaid-svg-GxjseqZX3YZpPmc0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GxjseqZX3YZpPmc0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-GxjseqZX3YZpPmc0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-GxjseqZX3YZpPmc0 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
是
否
是
否
是
否
需要类型转换
是数值类型间转换?
static_cast ✅
是多态下行转换?
dynamic_cast ✅
只是去 const?
const_cast ⚠️ 慎用
指针/整数位重解释?
reinterpret_cast ❌ 最后手段
重新设计,避免转换
💡 C++ Core Guidelines 建议 :不要用 C 风格
(int)x,一律用static_cast<int>(x),方便搜索和审查。
7️⃣ 本周高频面试题(5 道)
| # | 题目 | 考察点 | 参考答案要点 |
|---|---|---|---|
| 1 | int 和 long 有什么区别? |
平台差异 | 标准只保证最小位数,Windows long 32 位、Linux 64 位;跨平台用 int32_t |
| 2 | 0.1 + 0.2 == 0.3 为什么是 false? |
浮点表示 | IEEE 754 二进制无法精确表示 0.1,累加有误差;用 epsilon 比较 |
| 3 | size_t 和 int 比较为什么报警告? |
符号转换 | int 被转成无符号,负数变巨大值;用 0uz 或 static_cast<size_t> |
| 4 | auto x = 3.14; 中 x 是什么类型? |
auto 推导 | double,不是 float;要 float 必须写 3.14f |
| 5 | static_cast 和 reinterpret_cast 区别? |
转换语义 | 前者做语义相关的值转换,后者按位重解释,几乎不可移植 |
8️⃣ 本周项目验收:类型安全计算器
需求 :写一个命令行计算器,支持 + - * / %,要求:
- 输入两个数和一个运算符,输出结果;
- 除零检查,除零时输出错误而非崩溃;
- 结果用
double输出,但%只对整数生效; - 用
static_cast做所有显式转换,不用 C 风格转换; - 用
auto声明局部变量,大对象用const auto&。
参考答案(写完再看):
cpp
#include <iostream>
#include <string>
#include <cmath>
int main() {
double a, b;
char op;
std::cout << "输入表达式(如 3.5 + 2):";
std::cin >> a >> op >> b;
switch (op) {
case '+': std::cout << a + b << "\n"; break;
case '-': std::cout << a - b << "\n"; break;
case '*': std::cout << a * b << "\n"; break;
case '/':
if (std::fabs(b) < 1e-12) {
std::cout << "错误:除数为零\n";
} else {
std::cout << a / b << "\n";
}
break;
case '%':
std::cout << static_cast<long long>(a) % static_cast<long long>(b) << "\n";
break;
default:
std::cout << "未知运算符\n";
}
return 0;
}
验收标准:
-
3 / 0输出错误提示,不崩溃 -
5.5 % 2输出1(整数取模) - 编译加
-Wall -Wextra无警告 - 所有转换都是
static_cast
9️⃣ 本周避坑速查表(贴墙版)
#mermaid-svg-YSML9D9UTgG3lNLm{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-YSML9D9UTgG3lNLm .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YSML9D9UTgG3lNLm .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YSML9D9UTgG3lNLm .error-icon{fill:#552222;}#mermaid-svg-YSML9D9UTgG3lNLm .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YSML9D9UTgG3lNLm .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YSML9D9UTgG3lNLm .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YSML9D9UTgG3lNLm .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YSML9D9UTgG3lNLm .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YSML9D9UTgG3lNLm .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YSML9D9UTgG3lNLm .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YSML9D9UTgG3lNLm .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YSML9D9UTgG3lNLm .marker.cross{stroke:#333333;}#mermaid-svg-YSML9D9UTgG3lNLm svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YSML9D9UTgG3lNLm p{margin:0;}#mermaid-svg-YSML9D9UTgG3lNLm .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-YSML9D9UTgG3lNLm .cluster-label text{fill:#333;}#mermaid-svg-YSML9D9UTgG3lNLm .cluster-label span{color:#333;}#mermaid-svg-YSML9D9UTgG3lNLm .cluster-label span p{background-color:transparent;}#mermaid-svg-YSML9D9UTgG3lNLm .label text,#mermaid-svg-YSML9D9UTgG3lNLm span{fill:#333;color:#333;}#mermaid-svg-YSML9D9UTgG3lNLm .node rect,#mermaid-svg-YSML9D9UTgG3lNLm .node circle,#mermaid-svg-YSML9D9UTgG3lNLm .node ellipse,#mermaid-svg-YSML9D9UTgG3lNLm .node polygon,#mermaid-svg-YSML9D9UTgG3lNLm .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YSML9D9UTgG3lNLm .rough-node .label text,#mermaid-svg-YSML9D9UTgG3lNLm .node .label text,#mermaid-svg-YSML9D9UTgG3lNLm .image-shape .label,#mermaid-svg-YSML9D9UTgG3lNLm .icon-shape .label{text-anchor:middle;}#mermaid-svg-YSML9D9UTgG3lNLm .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-YSML9D9UTgG3lNLm .rough-node .label,#mermaid-svg-YSML9D9UTgG3lNLm .node .label,#mermaid-svg-YSML9D9UTgG3lNLm .image-shape .label,#mermaid-svg-YSML9D9UTgG3lNLm .icon-shape .label{text-align:center;}#mermaid-svg-YSML9D9UTgG3lNLm .node.clickable{cursor:pointer;}#mermaid-svg-YSML9D9UTgG3lNLm .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-YSML9D9UTgG3lNLm .arrowheadPath{fill:#333333;}#mermaid-svg-YSML9D9UTgG3lNLm .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-YSML9D9UTgG3lNLm .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-YSML9D9UTgG3lNLm .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YSML9D9UTgG3lNLm .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-YSML9D9UTgG3lNLm .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YSML9D9UTgG3lNLm .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-YSML9D9UTgG3lNLm .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-YSML9D9UTgG3lNLm .cluster text{fill:#333;}#mermaid-svg-YSML9D9UTgG3lNLm .cluster span{color:#333;}#mermaid-svg-YSML9D9UTgG3lNLm div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-YSML9D9UTgG3lNLm .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-YSML9D9UTgG3lNLm rect.text{fill:none;stroke-width:0;}#mermaid-svg-YSML9D9UTgG3lNLm .icon-shape,#mermaid-svg-YSML9D9UTgG3lNLm .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YSML9D9UTgG3lNLm .icon-shape p,#mermaid-svg-YSML9D9UTgG3lNLm .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-YSML9D9UTgG3lNLm .icon-shape .label rect,#mermaid-svg-YSML9D9UTgG3lNLm .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YSML9D9UTgG3lNLm .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-YSML9D9UTgG3lNLm .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-YSML9D9UTgG3lNLm :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 第2周避坑清单
整型
浮点
字符
auto
运算符
转换
用 cstdint 固定宽度
有符号溢出是 UB
不用 == 比较浮点
金额用整数分
字节用 unsigned char
不要裸 char 存二进制
大对象用 const auto&
3.14 推导是 double
混合运算加括号
&& 短路保证判空在前
不用 C 风格转换
用 static_cast
🎯 一句话总结 :类型选得对,Bug 少一半;转换写得明,审查不头疼;浮点别比等,符号别混比;括号不嫌多,auto 看场景。 掌握这六件事,第 2 周就算真正过关了。