目录
前言
作者写本篇文章旨在复习自己所学知识,并把我在这个过程中遇到的困难的将解决方法和心得分享给大家。由于作者本人还是一个刚入门的菜鸟,不可避免的会出现一些错误和观点片面的地方,非常感谢读者指正!希望大家能一同进步,成为大牛,拿到好offer。
本系列(初识C语言初阶),是为了与大家分享自己学习经验和所遇到的困难,同大家一起进步。
日志
-
- 2024.5.17首发
1.结构体的声明
我们说编程就是用来描述现实生活的问题的,C语言的数据类型就是用来描述现实事物的信息的。例如姓名、性别可以用char描述,年龄可以用int描述,但是人呢?怎么描述一个人?还有书本这些,好像单纯的内置类型并不能直接描述。就出现了结构体
C语言专门用结构体来描述这种复杂对象。
1.1结构体的基础知识
结构体是一些值的集合,这些值称为成员变量。结构体的每个成员可以是不同类型的变量。
1.2结构体的声明
- 创建结构体变量
struct tag
{
member - list;
}variable - list;
比如现在要描述一个复杂对象学生
struct Stu
{
char name[20];//姓名
int age;//年龄
char sex[5];//性别
};
-
当有了类型之后,我们就可以以此创建结构体变量了。这里先不初始化s1
结构体类型的创建,就相当于设计图,而s1则是拿设计图盖的房子
-
成员列表
-
变量列表
我们已经创建好了结构体变量s1,也可以在这里创建结构体变量
而且在变量列表这里创建的结构体变量s2,s3,s4,是在大括号外面的,相当于全局变量。s1则是只能在main里使用的局部变量
当然也可以不在这里创建,根据自己的需求来定 -
typedef结构体
此时此刻的Stu可不是变量列表了,而是新名字。在C语言中,结构体类型如果没有重命名,创建结构体变量的时候struct都不能省略
1.3结构体成员的类型
结构体成员的类型可以是变量、数组、指针,甚至是其他的结构体等等
1.4结构体变量的定义和初始化
有了结构体类型就可以按照我们刚刚说的方法创建结构体变量
类型 变量名 = 值;
1.4.1结构体变量的定义
结构体变量的创建有三种方式
只不过s1创建的方式是局部变量,而s2和s3在代码块外头,是全局变量
1.4.2结构体的初始化
在创建结构体变量的时候给值,就是对结构体变量的初始化
-
按顺序初始化结构体变量
我们说数组是一组相同类型的集合,数组的初始化用{}括起来。而结构体也是集合,所以也要用大括号括起来。
-
不按顺序初始化结构体变量
不能直接这样不按顺序初始化结构体变量s1
要有适当的方式才能不按顺序初始化
通过.操作符找到里面的成员就可以不按顺序初始化了 -
初始化好s3之后,我们来打印他里面的值看看是不是真的初始化成功了。这就涉及到下面结构体成员的访问
我们就按顺序打印一下吧
.结构体成员操作符就像打开文件夹一样,打开结构体,找到里面的成员 -
结构体A里面还套了一个结构体S,可以像二维数组一样初始化,大括号里套一个大括号
也可以打印
2.结构体成员的访问
结构体成员可以通过.和->访问
2.1(.)结构体成员
.结构体成员操作符就能打开结构体,找到里面的数据
2.2(->)结构体指针
- 先用结构体描述一个学生,创建一个s1,初始值给0
- 写一个函数设置一下s1里面的值
这里设置学生姓名出了问题。因为name是个数组,数组是地址啊,不可能把地址修改了。要用到之前讲过的strcpy函数(string.h)
- 这个时候写一个打印函数,去打印学生s1的信息就会发现压根没改
所以我们要把地址传进去
- 这个时候我们说形参t是指向了s1的指针,可以直接指向s1的空间啊。再对t解引用找到s1的空间,也就是先解引用找到变量,再
结构体变量.结构体成员
,不是多此一举吗?所以可以直接通过结构体指针->结构体成员
来访问
3.结构体传参
直接上代码
这个时候我们讨论说哪个print函数好?
答案其实是print2,因为print1传的是传结构体变量本身,而print2传的是结构体变量的地址
我们在函数栈帧的创建和销毁那节课讲过,函数传参的时候,如果传的是变本身。那么形参将是实参的一份临时拷贝,形参将在栈上压栈进去开辟好的空间。
如果传递一个结构体变量的时候,结构体过大(就像上面的S,里面创建了一个非常大的数组),在形参拷贝实参的时候,又要往栈区压进去一块非常大的空间,这就使得参数压栈的的系统开销比较大,所以会导致性能的下降。
因此传址比传址好
4.总结
还没想好