## sizeof vs strlen ## 判别规则(核心,唯一要记的) - **sizeof → 编译期,按类型算字节,含 \0**(数组得整块大小、指针得 4/8) - **strlen → 运行期,数到 \0 前,不含 \0** - **陷阱:数组名传参退化成指针后,sizeof 得指针大小**——函数里算数组长度要靠参数传入 一句话:**"sizeof 问多大(含\0,编译期),strlen 问多长(不含\0,运行期)。"** ## 抽象描述(一句话本质) sizeof = 编译期算"这个类型占多少字节";strlen = 运行期 O(n) 扫到 \0 前数"有几个字符"。strlen 依赖 \0 结尾,没 \0 会越界读。 ## 正反例(建立直觉) - **正例1**:`char s[] = "hello";` → `sizeof(s)` = **6**(5 字符+\0),`strlen(s)` = **5**(数到 \0 前) - **正例2**:`char *p = "hello";` → `sizeof(p)` = **4/8**(指针大小),`strlen(p)` = **5** - **正例3**:`void f(char s[]) { sizeof(s); }` → **4/8**!形参是退化指针;strlen(s) 照样对 - **正例4**:`char s[100] = "hi";` → `sizeof(s)` = **100**(声明的大小),`strlen(s)` = **2**(实际字符数) - **反例1**:以为 strlen 含 \0 → 错,不含 - **反例2**:以为 sizeof 数"有效字符数" → 错,是类型占多少字节 ## 易混对比 | | `sizeof` | `strlen` | | ------- | ------------------------ | ------------------------ | | 时机 | **编译期**(编完就定死) | **运行期**(跑起来才数) | | 算什么 | 类型占**多少字节** | 到 `\0` 前**几个字符** | | 含 `\0` | ✅ 含(按类型大小) | ❌ 不含 | | 对数组 | 整块大小(6/100) | 长度(5/2) | | 对指针 | 指针大小(4/8) | 照样数 | ## 变体验证(3 题,全过=学会) 1. `char s[100] = "hi";` → `sizeof(s)` = **100**(声明的大小),`strlen(s)` = **2**(实际字符数) 2. 陷阱题:`void f(char s[]) {...}` 传 `f("hello")` → 打印 `sizeof` = **4/8**(退化指针)、`strlen` = **5** 3. 陷阱题:`int a[5];` → `sizeof(a)` = **20**;`strlen(a)` **不能用**(strlen 只认 char* 字符串,int 数组没有 \0 语义) ## 口述要点(面试怎么讲) - **结论先行**:sizeof 编译期按类型算字节(含\0),strlen 运行期数到\0前(不含\0) - **为什么 strlen 必须运行期**:设计上必须 O(n) 扫描 \0 才能知道长度,编译期做不到(除非字面量可静态计算) - **函数里怎么拿数组长度**:函数参数显式传入数组长度;封装容器/宏在声明处算好。**函数内对退化指针 sizeof 拿不到长度** - **为什么嵌入式推崇 sizeof**:编译器按当前平台算,跨平台自动适配(int 在 16 位机是 2 字节、32 位是 4 字节),手写常量换平台就错;数组改大小时只改一处,防越界 - **易错点**:传参后 sizeof 失灵;strlen 对没 \0 的缓冲区会越界读 ## 关系网络 | 相邻概念 | 和本主题的关系 | 孤立理解会犯的错 | | -------------- | ----------------------------------------------- | ------------------------------ | | 数组名 vs 指针 | sizeof 失灵的根源 = 数组名传参退化 | 传参后还 sizeof 想拿数组长度 | | 字符串 | strlen 依赖 `\0` 结尾——没 `\0` 的缓冲区会数出界 | 以为 strlen 自动安全 | | 结构体对齐 | `sizeof(结构体)` 含填充字节,可用于算偏移 | 以为 sizeof 结构体 = 成员和 | | 内存安全 | strlen 对未初始化/无 `\0` 内存会越界读 | 忘了检查缓冲区是否以 `\0` 结尾 | ## 学习日期 2026-08-03 --- _每主题一页,复习时只翻本目录。_