【C语言】-- 结构体篇

目录

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 stu

	return 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 struct  st  * 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;
}

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

猜你喜欢

转载自blog.csdn.net/m0_73381672/article/details/131316248