sizeof运算符
一、sizeof是什么
sizeof 是 C/C++ 运算符,不是函数!
作用:计算 类型 / 变量 / 数组 / 结构体 所占内存字节数。
语法两种:
// 1. 类型必须加括号
sizeof(int);
// 2. 变量可以不加括号
int a;
sizeof a;
二、基本规则(64 位编译器)
- 基础数据类型固定大小
char 1字节
short 2字节
int 4字节
long long 8字节
double 8字节
重点:64 位系统不改变 int 大小,int 永远 4 字节。
- 指针大小规则
指针只和系统位数有关,和指向什么类型无关
32 位编译器:所有指针都是 4 字节
64 位编译器:所有指针都是 8 字节
示例:
char* p1;
int* p2;
double* p3;
// 64位下 sizeof(p1)=sizeof(p2)=sizeof(p3)=8
三、sizeof 对数组的处理
- 普通数组
//sizeof(数组名) = 整个数组总字节数
int arr[10];
sizeof(arr) = 40 // 总字节:10*4 = 40
int cnt = sizeof(arr) / sizeof(arr[0]); // 求数组元素个数经典公式:
- 字符串数组
char str[] = "abc"; // 实际存:a b c \0,自带结束符 \0
sizeof(str) = 4
- 数组做函数参数会退化
void fun(char arr[])
{
// 数组退化为指针,64位下=8
cout << sizeof(arr);
}
//只要数组当形参,就不再是数组,而是指针
四、sizeof 对结构体(重点必考)
- 默认内存对齐
编译器默认自动内存对齐:
- 成员变量按自身大小对齐
- 中间空余字节做填充
- 结构体整体大小是最大成员的整数倍
示例:
struct A
{
char c;
int n;
};
// 默认对齐:sizeof(A) = 8
- 关闭内存对齐(紧凑排列)
用 #pragma pack 强制 1 字节对齐,无填充:
#pragma pack(push, 1)
struct A
{
char c;
int n;
};
#pragma pack(pop)
// 紧凑后:sizeof(A) = 5
五、sizeof 几点核心特性
- sizeof 是编译期求值
程序运行时不会计算,编译阶段就确定结果。 - 不会计算表达式运行结果
int a = 10;
sizeof(a++);
// a 不会自增,sizeof 只看类型,不执行表达式
- 不能用于不完全类型
如未知大小的数组、未定义的类,不能用 sizeof。 - 对引用取 sizeof
sizeof(引用) = 原变量类型大小
引用只是别名,不单独占内存。
六、总结如下
cout << "sizeof(char) is " << sizeof(char) << endl; // 1(固定长度,与平台无关)
cout << "sizeof(short) is " << sizeof(short) << endl; // 2(固定长度,与平台无关)
cout << "sizeof(int) is " << sizeof(int) << endl; // 4(固定长度,与平台无关)
cout << "sizeof(long) is " << sizeof(long) << endl; // 4(Windows 32&64都是4,Linux 32是4,Linux 64是8)
cout << "sizeof(long long) is " << sizeof(long long) << endl; // 8(固定长度,与平台无关)
cout << "sizeof(float) is " << sizeof(float) << endl; // 4(固定长度,与平台无关)
cout << "sizeof(double) is " << sizeof(double) << endl; // 8(固定长度,与平台无关)
char* str1 = "12345";
char str2[] = "12345";
cout << "sizeof(char*) is " << sizeof(str1) << endl; // (32位编译器为4,64位为8,与字符串长度无关)
cout << "sizeof(char[]) is " << sizeof(str2) << endl; // 6(字符数+结尾符)
int a[10][2];
cout << "sizeof(a) / sizeof(a[0]) is " << sizeof(a) / sizeof(a[0]) << endl; // 10X2X4/2X4=10
cout << "sizeof(a) / sizeof(a[0][0]) is " << sizeof(a) / sizeof(a[0][0]) << endl; // 10X2X4/4=20
#pragma pack(push,1) // 改成1字节对齐,紧凑排列
struct A
{
char c;
int n;
};
#pragma pack(pop) // 恢复默认对齐,不影响后面其他结构体
cout << sizeof(A) << endl; // 默认内存对齐时为8(去掉上面的两行#pragma,保留上面两行时为5)
void fun(char arr[])
{
int len = sizeof(arr);
cout << "char array in function is " << len << endl; // (会隐式退化为指针,32位编译器为4,64位为8,与字符串长度无关)
}
七、常考口诀
- 基础类型大小基本固定,int 永远 4 字节
- 指针看系统:32 位 4,64 位 8
- 数组名 sizeof 是总字节,传参变指针
- 字符串数组含 \0,多占 1 字节
- 结构体默认对齐有填充,pack(1) 关闭对齐变紧凑
- sizeof 编译期计算,不执行里面表达式
浙公网安备 33010602011771号