一句话:"sizeof 问多大(含\0,编译期),strlen 问多长(不含\0,运行期)。"
sizeof = 编译期算"这个类型占多少字节";strlen = 运行期 O(n) 扫到 \0 前数"有几个字符"。strlen 依赖 \0 结尾,没 \0 会越界读。
char s[] = "hello"; → sizeof(s) = 6(5 字符+\0),strlen(s) = 5(数到 \0 前)char *p = "hello"; → sizeof(p) = 4/8(指针大小),strlen(p) = 5void f(char s[]) { sizeof(s); } → 4/8!形参是退化指针;strlen(s) 照样对char s[100] = "hi"; → sizeof(s) = 100(声明的大小),strlen(s) = 2(实际字符数)sizeof |
strlen |
|
|---|---|---|
| 时机 | 编译期(编完就定死) | 运行期(跑起来才数) |
| 算什么 | 类型占多少字节 | 到 \0 前几个字符 |
含 \0 |
✅ 含(按类型大小) | ❌ 不含 |
| 对数组 | 整块大小(6/100) | 长度(5/2) |
| 对指针 | 指针大小(4/8) | 照样数 |
char s[100] = "hi"; → sizeof(s) = 100(声明的大小),strlen(s) = 2(实际字符数)void f(char s[]) {...} 传 f("hello") → 打印 sizeof = 4/8(退化指针)、strlen = 5int a[5]; → sizeof(a) = 20;strlen(a) 不能用(strlen 只认 char* 字符串,int 数组没有 \0 语义)| 相邻概念 | 和本主题的关系 | 孤立理解会犯的错 |
|---|---|---|
| 数组名 vs 指针 | sizeof 失灵的根源 = 数组名传参退化 | 传参后还 sizeof 想拿数组长度 |
| 字符串 | strlen 依赖 \0 结尾——没 \0 的缓冲区会数出界 |
以为 strlen 自动安全 |
| 结构体对齐 | sizeof(结构体) 含填充字节,可用于算偏移 |
以为 sizeof 结构体 = 成员和 |
| 内存安全 | strlen 对未初始化/无 \0 内存会越界读 |
忘了检查缓冲区是否以 \0 结尾 |
2026-08-03
每主题一页,复习时只翻本目录。