前言
关于C语言,在指针学习过程中,在学习之余,做了一次总结,写成了一篇详解博客,也向大家分享的我对于指针的见解,我发现将所学的内容写成博客,不仅仅可以使和我一样的初学者们更快的了解相关知识点,还可以让我查缺补漏,弥补自己的短板,让我的基础更加扎实,所以在学完结构体以后,我也将结构体的内容整理成一篇博客,向大家分享。
为什么要学习结构体
当我们需要表达一个数据的时候,我们就需要用到变量,而变量又需要定义一个类型。我们通过之前的学习,知道了C语言中变量类型有:int、double、char、float等等基础类型,还有指针等等。但是如果我们想表达的数据比较复杂,不是一个数据,例如:日期(年、月、日)、学生信息(姓名、性别、年龄等等)、时间(时、分、秒)等等。而我们又想用一个整体来表达这些所有的数据,这个时候我们就需要用到一个自定义变量类型——结构体。
什么是结构体
结构体是C语言中一种重要的数据类型,该数据类型由一组称为成员(或称为域,或称为元素)的不同数据组成,其中每个成员可以具有不同的类型。结构体通常用来表示类型不同但是又相关的若干数据。
注意:结构体是一种数据类型!!!
一、结构体:struct
1、结构体类型的声明
(1)结构体的基础知识
成员变量:结构是一些值的集合,这些值称为成员变量。
结构体的每个成员可以是不同类型的变量。
(2)结构体的声明
结构体的定义如下所示,struct为结构体关键字,tag为结构体的标志,member-list为结构体成员列表,其必须列出其所有成员;variable-list为此结构体声明的变量。
struct tag
{
member-list
}variable-list;
例1:描述一个学生信息
#include<stdio.h>
//声明一个结构体类型
//声明一个学生类型,是想通过学生类型来创建学生变量(对象)
//描述学生:属性·名字+电话+性别+年龄
struct Stu
{
char name[20];//名字
char tele[12];//电话
char sex[5];//性别
int age;//年龄
}s4,s5,s6;//分号不能丢
struct Stu s3;//s3,s4,s5,s6为全局变量
int main()
{
//创建结构体变量
struct Stu s1;
struct Stu s2;
//s1,s2为局部变量
return 0;
}
易错提示:
一定不要忘记结束时的分号!!!
(3)特殊的声明
在声明结构的时候,可以不完全的声明
例2:匿名结构体类型
#include<stdio.h>
struct
{
int a;
char b;
float c;
}x;
struct
{
int a;
char b;
float c;
}* p;
int main()
{
p = &x;//错误 E0513 不能将 "struct <unnamed> *" 类型的值分配到 "struct <unnamed> *" 类型的实体
return 0;
}
上面的两个结构在声明的时候省略了结构体的标志(tag)。(是正确的)
上述代码的问题出现在:p = &x。//这是非法的。
上面的两个匿名结构体虽然各自的成员是一模一样的,但是在编译器看来,它们是两个不同的类型,所以出现了报错(部分编译器是警告)。
2、结构体的自引用
结构体的自引用就是指在结构体内部,包含指向自身类型结构体的指针。
在之前的学习中,我们知道了在函数中可以包含自己(即递归),那么在结构中包含一个类型为该结构体本身的成员是否可以呢?
例3:
#include<stdio.h>
struct Node
{
int data;//4
struct Node n;//4+套娃
};
int main()
{
sizeof(struct Node);
return 0;
}
运行结果:
错误 C2460 “Node::n”: 使用正在定义的“Node”
这是为什么呢?因为n定义中又有n,无限循环,系统无法确定该结构体的长度,会判定定义非法。
切记,结构体自引用,成员定义只能是指针。
例4:正确的自引用
#include<stdio.h>
struct Node
{
int data;//4
struct Node* n;//4/8
};
int main()
{
int a = sizeof(struct Node);
printf("%d", a);
return 0;
}
运行结果为:8(因为博主是32位)
这是为什么呢?因为我们在自引用时把结构的成员定义为指针,又指针的长度是确定的(上一节指针详解中提到过),所以此时结构体的长度也是确定的。
这时候可能有人又有疑问了,我们刚刚学了一种特殊的声明方式——匿名,那在自引用的时候,我们可不可以使用匿名了,就拿例4来举例子,因为这时候,我们使用了匿名结构,所以里边使用“Node* n;”不就好了吗?我们来看看,结构是怎样的:
例5:
#include<stdio.h>
struct
{
int data;
Node* n;
}Node;
int main()
{
int a = sizeof(struct Node);
printf("%d", a);
return 0;
}
运行结果为:一大堆报错
这是为什么呢?因为我们在声明结构体的内部,就使用了Node这个变量,但是我们的编译器是在声