概述
一、基本计算
1、变量大小(64位机)
sizeof(bool) = 1
sizeof(char) = 1
sizeof(short) = 2
sizeof(int) = 4
sizeof(long) = 4
sizeof(long long) = 8
sizeof(float) = 4
sizeof(double) = 8
2、数组、指针大小
char arr[10];
char str[] = "hello world";
char *p = "hello world";
sizeof(arr) = 10
sizeof(str) = 12
sizeof(p) = 4 // 指针变量的大小
3、类、结构体
字节对齐:(1)对齐最宽的成员;(2)类/结构体的大小是最宽成员宽度的整数倍。
class A {
char a;
};
class B {
char a;
int b;
};
class C {
char a;
int b;
short c;
};
class D {
char a;
int b;
short c;
char *p;
};
class E {
char a;
int b;
short c;
char *p; // 指针占 4 个字节
double d;
};
class F {
char a;
short b;
short c;
};
class G {
char a[11]; // 2 字节对齐,后面补 1 个空位,占 12 个字节
short b;
short c;
};
sizeof(A) = 1 // 1字节对齐
sizeof(B) = 8 // 4字节对齐
sizeof(C) = 12 // 4字节对齐
sizeof(D) = 16 // 4字节对齐
sizeof(E) = 24 // 8字节对齐
sizeof(F) = 6 // 2字节对齐
sizeof(G) = 16 // 2字节对齐
4、联合体(共用体)
联合体的大小:最宽成员大小的整数倍。
特点:只能给一个成员赋值,所有成员共享一块内存。
union A {
char a;
};
union B {
char a;
short b;
};
union C {
char a;
short b;
int c;
};
union C {
char a[10];
short b;
int c;
};
union D {
char a[10]; // 最大 10,不是 4 的倍数,改 12
short b;
int c = 10;
};
sizeof(A) = 1 // 最宽成员大小 1
sizeof(B) = 2 // 最宽成员大小 2
sizeof(C) = 4 // 最宽成员大小 4
sizeof(D) = 12 // 最宽成员大小的整数倍 4*3,也是一种对齐
所有成员共享一块内存:
cout << (int)(aa.a[0]) << endl; 10
cout << (int)(aa.a[1]) << endl; 0
cout << aa.b << endl; 10
cout << aa.c << endl; 10
5、枚举类型
枚举类型的大小:4个字节
特点:保存一个从0开始的序列。
对于成员,是枚举常量,值为序列号,不能再被赋值;
成员就像宏常量一样,可以用来给枚举变量赋值,也可以用来给其他对象赋值。局部变量会屏蔽枚举常量。
对于枚举变量/对象,其值只能赋值为其成员,不能直接赋值为 0, 1, 2, ...。不能用枚举变量引用其成员。
union A {
a
};
union B {
a,
b,
c,
d,
e,
f
};
sizeof(A) = 4
sizeof(B) = 4
6、位段结构体
位段结构体大小:最宽成员的大小的整数倍。
位域/位段:以位为单位来指定成员所占内存的长度,这种成员称为“位域”或“位段”。
特点:
(1)成员类型 —— long long、int、short、char(unsigned char)。有符号或者无符号类型。char 默认是无符号的。
(2)一个位域必须存储在同一个存储单元中,不能跨越两个存储单元。
(3)存储单元的大小是最宽成员的宽度。
(4)位域长度不能大于存储单元的长度,不能定义位域数组。
(5)通过使用空域,可以使下一个位域从下一个存储单元开始存放。
struct A {
int a:8;
int b:2;
int c:6;
};
struct B {
int a : 8;
int b : 2;
int : 0; // 空域,使下一个位域从下一个存储单元 (int) 开始存放
int d : 3;
};
struct C {
short a : 8;
short b : 2;
short : 0;
short d : 3;
};
struct D {
short a : 8;
short b : 2;
short : 0;
int d : 3;
};
struct E {
int a : 8;
short b : 2;
short : 0;
short d : 3;
};
sizeof(A) = 4 // 1 * int
sizeof(B) = 8 // 2 * int
sizeof(C) = 4 // 2 * short
sizeof(D) = 8 // 2 * int
sizeof(E) = 8 // 2 * int
二、复杂分析
1、结论
(1)无论是结构体,还是联合体,对齐方式都是一样的 —— 与最宽基本类型对齐。
(2)结构体取和,联合体取最大。
(3)嵌套的情况,必须定义子对象才有意义,否则无大小无意义。
(4)嵌套时,与最宽基本类型对齐。
2、嵌套计算
(1)先确定计算子对象大小,并将其转化为等效对象
(2)再计算
3、案列分析
(1)按 4 字节对齐,填充内存
class class_abc {
int a; // 4
char b[10]; // 12
};
// --- 与4对齐 ---
4 //a
4 //b
4
2
(2)按 4 字节对齐,取最大的
union union_abc {
int a; // 4,与4对齐
char b[10]; // 12
};
// --- 与4对齐 ---
4
4
2
(3)按 4 字节对齐,填充内存
class class_abcdef {
int a; // 2,与2对齐
char b[9]; // 9
short c[3]; // 6
char d[5]; // 5
};
// --- 与4对齐 ---
4 //a
4 //b
4
1 2 //b,c
4
4 //d
1
(4)内层按 4 字节对齐,等效为 int c[3],外层按等效后的 4 字节对齐
class class_abcdef {
int a; // 4,与2对齐
char b[9]; // 9
union union_abcdef { // 与4对齐,12,相当于 int c[3];
int a;
char b[10];
} abcdef; // 注意,不定义对象的话,该块大小按 0 计算 !!!
};
// --- 与4对齐 ---
4 //a
4 //b
4
1
4 //c
4
4
(5)内层按 1 字节对齐,等效为 char c[10],外层按等效后的 4 字节对齐
class class_abcdef {
int a; // 4,与2对齐
char b[9]; // 9
union union_abcdef { // 与1对齐,10,相当于 char c[10];
char b[10];
} abcdef; // 注意,不定义对象的话,该块大小按 0 计算 !!!
};
// --- 与4对齐 ---
4 //a
4 //b
4
1 3 //b,c
4
3
(6)内层按 1 字节对齐,等效为 char c[10],外层按等效后的 4 字节对齐
class class_abcdef {
int a; // 4,与2对齐
char b[9]; // 9
union union_abcdef { // 与1对齐,10,相当于 char c[10];
char b[10];
} abcdef; // 注意,不定义对象的话,该块大小按 0 计算 !!!
char d;
};
// --- 与4对齐 ---
4 //a
4 //b
4
1 3 //b,c
4
3 1 //c,d
(7)内层按 8 字节对齐,等效为 double c[2],外层按等效后的 8 字节对齐
class class_abcdef {
int a; // 4,与2对齐
char b[9]; // 9
union union_abcdef { // 与8对齐,16,相当于 double c[2];
double a;
char b[10];
} abcdef; // 注意,不定义对象的话,该块大小按 0 计算 !!!
char k;
};
// --- 与8对齐 ---
4 4 //a,b
5 //b
8 //c
8
1 //d
(8)内层按 4 字节对齐,等效为 int c[3],外层按 8 字节对齐
class class_abcdef {
double a; // 4,与2对齐
char b[9]; // 9
union union_abcdef { // 与4对齐,12,相当于 int c[3];
int a;
char b[10];
} abcdef; // 注意,不定义对象的话,该块大小按 0 计算 !!!
char k;
};
// --- 与8对齐 ---
8 //a
8 //b
1 4 //b,c
8
1 //d
最后
以上就是无限仙人掌为你收集整理的C++:sizeof() —— 变量、指针、数组、类、结构体、联合体(共用体)、枚举类型一、基本计算二、复杂分析的全部内容,希望文章能够帮你解决C++:sizeof() —— 变量、指针、数组、类、结构体、联合体(共用体)、枚举类型一、基本计算二、复杂分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复