一. 什么是结构体
结构体是用户自定义的一种类型,可以将char,int,double...以及多种函数体放在一起的数据类型。每个结构体由不同的数据类型的成员组成,这些成员类型可以表达各种属性,例如人的姓名,职业,年龄,或者其他你想表示出来的内容。
二. 结构体的定义和使用
结构体是一种数据类型的集合,里面包含了多个数据变量和数组,其类型可以相同也可以不
同,里面的每个数据变量都称为结构体成员。
结构体的表达形式:
//结构体的定义形式
struct + 结构体名称
{
成员列表;
}结构体名称 ;//在声明结构体的同时定义一个结构体变量
例如我编写一个最简单的学生结构体,其表现形式如下:
结构体成员的访问一般采用 “ . ” 访问,例如定义一个结构体变量 struct Student stu; 来表示上图中的结构体。当我们需要访问姓名时 stu.name 可以通过这种形式访问,其他的学号成绩等等也可以采用这种方式去访问。
结构体成员的初始化以及修改:当需要给成员初始化时,还是用上图举例。
struct Student stu1={"张三",18,20240503,100,"陕西省西安市“};//结构体成员有几个括号内的内容就需要填几个且是一一对应的。这行代码表示学生stu1姓名是张三,年龄18,学号
20240503,成绩100,住址是陕西省西安市。
假如我要把成员中的值进行修改该如何操作。对于int整型变量修改时,可以直接使用”.“访问进行修改,而对于char类型的变量进行修改时,则需要通过strcpy函数进行修改:
stu1.age=20;//访问stu1类型中的age成员并将stu1的年龄18岁修改为20岁
strcpy(stu1.name,"李四”)//利用strcpy 函数修改stu1中的char类型name
三. 结构体大小
在常见的数据类型里,char类型占1字节,int类型占了4字节,double类型占据8字节......
由于vs的默认对齐数为8,第一个成员在结构体变量偏移量为0的地址处。这里的对齐数=编译器默认对齐数与该成员大小的较小值。举个例子,如下图代码;
接下来咱们就分析这个内存大小24是如何来的。
首先是a,因为char类型占1字节,所以如图所示a的对齐数为1
接下来考虑的是b,因为b是int类型占4字节,小于默认对齐数,因此他的默认对齐数为4,他则需要对齐到4的整数倍来存储,如图
然后到c,double类型的占8字节,与默认对齐数相等,则需要从8的整数倍开始存储,如图
再到d,还是char类型1字节,小于默认对齐数,无须考虑,可以直接跟在后面对齐,如图
之后是e,short类型的2字节,小于默认对齐数,需要从2的整数倍开始存储,所以需要从18开始存储,如图
最后就是f的long类型的4字节,也是小于默认对齐数8,则从4的整数倍20开始对存储,如图
所以根据上述分析,可以得出总共的内存大小为24字节。其方法也可以计算其他不同的数据类型。
四. 结构体指针
如何定义一个结构体指针。之后再利用指针去访问结构体成员,在下面我将举例说明。
struct Student *p =&stu; //定义指针p指向结构体变量stu
(*p).age = 66; //将结构体成员age修改为66岁。(至于为什么要给*p加括号,因为“.”的优先级是要高于“*”的优先级,如果不加括号就会报错。)
上述的“.”也可以用“->”来代替,注意“-”和“>”不能隔开,要放在一起。
strcpy((*p).name,"李四"); //如果是字符串型的话,还是要调用strcpy函数进行修改。
五. 结构体数组
对于结构体数组的使用,则是在变量成员居多的情况下使用,此时就需要用数组来存储变量;
struct Student
{
char name[10];
int age;
}stu[8];
在上述例子里,成员变量相当于8个学生,此时name如果单单采用char 的话,就只有1个字节的存储空间,所以数组给到了10。