一、结构体 在前面的数组分享中,把同一类型的数据进行保存通过数组,我们可以用数组来表示这个整体,但是数组有个特点:内部的每一个元素都必须是相同类型的数据。那么如何通过一个方式将不同类型的数据进行存储呢? 为此,C语言专门提供了一种构造类型来解决上述问题,这是结构体,它允许内部的元素是不同类型的。 二、结构体的定义 1.先定义结构体类型, 在定义结构体变量 struct student { int age ; char *name; double height; }; struct student sd; 2.定义结构体类型的同时定义结构体变量 struct student2{ int age; char *name; double height; }sd2; sd2.age = 16; sd2.name = “JAMES”; sd2.height = 1.9; 3.定义结构体类型的同时定义结构体变量, 并且省略结构体名称 struct { int age; char *name; double height; }sd3; sd3.age = 17; sd3.name = “james”; sd3.height = 1.88; 定义结构体类型的同时定义结构体变量, 并且省略结构体名称的注意: 弊端: 由于结构体类型没有名称, 所以以后不能使用该结构体类型 优点: 如果结构体类型只需要使用一次, 那么可以使用该方式 三、结构体初始化 1.定义的同时初始化 struct student sd = {18,”james”,1.87}; 2.先定义后初始化(一次性初始化) struct student sd2; sd2 = (struct student){18,”james”,1.98}; 3.先定义再初始化(逐个初始化) struct student sd3; sd3.name = “james”; sd3.age = 18; sd3.height = 1.87; 4.指定将数据赋值给指定的属性 struct student sd4 = {.height = 1.76,.age = 19,.name = “james”}; 四、结构体数组 跟结构体变量一样,结构体数组也有3种定义方式: 方式一: struct Student { char *name; int age; }; struct Student stu[5]; //定义1 方式二: struct Student { char *name; int age; } stu[5]; //定义2 方式三: struct { char *name; int age; } stu[5]; //定义3 结构体数组的初始化: truct { char *name; int age; } stu[2] = { {“Jmes”, 21}, {“JJ”, 30} }; 五、结构体函数 将结构体变量作为函数参数进行传递时,其实传递的是全部成员的值,也是将实参中成员的值一一赋值给对应的形参成员。因此,形参的改变不会影响到实参。相当于拷贝。 // 定义一个结构体 struct Student { int age; }; void test(struct Student stu) { printf(“修改前的形参:%d ”, stu.age); // 修改实参中的age stu.age = 10; printf(“修改后的形参:%d ”, stu.age); } int main(int argc, const char * argv[]) { struct Student stu = {30}; printf(“修改前的实参:%d ”, stu.age); // 调用test函数 test(stu); printf(“修改后的实参:%d ”, stu.age); return 0; }
六、指向结构体的指针 结构体指针变量的定义形式:struct 结构体名称 指针变量名* 有了指向结构体的指针,那么有3种访问结构体成员的方式 结构体变量名.成员名 (*指针变量名).成员名 指针变量名->成员名 int main(int argc, const char * argv[]) { // 定义一个结构体类型 struct Student { char *name; int age; }; // 定义一个结构体变量 struct Student stu = {“MJ”, 27}; // 定义一个指向结构体的指针变量 struct Student *p; // 指向结构体变量stu p = &stu; //这时候可以用3种方式访问结构体的成员 // 方式1:结构体变量名.成员名 printf(“name=%s, age = %d ”, stu.name, stu.age); // 方式2:(*指针变量名).成员名 printf(“name=%s, age = %d ”, (*p).name, (*p).age); // 方式3:指针变量名->成员名 printf(“name=%s, age = %d ”, p->name, p->age); return 0; } 七、结构体如何开辟存储空间 看上去, 结构体分配存储空间是将所有属性占用的存储空间的总和加在一起后再分配 注意: 其实结构体分配存储空间本质上并不是将所有属性占用的存储空间的总和加在一起后再分配 而是会获取结构体类型中占用内存大的属性的大小, 然后取该大小的倍数 特例: 如果剩余的存储空间”不够”存储将要存储的数据, 那么会重新开辟8个字节的存储空间, 并且将需要存储的数据放到新开辟的存储空间中。 如果剩余的存储空间”够”存储将要存储的数据, 那么不会开辟了。 八、枚举 枚举是专门用于表示几种固定类型的取值,枚举的本质是基本数据类型, 是整型。在iOS开发中是非常常用的。 枚举类型定义的格式 enum 枚举类型名称{ 类型1, 类型2, }; 注意:由于枚举类型的本质是整型, 所以枚举类型除了可以接收枚举的固定的取值以外, 还可以接收其它整型的值,枚举的值默认从0开始依次递增。 定义枚举的一般规范: *(1)枚举类型的取值一般以k开头 后面跟上枚举类型的名称 跟上当前取值的含义 (2)和结构体一样, 枚举类型的名称首字母大写* enum Season { kSeasonSpring, kSeasonSummer, kSeasonAutumn, kSeasonWinter };