最近对C语言中的结构体分配问题做了一些功课,总结一下,有错误的地方欢迎大家指正。
大家都知道结构体中
char 偏移量必须为sizeof (char)即 1 的整数倍
int 偏移量必须为sizeof (int)即 4 的整数倍
double 偏移量必须为sizeof (bouble)即 8 的整数倍
float 偏移量必须为sizeof (float)即 4 的整数倍
首先对以下结构体进行内存大小输出,sizeof ( struct s ss )
(1)struct s
{
int i;
char ch;
double d;
};
对于这个结构体它的内存大小是多少呢?答案是:16
(2)struct s
{
char ch;
double d;
int i;
};
这个是:24
(3)struct s
{
double d;
int i;
char ch;
};
这个是:16
演示为:
#include<stdio.h>
#include<stdlib.h>
struct s
{
int i;
char ch;
double d;
};
void main()
{
struct s s1;
printf("sizeof(int)=%ld\n",sizeof(s1.i));
printf("sizeof(char)=%ld\n",sizeof(s1.ch));
printf("sizeof(double)=%ld\n",sizeof(s1.d));
printf("sizeof(struct1)=%ld\n",sizeof(s1));
}
#include<stdio.h>
#include<stdlib.h>
struct s
{
char ch;
double d;
int i;
};
void main()
{
struct s s1;
printf("sizeof(char)=%ld\n",sizeof(s1.ch));
printf("sizeof(double)=%ld\n",sizeof(s1.d));
printf("sizeof(int)=%ld\n",sizeof(s1.i));
printf("sizeof(struct1)=%ld\n",sizeof(s1));
}
#include<stdio.h>
#include<stdlib.h>
struct s
{
double d;
int i;
char ch;
};
void main()
{
struct s s1;
printf("sizeof(double)=%ld\n",sizeof(s1.d));
printf("sizeof(int)=%ld\n",sizeof(s1.i));
printf("sizeof(char)=%ld\n",sizeof(s1.ch));
printf("sizeof(struct1)=%ld\n",sizeof(s1));
}
以下图片为结构输出。
居然有不同的结果,很好奇,为什么会出现这些不同的结果,原来是因为在存储过程中,为了提高CPU的存储速度,编译器会对变量的地址做对其处理,C语言中规定结构体的起始地址的偏移量必须是该变量类型所占字节的整数倍,并且整个结构体的字节数必须是该结构体中占用空间最大的类型的字节数的整数倍,不满足以上两个条件的情况下编译器自动补位。因此对以上三个结构体其实际分配情况是:(0表示编译器所补位)
(1)1111 1000 11111111 以此为例,int型数据 i 占4 个字节,char 型数据 ch 占一个字节,此时 ch 的偏移量是4,4是1的整数倍,因此直接分配,double的偏移量是5(即4+1),不是double 所占字节的整数倍,则编译器自动补位直至是double 的整数倍,因此补三位 ,加上double 的 8 位该结构体共有 16 位(即4+1+3+8),(此时因为结构体字节数已经是所占空间最大成员变量double的倍数,之后不再补位)
(2)1 0000000 11111111 1111 0000 可以看到 int 型数据后还补了四位是因为 20(=1+7+8+4)不是所占空间最大成员 double 的整数倍,因此需要补位直至结构体字节数是最大成员double 所占字节的整数倍,因此补四位
(3)11111111 1111 1 000 补三位,同(2)
总结:
对于结构体内存的分配问题主要有以下两点: (1) 各变量存放的起始地址相对于结构体的起始地址的偏移量必须是该变量类型所占字节的整数倍
(2)整个结构体的字节数必须是给结构体中所用空间最大的类型字节数的整数倍