✨✨小新课堂开课了,欢迎欢迎~✨✨
🎈🎈养成好习惯,先赞后看哦~🎈🎈
所属专栏:http://t.csdnimg.cn/Oytke
小新的主页:编程版小新-CSDN博客
在C语言中有内置类型(C语言本身就支持的类型),比如char ,short ,int ,long ,long long ,float,double ,long double。但仅有内置类型是不够的,假设我想描述学生,描述⼀本书,这时单⼀的内置类型是不行的。描述⼀个学生需要 名字、年龄、学号、身高、体重等;描述⼀本书需要作者、出版社、定价等。C语言为了解决这个问题,增加了结构体这种自定义的数据类型,让程序员可以自己创造适合的类型。
自定义类型又分为:结构体struct,枚举enum,联合体union。
今天小新要分享的是结构体。
结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量,如: 标量、数组、指针,甚至是其他结构体。
1.结构体的声明
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//我们用结构体描述一个学生
struct stu//tag 标签
{
char str[20];
int age;
char sex; //number-list 成员列表
float height;
float weight;
}a1, a2;//variable-list 变量列表,放在这里的变量是全局变量
struct stu a5;//全局变量
int main()
{
struct stu a3;
struct stu a4;//局部变量
return 0;
}
2.结构体的初始化
struct stu
{
char str[20];
int age;
char sex;
float height;
float weight;
};//分号不要忘记哦
int main()
{
struct stu a1 = { "yeyuanxinzizhu",5,"male",1.06,22.8 };//按照成员列表的顺序进行初始化
struct stu a2 = { .height = 1.06,.age = 5,.sex = "male",.str = "yeyuanxinzizhu",.weight = 22.8 };//可以打乱顺序初始化
printf("%d %s\n",a1.age,a1.sex);
return 0;
}
想要不按照成员列表的顺序初始化,就可以使用结构体的直接访问操作符(.)
使用方式为:结构体变量名.结构体成员
既然说到了结构体的直接访问操作符,我们就再来介绍一个操作符->,这是结构体的间接访问操作符,有时我们得到不是结构体变量,而是结构体指针,这是我们就可以使用间接访问操作符,下面上才艺。
#include<stdio.h>
struct stu
{
int i;
int j;
};
int main()
{
struct stu a1 = { 8,9 };
struct stu* a2 = &a1;
//a2->i = 3;
//a2->j = 4;也可以修改他们的值
printf("%d %d\n", a2->i, a2->j);//8 9
return 0;
}
使用方法为:结构体指针->成员名
3.结构体的特殊声明(匿名结构体)
下面小新要介绍匿名结构体的用法及其注意事项啦
匿名结构体就是没有结构体的标签名
这里还有一个易错的地方
#include<stdio.h>
//匿名结构体
struct
{
int a;
float b;
double c;
}s;
struct
{
int a;
float b;
double c;
}*p;
int main()
{
p = &s;
return 0;
}
你觉得上面的代码合法吗???
其实是不合法的,编译器会把上面的两个声明当成完全不同的两个类型,所以是非法的。 匿名的结构体类型,如果没有对结构体类型重命名(typedef)的话,基本上只能使用⼀次。
4.结构体的自引用
大家思考一个问题在结构体内部包含一个和自己类型一样的结构体是否可以?
struct stu
{
int a;
char c;
float f;
struct stu next;
};
如果大家没有头绪的话,小新给大家一个小提示,大家想一想sizeof(struct stu)是多大。
这样的话仔细想想其实是不可以的,struct stu里除了a,c,f,还有一个自己,这个自己里面除了a,c,f外还有下一个自己,下一个自己除了a,c,f外还有下下一个自己……,这样下去就会是一个死循环,肯定是不可以的。
正确的自引用方法是包含一个和自己是同一类型的结构体指针
struct stu
{
int a;
char c;
float f;
struct stu *next;
};
这里还要注意一个点,如果这是一个包含typedef的匿名结构体,也用可能会产生麻烦
typedef struct
{
int a;
char c;
float f;
struct s*next;
}s;
这样是不行的,s是对上面的结构体重命名产生的,而在s产生之前,结构体成员中的结构体指针就已经使用了s。
正确的使用方法是这样的
typedef struct s
{
int a;
char c;
float f;
struct s* next;
}s;
定义结构体不再是匿名结构体,给他一个标签名
今天就介绍到这里, 下一篇我们讲一个很热门的考点,也是相比上面的难一些的知识点,主要是是结构体内存对齐,结构体传参,结构体实现位段。内容很多,小新分成两篇去讲。感谢大家的支持哦。