结构体struct一种用户可以自定义的数据类型,它允许存储不同类型的数据项,存储的数据项被称为struct成员。
1、结构体的语法:
struct tag //struct tag,更清晰规范一般会写上
{
char member1;//struct members,可以为空
int membe2;
char member3;
}[structure variables,一个或多个结构体变量,多个变量由逗号隔开];
一般结构体中struct tag、struct member、structure variables三者至少有两个。其中只有struct member和structure variables的话结构体变量不能定义新的结构体变量。
结构体变量也是变量,可以在定义结构体时初始化数据:
#include <stdio.h>
struct staff //struct tag
{
char name[15];
int age;
char unit[10];
float personal_tax;
}staff0 = {"Ann","30","IT","100.95"};
int main()
{
printf("name: %s\n age: %d\n unit: %s\n personal_tax: %f\n",staff0.name,staff0.age,staff0.unit,staff0.personal_tax);
}
gcc编译执行后结果如下:
2、访问结构体成员并赋值
(1)使用结构体名进行访问赋值
#include <stdio.h>
struct staff //struct tag
{
char name[10];
int age;
char unit[10];
float personal_tax;
};
int main()
{
struct staff staf0, staf1;
strcpy(staf0.name,"Anna");
staf0.age = 30;
strcpy(staf0.unit,"IT");
staf0.personal_tax = 100.95;
staf1 = (struct staff){"Bob",29,"Sale",105.8};
printf("staf0 name: %s\n staf0 age: %d\n staf0 unit: %s\nstaf0 personal_tax: %f\n",staf0.name,staf0.age,staf0.unit,staf0.personal_tax);
printf("staf1 name: %s\n staf1 age: %d\n staf1 unit: %s\n staf1 personal_tax: %f\n",staf1.name,staf1.age,staf1.unit,staf1.personal_tax);
}
gcc编译执行后结果如下:
(2)使用指针进行访问赋值
#include <stdio.h>
struct staff //struct tag
{
char name[10];
int age;
char unit[10];
float personal_tax;
}staf0 = {"Anna",30,"IT",100.95};//在:前面填写 *pstaff = &staf0效果一样
int main()
{
struct staff *pstaff = &staf0;
printf("staf0 name: %s\nstaf0 age: %d\nstaf0 unit: %s\nstaf0 personal_tax: %f\n",pstaff->name,pstaff->age,pstaff->unit,pstaff->personal_tax);
//printf("staf0 name: %s\nstaf0 age: %d\nstaf0 unit: %s\nstaf0 personal_tax: %f\n",(*pstaff).name,(*pstaff)age,(*pstaff)unit,(*pstaff)personal_tax);效果和上面的printf的效果一样
}
gcc编译执行后结果如下:
3、结构体大小和指针大小与地址值的获取
上面的代码printf下面添加另外三个printf:
printf("struct staff size:%d\n", sizeof(struct staff));
printf("pstaff size:%d\n", sizeof(pstaff));
printf("pstaff:%x\n",pstaff);
gcc编译执行后结果如下:
4、结构体占内存的字节数–对齐原则
#include <stdio.h>
struct staff //struct tag
{
char name[10]; //10个byte
int age; //4个byte
char unit[10]; //10个byte
float personal_tax; //4个byte
}staf0 = {"Anna",30,"IT",100.95};
int main()
{
struct staff *pstaff = &staf0;
printf("staf0 name: %s\nstaf0 age: %d\nstaf0 unit: %s\nstaf0 personal_tax: %f\n",pstaff->name,pstaff->age,pstaff->unit,pstaff->personal_tax);
printf("struct staff size:%d\n", sizeof(struct staff));
}
理论上,char name[10]占内存10个byte即可,但是struct成员占内存最大的类型是int和float都是4个byte,所以char name[10]要占内存12个byte(4的倍数),其中有2个byte是空出来的,接着int age占4个byte,后面char unit[10]也占内存12个byte,也有2个byte空出来,最后是float personal_tax占4个byte,综上加起来就是12+4+12+4 = 32byte。这就是结构体struct的对齐原则,所有成员占字节数必须是最大成员的倍数。
我们调整一下结构体staff中成员顺序,将char unit与int age交换位置:
struct staff //struct tag
{
char name[10]; //10个byte
char unit[10]; //10个byte
int age; //4个byte
float personal_tax; //4个byte
}staf0 = {"Anna","IT",30,100.95};//有初始值的记得初始值对应的也要交换位置。
其他的都保持不变,编译执行结果:
两个char 均占10个byte,加起来是20byte正好是4的倍数,后面再加上int(4个byte)和float(4个byte)总和是28byte。