📄 一句话概括
sizeof 是量字节的尺子——量类型、量变量、量表达式,回答"这东西占几个字节"。两个反直觉的点:它不是函数,是运算符;它在编译期就出结果,程序还没跑答案就定了。
一、三种量法
| 用法 | 例子 | 结果(典型 64 位系统) |
|---|---|---|
| 量类型 | sizeof(int) |
4 |
| 量变量 | double d; sizeof(d) |
8 |
| 量表达式 | sizeof(3 + 1.5) |
8(不真算 3+1.5,只看结果类型是 double) |
回看 2.3.3 整型家族那章,sizeof(int) = 4 就已经见过它——当时它给整型家族报了各自占几个字节。把它当"尺子"记住即可:给什么量什么,答字节数。
两种写法:sizeof(int) 必须带括号(量类型时);sizeof d 量变量时可以不带——但建议永远带括号,统一好记。
二、反直觉一:它不是函数,是运算符
长得像函数调用,但它在本章九类运算符的名单里("问"字号分组)。怎么证明?量类型时不用任何"运行"动作——sizeof(int) 编译阶段就变成了常数 4,编译器直接把数字填进程序。
推论(编译期求值):sizeof(3 + 1.5) 不会在运行时做加法——编译器只看"这个表达式结果类型是 double",填一个 8 了事。表达式里就算写个函数调用,函数也不会执行。
这个特性有个正经用途:sizeof(数组名) / sizeof(数组名[0]) 能在编译期算出数组元素个数(第 7 章数组会正式用)。
三、反直觉二:尺子量的是"盒子容量",不是"装了多少"
2.2.4 的老对比,这里正式收编:
char s[10] = "abc";
cout << sizeof(s) << endl; // 10 —— 盒子总容量(10 个格子)
cout << strlen(s) << endl; // 3 —— 实际字数(走到 '\0' 停)
sizeof(运算符):容量——编译期、静态、认格子不认内容strlen(函数):存量——运行期、逐字节数、认内容
一个好记的比方:sizeof 量的是杯子多大,strlen 量的是杯里有多少水。杯子 10 格,倒了 3 格水,两个答案都对,量的是不同的东西。
四、动手 Demo:把全家族量一遍
#include <iostream>
#include <cstring>
using namespace std;
int main() {
cout << "char " << sizeof(char) << endl; // 1
cout << "bool " << sizeof(bool) << endl; // 1
cout << "short " << sizeof(short) << endl; // 2
cout << "int " << sizeof(int) << endl; // 4
cout << "long long" << sizeof(long long) << endl;// 8
cout << "float " << sizeof(float) << endl; // 4
cout << "double " << sizeof(double) << endl; // 8
char s[10] = "abc";
cout << "sizeof(s) " << sizeof(s) << endl; // 10
cout << "strlen(s) " << strlen(s) << endl; // 3
cout << "sizeof(1+1.5) " << sizeof(1 + 1.5) << endl; // 8
return 0;
}
看到什么算成功:家族字节表 + 10 3 8。这张字节表建议抄进笔记——它是 2.3.3、2.3.4 两节范围表的"来源"。
30 秒实验:把 char s[10] 改成 char s[] = "abc"(让编译器自动定容量),再看 sizeof(s)——变成 4(3 个字符 + 1 个 '\0')。尺子跟着盒子的实际大小走。
五、常见误区
- "
sizeof是函数,要头文件"——是运算符,不需要任何头文件。(strlen才要<cstring>。) - "
sizeof是程序运行时量的"——编译期就定了,这是它和strlen最本质的区别之一。 - "
sizeof(3+1.5)会算出 4.5 再量"——不算,只看结果类型(double → 8)。 - "所有机器上 int 都是 4 字节"——C++ 标准只规定"int ≥ short、long ≥ int"这类相对关系,具体字节随平台。写"可移植"的程序就该用 sizeof 现场量,别写死 4。
自测四问(点开对答案)
1. `sizeof` 和 `strlen` 谁需要头文件?——`strlen` 要 `- ☐ 3.1.8 条件运算符(下一节)