C语言初阶——8结构体


前言

作者写本篇文章旨在复习自己所学知识,并把我在这个过程中遇到的困难的将解决方法和心得分享给大家。由于作者本人还是一个刚入门的菜鸟,不可避免的会出现一些错误和观点片面的地方,非常感谢读者指正!希望大家能一同进步,成为大牛,拿到好offer。
本系列(初识C语言初阶),是为了与大家分享自己学习经验和所遇到的困难,同大家一起进步。


日志

    1. 2024.5.17首发

1.结构体的声明

我们说编程就是用来描述现实生活的问题的,C语言的数据类型就是用来描述现实事物的信息的。例如姓名、性别可以用char描述,年龄可以用int描述,但是人呢?怎么描述一个人?还有书本这些,好像单纯的内置类型并不能直接描述。就出现了结构体
在这里插入图片描述
C语言专门用结构体来描述这种复杂对象。

1.1结构体的基础知识

结构体是一些值的集合,这些值称为成员变量。结构体的每个成员可以是不同类型的变量。
在这里插入图片描述

1.2结构体的声明

  1. 创建结构体变量
struct tag
{
	member - list;
}variable - list;

比如现在要描述一个复杂对象学生

struct Stu
{
	char name[20];//姓名
	int age;//年龄
	char sex[5];//性别
};

在这里插入图片描述

  1. 当有了类型之后,我们就可以以此创建结构体变量了。这里先不初始化s1
    在这里插入图片描述
    结构体类型的创建,就相当于设计图,而s1则是拿设计图盖的房子
    在这里插入图片描述

  2. 成员列表
    在这里插入图片描述

  3. 变量列表
    我们已经创建好了结构体变量s1,也可以在这里创建结构体变量
    在这里插入图片描述
    而且在变量列表这里创建的结构体变量s2,s3,s4,是在大括号外面的,相当于全局变量。s1则是只能在main里使用的局部变量
    当然也可以不在这里创建,根据自己的需求来定

  4. typedef结构体
    在这里插入图片描述
    此时此刻的Stu可不是变量列表了,而是新名字。在C语言中,结构体类型如果没有重命名,创建结构体变量的时候struct都不能省略

1.3结构体成员的类型

结构体成员的类型可以是变量、数组、指针,甚至是其他的结构体等等
在这里插入图片描述

1.4结构体变量的定义和初始化

有了结构体类型就可以按照我们刚刚说的方法创建结构体变量
类型 变量名 = 值;

1.4.1结构体变量的定义

结构体变量的创建有三种方式
在这里插入图片描述

只不过s1创建的方式是局部变量,而s2和s3在代码块外头,是全局变量

1.4.2结构体的初始化

在创建结构体变量的时候给值,就是对结构体变量的初始化

  1. 按顺序初始化结构体变量
    在这里插入图片描述
    我们说数组是一组相同类型的集合,数组的初始化用{}括起来。而结构体也是集合,所以也要用大括号括起来。
    在这里插入图片描述

  2. 不按顺序初始化结构体变量
    不能直接这样不按顺序初始化结构体变量s1
    在这里插入图片描述
    要有适当的方式才能不按顺序初始化
    在这里插入图片描述
    通过.操作符找到里面的成员就可以不按顺序初始化了

  3. 初始化好s3之后,我们来打印他里面的值看看是不是真的初始化成功了。这就涉及到下面结构体成员的访问
    我们就按顺序打印一下吧
    在这里插入图片描述
    .结构体成员操作符就像打开文件夹一样,打开结构体,找到里面的成员

  4. 结构体A里面还套了一个结构体S,可以像二维数组一样初始化,大括号里套一个大括号
    在这里插入图片描述
    也可以打印
    在这里插入图片描述

2.结构体成员的访问

结构体成员可以通过.和->访问

2.1(.)结构体成员

.结构体成员操作符就能打开结构体,找到里面的数据
在这里插入图片描述

2.2(->)结构体指针

  1. 先用结构体描述一个学生,创建一个s1,初始值给0
    在这里插入图片描述
  2. 写一个函数设置一下s1里面的值
    在这里插入图片描述
    这里设置学生姓名出了问题。因为name是个数组,数组是地址啊,不可能把地址修改了。要用到之前讲过的strcpy函数(string.h)
    在这里插入图片描述
  3. 这个时候写一个打印函数,去打印学生s1的信息就会发现压根没改
    在这里插入图片描述
    所以我们要把地址传进去
    在这里插入图片描述
  4. 这个时候我们说形参t是指向了s1的指针,可以直接指向s1的空间啊。再对t解引用找到s1的空间,也就是先解引用找到变量,再结构体变量.结构体成员,不是多此一举吗?所以可以直接通过结构体指针->结构体成员来访问
    在这里插入图片描述

3.结构体传参

直接上代码
在这里插入图片描述
这个时候我们讨论说哪个print函数好?
答案其实是print2,因为print1传的是传结构体变量本身,而print2传的是结构体变量的地址
我们在函数栈帧的创建和销毁那节课讲过,函数传参的时候,如果传的是变本身。那么形参将是实参的一份临时拷贝,形参将在栈上压栈进去开辟好的空间。
如果传递一个结构体变量的时候,结构体过大(就像上面的S,里面创建了一个非常大的数组),在形参拷贝实参的时候,又要往栈区压进去一块非常大的空间,这就使得参数压栈的的系统开销比较大,所以会导致性能的下降。
因此传址比传址好

4.总结

还没想好

  • 24
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值