- sizeof是一个单目运算符,并不是一个函数
- 操作数可以是类型名也可以是表达式
- 如果是类型名,直接获取该类型的字节数
- 如果是表达式,先分析表达式结果的类型,再确定所占字节数,并不对表达式实际进行计算
int a = 1;
double b = 1.5;
sizeof(short); //2
sizeof(long); //4
sizeof(float); //4
sizeof(double); //8
sizeof(int); //4
sizeof(a); //4
sizeof(a + b); //8
int * ptr = (int *)malloc(sizeof(int) * 20); //申请20个int类型大小的空间
sizeof(ptr); //x86为4,x64为8
将数组名作为sizeof运算符的操作数可以获得整个数组所占空间
如果作为实参传递给子函数,子函数中形参对应的参数已经变成指针,而对指针使用sizeof运算符只能获取指针本身所占的字节数。
void subfunc(double darray[]){
cout << sizeof(darray)/sizeof(double) << endl; //输出4/8 = 0
}
int main(){
double darray[20];
cout<<sizeof(darray)/sizeof(double) << endl;//输出160/8 = 20
subfunc(darray);
}
sizeof的适用范围
struct baby{
unsigned int gender:1;
unsigned int weight:5;
unsigned int week:7;
};
int triple(int number){
return 3 * number;
}
void show(int rank){
cout <<"NO."<<rank<<endl;
}
int main(){
sizeof(baby); //可以计算结构体占的空间
// sizeof(baby.gender); 不允许计算结构体中某个位域成占用的空间
// sizeof(triple); 不能计算函数所占空间
sizeof(triple(3));//允许计算函数调用表达式(返回值类型所占空间)
// sizeof(show()); 不允许计算不明确类型、void类型
}
数据对齐
在处理结构体中的成员时,成员在内存中的起始地址编码必须是成员类型的所占字节的整数倍(补齐)
struct s1{
char a;
short b;
int c;
double d;
};
struct s2{
char a;
short b;
double c;
int d;
};
sizeof(s1); //16
sizeof(s2); //24
如结构体s1
a为char型,起始地址为0,占1个字节,下一地址是1;
b为short型,占2个字节,起始地址必须是2的整数倍,起始地址为2,下一地址为4;
c为int型,占4个字节起始地址为4,下一地址为8;
d为double型,占8个字节,起始地址为8,下一地址为16
struct s1{
int a;
};
struct s2{
char a[4];
};
struct s3{
char a[4];
char b;
};
struct s4{
s1 a;
char b;
};
struct s5{
s2 a;
char b;
};
/*在数据对齐时,要以结构体中最深层的基本数据类型为准*/
sizeof(s1) = 4
sizeof(s2) = 4 // 1*4
sizeof(s3) = 5 // 1*4 + 1
sizeof(s4) = 8 // 4 + 4 运算结果为4的整数倍
sizeof(s5) = 5 // 4*1 + 1
本文深入解析C++中sizeof运算符的功能与使用,包括其如何计算不同类型及表达式的字节数,数据对齐规则,以及在结构体、数组和函数调用中的表现。通过实例展示了sizeof在内存管理中的应用。
1478

被折叠的 条评论
为什么被折叠?



