目录

1.什么是结构体?

2.为什么要有结构体?

3.结构体的声明,定义,初始化

1.简单的结构体创建变量

2.加 typedef 作用是:类型重命名

3.结构体中的结构体

4.结构体的传址,传值

5.结构体的传址,传值 哪种好?

创作不易,如果本篇博客对您有一定的帮助,大家记得留言+点赞哦。


1.什么是结构体?

就是用户自己定义的一种类型,你可以自己去定义这个类型的一系列属性。比较常用的自定义类型有:结构体, 联合体,枚举

2.为什么要有结构体?

由于在实际问题中,一组数据往往有很多种不同的数据类型。例如,登记学生的信息,可能需要用到 char型的姓名,int型或 char型的学号,int型的年龄,char型的性别,float型的成绩。又例如,对于记录一本书,需要 char型的书名,char型的作者名,float型的价格。在这些情况下,使用简单的基本数据类型甚至是数组都是很困难的。而有了结构体,我们可以借助它可以有效的解决这个问题。
结构体本质上还是一种数据类型,但它可以包括若干个“成员”,每个成员的类型可以相同也可以不同,也可以是基本数据类型或者又是一个构造类型。

结构体的优点:结构体不仅可以记录不同类型的数据,而且使得数据结构是“高内聚,低耦合”的,更利于程序的阅读理解和移植,而且结构体的存储方式可以提高CPU对内存的访问速度。

3.结构体的声明,定义,初始化

1.简单的结构体创建变量

struct stu { //结构体声明注:struct stu 是【结构体类型名】char name[20];//s2,s3 是【变量名】int age;//name[],age,sex[] 是【结构体成员名】char sex[5];}s2,s3; //此处可创建变量--为全局变量 ;冒号不要忘记struct stu s4;// 此处也可创建变量--为全局变量 int main() {struct stu s1;//--局部变量return 0;}

struct stu 是【结构体类型名】

s2,s3, s4是【变量名】且是全局变量s1是局部变量

name[],age,sex[] 是【结构体成员名】

2.加 typedef 作用是:类型重命名

typedef struct stu { //这里的 S(大括号后跟的) 是 【结构体变量】char name[20];int age;char sex[5];}S;// 给【struct stu】整体起了个名【S】int main() {S s1; //即S 等价于 struct stureturn 0;}

3.结构体中的结构体

//初始化及打印struct A {char name[20];int age;char sex[5];};struct B {char dept[20];struct A a; //在结构体中定义结构体变量char sno[10];};int main() {struct A aa = {"赵亦",20,"男"}; //初始化struct B b = { "计算机",{"赵亦",20,"男"},"001"}; //初始化printf("%s %d %s\n",aa.name,aa.age,aa.sex);printf("%s %s %d %s %s",b.dept,b.a.name,b.a.age,b.a.sex,b.sno);return 0;}

4.结构体的传址,传值

struct st {char name[20];int age;char sex[5];};void set_st(struct st s) {//传值 不能改变原有的s.age = 20;strcpy(s.name,"赵亦");strcpy(s.sex,"男");//s.name = "赵亦"; //这种形式是错误的name,sex 为数组名,指针 不能为左值//s.sex = "男";}void set_stt(struct st *ss) {//传址 可改变原有的ss->age = 20;strcpy(ss->name, "赵亦");strcpy(ss->sex,"男");//printf("%s %d %s", ss->name, ss->age, ss->sex);//或者下面形式【即ss->age 等价于 (*ss).age】//(*ss).age = 20;//strcpy((*ss).name, "赵亦");//strcpy((*ss).sex, "男");//printf("%s %d %s", (*ss).name,(*ss).age,(*ss).sex);}void print_st(struct st s) {printf("%s %d %s\n",s.name,s.age,s.sex );}int main() {struct st s = { 0 }; //初始化结构体struct st ss = { 0 };set_st(s);//结构体传值print_st(s);set_stt(&ss);//结构体传址print_st(ss);return 0;}

5.结构体的传址,传值 哪种好?

在一般情况下,我们都是会去传址的,不仅因为它快,高效。而是如果传值,函数在传参的时候是需要压栈的,若此时结构体过大,参数压栈时系统的开销也就较大,会导致性能的下降。

并且传址不管你结构体有多大,我传递的地址永远是4/8个字节,开销远比传值小得多。故首选传址。

那有时候我们传值的目的是只使用访问而不改变原有的数据。如果都传址,万一不小心改变数据该怎么办。这里根据自己的使用场景,可以加const,从而防止数据改变。

struct st {char name[20];int age;char sex[5];};void set_stt(const structst* ss) {//加const传址 原数据不能被改变//ss->age = 20;会报错//(*ss).age = 20; 会报错printf("%s %d %s", ss->name, ss->age, ss->sex);}int main() {struct st ss = { 0 };set_stt(&ss);return 0;}

创作不易,如果本篇博客对您有一定的帮助,大家记得留言+点赞哦。