
简要说明: 结构的成员按照定义的顺序存储在连续的内存空间中. 但是,结构的大小不是简单地将所有成员加在一起,而是遵循某些规则. 存储结构变量时,应在系统地址对齐问题中予以考虑.
1. 没有成员的结构占用多少字节?
答案是: 1个字节.
这就是实例化的原因(空类也可以被实例化),每个实例在内存中都有一个唯一的地址,为了达到这个目的,编译器通常会给出一个空类或空结构(C ++中的结构)也可以视为一个类)sizeof计算结构体大小,隐式添加一个字节,以便空类或空结构在实例化后在内存中获得唯一的地址,因此空类的内存大小为1个字节.
二,首先介绍一个相关的概念偏移量
结构体
{
int a; //起始地址为0
字符b; //起始地址为4
int c; //起始地址为8
};
偏移量是指结构变量中成员的地址与结构变量地址之间的差. 结构的大小等于最后一个成员的偏移量加上最后一个成员的大小. 显然,结构变量中第一个成员的地址是结构变量的第一个地址. 例如,在上面的结构中,第一成员a的偏移量为0. 第二成员b的偏移量为第一成员的偏移量加上第一成员的大小(0 + 4),其值为4 第三个成员c的偏移量是第二个成员. 该成员的偏移量应加上第二个成员的大小(4 + 1).
三个. 实际上,存储变量时需要地址对齐,并且编译器在编译程序时将遵循两个原则:
(1)结构变量中成员的偏移量必须是成员大小的整数倍(0被认为是任意数字的整数倍)
(2)结构的大小必须是所有成员大小的整数倍,即所有成员大小的公倍数.
示例1:
struct stru1
{
int a; //起始地址为0
字符b; //起始地址为4
int c; //起始地址为8
};
PS: 使用sizeof查找结构的大小,并找到值为12. Int占用4个字节,而char占用1个字节. 结果应为9个字节. 为什么?在此示例中,前两个成员的偏移量满足要求,但是第三个成员的偏移量为5,这不是其自身(int)大小的整数倍. 处理时,编译器将在第二个成员之后添加3个空字节,以使第三个成员的偏移量变为8. 该结构的大小等于最后一个成员的偏移量加上其大小. 上例中计算出的大小为12,符合要求.
示例2:
struct stru2
{
int i; //起始地址为0
短m; //起始地址为4
};
PS: 成员i的偏移量为0;成员m的偏移量为4,因此无需进行调整. 但是计算得出的大小为6,这显然不是成员m大小的整数倍. 因此,编译器将在成员m之后添加2个字节,以便结构的大小变为8以满足第二个要求.
示例3和4:
struct stru3
{
char i; //起始地址为0
int m; //起始地址为4
char n; //起始地址为8
};
struct stru4

{
char i; //起始地址为0
char n; //起始地址为1
int m; //起始地址为4
};
尽管结构stru3和stru4的成员相同,但是sizeof(struct stru3)的值为12,sizeof(struct stru4)的值为8.
可以看出,结构类型需要考虑字节对齐,并且不同的顺序将影响结构的大小.
四个. 对于嵌套结构,您需要对其进行扩展. 在为该结构寻求sizeof时,以上两个原则变为:
(1)扩展结构的第一个成员的偏移量应为扩展结构中最大成员的整数倍.
(2)结构的大小必须是所有成员大小的整数倍. 在这里sizeof计算结构体大小,所有成员都被计算为扩展成员,而不是整个嵌套结构.
示例1:
struct stru5
{
简短的我;
结构
{
字符c;
int j;
} tt;
int k;
};
结构stru5的成员tt.c的偏移量应为4,而不是2. 整个结构的大小应为16.
示例2:
struct stru6
{
char i;
结构
{
字符c;
int j;
} tt;
字符a;
字符b;
char d;
字符e;
int f;
};
仅结构tt计算8占用的空间,而stru6的sizeof为20,而不是8的整数倍,这意味着在计算sizeof(stru6)时,嵌套结构ss被扩展了,因此stu6最大的成员是tt.j,它占4个字节,而20是4的整数倍. 如果将tt作为一个整体,结果应为24.

5: 另一个特殊的示例是该结构包含一个数组,并且其sizeof应该与嵌套结构相同. 展开它,如以下示例所示:
结构数组
{
f浮动;
字符p;
int arr [3];
};
值为20. 浮点数占4个字节,到char p的偏移量为4,p占1个字节,到int arr [3],偏移量为5,它扩展为int的整数倍,而不是int arr [3]是的整数倍,因此偏移量变为8而不是12. 结果是8 + 12 = 20,这是最大成员float或int大小的整数倍.
测试环境: vc ++ 6.0
测试代码:
//#ifndef __cplusplus
//#endif
#include
#include“ stdio.h”
#include
使用命名空间标准;
struct stru_empty
{
};
struct stru1
{
int a; //起始地址为0
字符b; //起始地址为4
int c; //起始地址为8
};
struct stru2
{
int i; //起始地址为0
短m; //起始地址为4
};
struct stru3
{
char i; //起始地址为0
int m; //起始地址为4
char n; //起始地址为8
};
struct stru4
{

char i; //起始地址为0
char n; //起始地址为1
int m; //起始地址为4
};
struct stru5
{
简短的我;
结构
{
字符c;
int j;
} ss;
int k;
};
struct stru6
{
char i;
结构
{
字符c;
int j;
} tt;
字符a;
字符b;
char d;
字符e;
int f;
};
struct stru7
{
char i;
结构
{
字符c;
// int j;
} tt;
字符a;
字符b;

char d;
字符e;
int f;
};
结构数组
{
f浮动;
字符p;
int arr [3];
};
int main()
{
structstru6 st6;
structstru7 st7;
结构数组ar;
printf(“ sizof(char)=%d \ n”,sizeof(char));
printf(“ sizof(int)=%d \ n”,sizeof(int));
printf(“ sizof(short int)=%d \ n”,sizeof(short int));
printf(“ sizof(long int)=%d \ n”,sizeof(long int));
printf(“ sizof(long)=%d \ n”,sizeof(long));
printf(“ sizof(float)=%d \ n \ n”,sizeof(float));
printf(“ sizof(stru_empty)=%d \ n”,sizeof(stru_empty));
printf(“ sizof(stru1)=%d \ n \ n”,sizeof(stru1));
printf(“ sizof(stru2)=%d \ n \ n”,sizeof(stru2));
printf(“ sizof(stru3)=%d \ n \ n”,sizeof(stru3));
printf(“ sizof(stru4)=%d \ n \ n”,sizeof(stru4));
printf(“ sizof(stru5)=%d \ n \ n”,sizeof(stru5));
printf(“ sizof(stru6)=%d \ n”,sizeof(stru6));
printf(“ sizof(stru6.tt)=%d \ n”,sizeof(st6.tt));
printf(“ stru6.i的地址=%d \ n”,&st6.i);
printf(“ stru6.a的地址=%d \ n \ n”,&st6.a);
printf(“ sizof(stru7)=%d \ n”,sizeof(stru7));
printf(“ sizof(stru7)=%d \ n”,sizeof(st7.tt));
printf(“ stru7.i的地址=%d \ n”,&st7.i);
printf(“ stru7.a的地址=%d \ n \ n”,&st7.a);
printf(“ sizof(ar)=%d \ n”,sizeof(ar));
printf(“ sizof(ar.f)=%d \ n”,sizeof(ar.f));
printf(“ sizof(ar.arr)=%d \ n”,sizeof(ar.arr));
返回0;
}
运行结果:
————————————————
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-287417-1.html
_
好可怜的学生党
把叙利亚难民危机与光棍危机进行对冲