目录
前言
Hello,小伙伴们,大家好,咱们又见面了,今天给各位小伙伴们带来的是C语言中结构体这个部分,很多小伙伴们就会很好奇,为什么会有结构体,结构体好像不还是一些变量吗?但是我们想一想有一些变量无法用一个变量就可以包括他的属性,例如学生(有姓名,年龄,性别,班级,学号等等),书籍(有书名,书号,书价,作者,出版社等等),这样子很多无法一个变量说明的事物,我们便采用结构体。
一. 结构体的声明
1.1 什么叫结构体?
结构体是由一批数据组合而成的结构型数据。组成结构型数据的每个数据称为结构型数据的“成员”,其描述了一块内存区间的大小及解释意义。
结构体是一些值的集合,这些值是对于一个成员的属性,这些值也被称为成员变量,结构中的每个成员的成员变量,并不需要是相同类型,每个成员变量可以是不同的类型。
1.2 结构的声明
struct tag //tag表示定义的结构名
{
member-list //成员变量
}variable-list; //可以定义结构体变量
这样子把公式写出来,大家肯定理解的并不是很透彻,下面就举例理解:
struct Student
{
char name[10];//姓名
int age;//年龄
char number[20];//学号
float grade;//成绩
char sex[10];//性别
}Student1;
1.3 结构成员的类型
结构成员的类型也就是成员变量,我们可以发现可以是整型,浮点型,也可以是数组,其实甚至可以是指针也可以是另一个结构体,是不是非常的不可思议。
1.4 结构体变量的定义和初始化
既然我们已经知晓结构体类型,那想要定义结构体变量就变得非常的简单。
struct Point
{
int x;
int y;
}p1; //声明类型的同时定义变量p1
struct Point p2; //定义结构体变量p2
struct Point p3 = { x, y };
struct Stu //结构体类型声明
{
char name[15];//名字
int age; //年龄
};
struct Stu student1 = { "zhangsan", 20 };//将结构体中的成员变量初始化
struct Node
{
int data;
struct Point p;
struct Node* next;//结构体嵌套使用
}n1 = { 10, {4,5}, NULL }; //结构体嵌套初始化
struct Node n2 = { 20, {5, 6}, NULL };//结构体嵌套初始化
我们可以看到对于结构体的定义有两个地方,一个就是上面variable-list这个地方,第二个就是在外部,使用struct 结构体 结果变量名。
二. 结构体成员的访问
结构体变量对于成员变量的访问我们就要用到在操作符篇中提及的点操作符(.)来实现的,结构体的关系如下图:
那这样我们可以知晓student结构变量中包含有name和age两个成员变量,那我们应该如何访问这两个成员变量呢?
struct Stu
{
char name[20];
int age;
};
struct Stu student={"zhangxx",20};
student.age = 18;
我们采取.来访问age成员。
但是有的时候我们的结构体里面并不是一个变量,而是一个指针,那我们又该如何访问成员呢?
struct Stu
{
char name[20];
int age;
};
void print(struct Stu* ps)
{
printf("name = %s age = %d\n", (*ps).name, (*ps).age);
//使用结构体指针访问指向对象的成员
printf("name = %s age = %d\n", ps->name, ps->age);
}
int main()
{
struct Stu s = {"zhangsan", 20};
print(&s);//结构体地址传参
return 0;
}
我们可以将传入的地址解引用从而来访问结构体中的成员变量。
三. 结构体传参
给大家举个例子:
struct S
{
int data[1000];
int num;
};
struct S s = {{1,2,3,4}, 1000};
//结构体变量传参
void print1(struct S s)
{
printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
printf("%d\n", ps->num);
}
int main()
{
print1(s); //传值传参
print2(&s); //传址传参
return 0;
}
这就跟我们在函数篇中所讲的传址输入和传值输入,printf1函数和print2函数实质上打出来的结果是没有差异的,不过依然还是传址传参更好一点,原因并不是跟函数篇一样,原因就是:
函数传参的时候,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的 下降。
所以我们在对于结构体传参的时候选择采用传入结构体的地址。
到这里结构体的基础内容也就讲完了,不知道大家学会了最基础的结构体没有,如果没有也没有关系,我们后面还会对于结构体更加深入的讲解,其中班级通讯录等文档都是需要使用结构体来实现,那今天就到此为止了,各位小伙伴们,咱们下期再见!