class A
{
int a;
}
class B
{
char b;
};
class C
class C
{
char a;
int b;
};
cout<<sizeof(A)<<endl;
cout<<sizeof(B)<<endl;
cout<<sizeof(C)<<endl;
运行结果: 4,1,8;
运行结果: 4,1,8;
大家一定会奇怪为什么最后面的那个会是8字节!
这和变量在内存中的存储形式有关(罪魁祸首是编译器),大家都知道我们所写的代码,在编译后都会变成汇编代码(也会进一步成为机器代码),汇编吧数据设计成段栈的存储形式,为了提高访问效率,它要求每一次移动栈顶指针的步长都要相同(以空间换换时间)!也就是说即使一个变量没有占那么多字节也要把它后面补上一些空字节来使各变量在内存上对齐!而且按照占字节最多的那个变量来对齐!
这和变量在内存中的存储形式有关(罪魁祸首是编译器),大家都知道我们所写的代码,在编译后都会变成汇编代码(也会进一步成为机器代码),汇编吧数据设计成段栈的存储形式,为了提高访问效率,它要求每一次移动栈顶指针的步长都要相同(以空间换换时间)!也就是说即使一个变量没有占那么多字节也要把它后面补上一些空字节来使各变量在内存上对齐!而且按照占字节最多的那个变量来对齐!
举个例子吧!
struct s
{
int i;
char j;
double b;
int a;
};
在内存上,存储这四个变量是按出现的顺序来的!首先最长的是b占8个字节,前两个一共占了5个字节,所以可以把i和j“连接成一块",然后在后面补齐3个空字节,然后写b8个字节,最后是a因为后面已经没有变量了所以他自己在后面补齐4个空字节!Ok !所以结果是24个字节。
在内存上,存储这四个变量是按出现的顺序来的!首先最长的是b占8个字节,前两个一共占了5个字节,所以可以把i和j“连接成一块",然后在后面补齐3个空字节,然后写b8个字节,最后是a因为后面已经没有变量了所以他自己在后面补齐4个空字节!Ok !所以结果是24个字节。
若是
struct s
{
int i;
char j;
double b;
char a[6];
};
则sizeof(struct s) = 24;
若是
struct s
{
int i;
char j;
double b;
char a[9];
};
{
int i;
char j;
double b;
char a[9];
};
则sizeof(struct s) = 32;同样,最长的是b占8个字节,i和j连成一起占8个字节,而a[9]大于8填满8个字节后还有一个字符必须再填满8个字节,一共是32个字节。
结构体中的位域
位域是指信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几 个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。
如:
struct s
{
int year;
int mouth:4;
int day:5;
int hour:5;
int minute:6;
int second:5;
};
则sizeof(struct s) = 8,因为 4+5+5+6+5 = 25 < 32,加上year的4字节补齐一共是8字节。
若是
struct s
{
int year;
int mouth:7;
int day:7;
int hour:7;
int minute:7;
int second:5;
};
则sizeof(struct s) = 12;因为7+7+7+7+5 = 33 > 32,补齐一共是12个字节。