在C语言中struct结构体,其第一身份是作为C语言中的一种数据类型,这和char,int,float,double数据类型在C语言中的身份一样,通过对应的数据类型关键字,我们使用者知道用什么样的数据类型来满足我们的需要。而我们的IDE在编译程序的过程中,可以在经过编译器,链接器后将程序变为可执行.exe文件(就是机器语言)然后通过加载器将已经变为由机器语言表示的程序存到对应大小的内存中,在这个过程中每个数据究竟要占多少内存是根据其数据类型来决定的。注意一点“struct 结构体名”是完整的结构体数据类型的定义如果只有struct关键字,则是无名结构体,是一种限量版的结构体数据类型。
#include<stdio.h> #include<stdlib.h> struct student { char name[10]; float score; }; void main() { struct student st1,st2,st3; system("pause"); }
对于完整的结构体类型定义可以创建的变量根据自己的需求来定,但是对于不完整的无名结构体则只能以一下的方式创建变量
#include<stdio.h> #include<stdlib.h> struct { char name[10]; float score; }s1,s2; void main() { system("pause"); }
无名结构体创建的变量是限量的,因为你不能在创建结构体数据类型声明后直接使用这个不完整的数据类型来定义变量,只能在开始声明结构体数据类型的时候限定发行变量。如上图无名结构体里面的变量s1,s2,这就是限量发行变量。再一个我们还需要注意,在创建结构体数据类型声明的时候我们的存储器是不会给它分配内存,只有当用结构体类型定义变量的时候,才会分配相应的内存。
一个struct结构体存储到内存时究竟占有多少字节的内存呢,接下来我们讨论一下struct结构体的字节对齐机制。由于对于不同的编译器字节对齐机制会有所不同,但都遵循以下四条最基本的原则:
(1)结构体变量占据的内存单元个数应当大于等于其内部所有数据成员占据内存单元数之和。
(2)结构体变量的大小能被其最宽基本数据类型成员的大小整除
(3)结构体变量的每个成员对于结构体首地址的偏移量是成员大小的整数倍
(4)结构体变量的总大小为结构体最宽基本成员类型的整数倍
#include<stdio.h> #include<stdlib.h> struct student { char name[9]; char a; }; struct student1 { char name1[10]; char a1; int b1; }; struct student2 { char name2[9]; int a2; double b2; }; void main() { printf("%d,%d,%d",sizeof(struct student), sizeof(struct student1), sizeof(struct student2)); system("pause"); }
这是我在VS2010里面运行的结果
不同的编译器结果可能不一样,但是都要遵循上面的四个基本原则。