C语言零基础入门-结构体-02
这节课的主要内容:
1,结构体类型的数组。
2,指针对结构体的操作。
0. 概述
上一节课讲述了结构体的定义、初始化、以及简单的使用。
但是既然结构体是一个重新定义出的数据类型,那么他就也能够像C语言中自带的数据类型一样(int、float等等),可以进行数组、指针的操作。
如下:
1. 结构体类型的数组
其实结构体数组很简单,就和使用普通的数据类型一样。
1.1 int类型数组示例
int数据类型定义的数组:
这个数组程序大家应该很熟悉了吧。
#includevoid main(){ int a[3] = {1,2,3}; printf("原始数据:\n"); for(int i=0;i<3;i++){ printf("%d ",a[i]); } printf("\n"); a[1] = 69; printf("修改之后的数据:\n"); for(i=0;i<3;i++){ printf("%d ",a[i]); } printf("\n");}
很简单的一个数组例子,先定义了一个具有三个元素的int类型的数组。然后在打印一下这三个元素,最后修改第二个数据之后在打印。
结果:
1.2 结构体数组示例
在这里同样实现上述int数组的功能。
但是这里需要注意的一点就是,这里使用的结构体是自定义的数据类型,所以使用之前别忘记了定义。
结构体类型的数组:
#include #include // 先定义出结构体,并且给这个结构体起一个别名为 Stu。// 此时Stu就与int同样是一个数据类型了,只是存放的数据不一样而已。typedef struct Student{ char name[30]; int id; int gender; int age;}Stu;void main(){ // 这里使用自定义数据类型Stu定义出一个含有三个数据的数组。 // 数组中的每个元素都是一个Stu数据类型。 Stu stu[3] = { {"Zhang",1001,1,22},{"Wang",1002,0,21},{"Li",1003,1,23} } ; printf("原始数据:\n"); // 首先使用循环输出一下每个Stu类型的数据。 // stu[i]可以索引到数组中的第i个结构体。 // stu[i].name可以索引到数组中第i个结构体的name属性。 for(int i=0;i<3;i++){ printf("%s %d %d %d\n",stu[i].name,stu[i].id,stu[i].gender,stu[i].age); } printf("\n"); // 这里是修改数组中第2个结构体的数据。 // 使用stu[1]索引到数组中的第2个结构体。 // 使用stu[1].name索引到数组中的第2个结构体的name属性。 strcpy(stu[1].name,"XiaoJie"); stu[1].id = 007; stu[1].gender = 1; stu[1].age = 55; // 修改数据 printf("修改之后的数据:\n"); // 修改之后再次输出一下。 for(i=0;i<3;i++){ printf("%s %d %d %d\n",stu[i].name,stu[i].id,stu[i].gender,stu[i].age); }}
程序解读见代码中的注释。
结果:
2. 结构体指针
如果你之前的基础还不错,那么从介绍完结构体的定义与使用方式之后。
接下来的一些数组,指针操作结构体你都不应该感觉难的。
因为结构体就是定义了一个新的类似于int的数据类型而已,所以还是参考之前的int这些熟悉的数据类型怎么操作数组,指针即可啊。
2.1 指向结构体的指针
同样,这里用实际例子给出操作,代码一看就会很明了的。
值得一提的是:当使用指针操作结构体的时候,要将点换成箭头。(具体看代码)
程序:
#include #include // 结构体的定义,不用再赘述了typedef struct Student{ char name[30]; int id; int gender; int age;}Stu;// 相当于有一个新的数据类型Stu诞生了void main(){ // 首先定义出一个普通的Stu类型的数据变量stu。 Stu stu; // 在定义出一个指针类型的变量p,p的数据类型还是Stu。 Stu *p; // 将stu的地址给p,这样p就会指向stu了。 p = &stu; // 到这里有没有发现,与之前学习的int指针很类似啊。 // 然后使用普通变量stu进行数据的初始化。 strcpy(stu.name,"XiaoJie"); stu.id = 007; // 这里使用指针p对结构体进行赋值。 // 指针操作结构体要将点换成箭头 p->gender = 1; p->age = 55; // 在这里使用stu输出一下 printf("普通输出:%s %d %d %d \n",stu.name,stu.id,stu.gender,stu.age); // 然后在使用指针p输出一下。 // (这里需要注意的一点,当使用指针操作结构体的时候要将 '.'' 换成 '->') printf("指针输出:%s %d %d %d \n",p->name,p->id,p->gender,p->age);}
看整个操作之后就会发现与int的指针操作是一样的。
结果:
2.2 指向结构体数组的指针
老样子,给出代码直接解释吧。
程序:
#include #include // 结构体的定义,不用再赘述了// 相当于有一个新的数据类型Stu诞生了typedef struct Student{ char name[30]; int id; int gender; int age;}Stu;void main(){ // 一个普通的Stu类型的变量stu。 Stu stu[3]; // 一个Stu数据类型的指针变量。 Stu *p; // 将p指向stu数组的第一个元素(但是这里数组的元素是一个整体,具体看后边的内存分析图)。 p = &stu[0]; // 先给数组中的每一个结构体赋初始值。 // 因为循环赋值,所以我这里的三个name都是相同的。 // 其他元素都是在基础数据上 加了一个数 i 的值。 for(int i=0;i<3;i++){ // 可以使用普通数据stu通过下边索引到数组中的每一个结构体。 strcpy(stu[i].name,"XiaoJie"); stu[i].id = 007+i; // 也可以通过指针获取到第i个结构体的首地址,然后在获取结构体内部的数据。(至于为什么+i,看后边的内存分析图) (p+i)->gender = 1; (p+i)->age = 55+i; } // 输出一下 for(i=0;i<3;i++){ printf("普通输出:%s %d %d %d \n",stu[i].name,stu[i].id,stu[i].gender,stu[i].age); printf("指针输出:%s %d %d %d \n",(p+i)->name,(p+i)->id,(p+i)->gender,(p+i)->age); }}
重点来了:
为什么 p+i 可以得到数组中每个结构体的首地址呢?
先看一下结构体定义的时候的地址图:
数组地址申请的时候内存中是这个样子的,会以每一个结构体的长度为基本单位,申请三个结构体的空间。
比如:一个结构体占据25字节的数据,那么定义三个结构体数组的时候就会申请 25*3=75 字节的数据。
指针指向结构体数组的首部的时候。
指针指向结构体数组首部的时候,指针是指向结构体数组的第一个元素。
结构体数组指针移动的时候:指针移动的时候,移动的基本单位长度是结构体的长度。
如图所示:结构体指针+1的时候,指针是以结构体大小为基本单位进行移动。
所以当指针p+1的时候,指针将指向p所指向的结构体 的 后一个结构体的首部,而不是进入到p所指向的结构体的内部。
3. 结束
结构体的基本知识也就结束了,下一节讲完文件,C语言就算是结束了。
大家加油!!!