C语言复合类型之结构(struct)篇(结构指针)

news/2025/1/1 17:58:20/

结构相关知识总结

  • 什么是结构?
  • 结构的声明与简单使用
  • 结构的初始化
  • 结构中成员变量的访问
  • 结构的初始化器
  • 结构数组
      • 结构数组的声明
      • 结构数组的成员标识
  • 结构的嵌套
  • 结构指针
  • 结构作为参数在函数中传递
      • 将结构成员作为参数进行传递
      • 将结构地址(指向结构的指针)作为参数进行传递
      • 将整个结构作为参数进行传递
  • 结构和结构指针的选择

什么是结构?

结构是一种复合类型,一个结构里面存放多种数据类型的元素,相比数组而言,简直爽歪歪不是。它既可以包含不同的数据形式,又可以使得个信息之间保持独立。
此部分非常之重要,不可马虎呀

结构的声明与简单使用

结构的声明并没有创建出实际的数据对象,只是描述了该对象是由什么组成的而已。下图中创建一个结构,结构的标识为book,结构变量为:library
请添加图片描述

上图中,对于结构的创建的结构变量的声明可以合二为一,声明方法与使用方法如下图所示,而且组合之后的使用可以不要结构标记(即下图中的book可以去掉)。如果该结构模板是要多次被使用的,则需要使用结构标识
请添加图片描述

结构的初始化

结构的初始化与数组的初始化别无二致,都是同样的手法。使用花括号将初始化列表括起来进行初始化,各个初始化项之间使用逗号隔开,为了代码的可读性,一行只写一个初始化项。使用初始化时必须要带上结构标识,不能只有结构变量与struct关键词
请添加图片描述

结构中成员变量的访问

使用结构成员运算符——点(.)访问结构中的成员,例如上面的library.uesrIDlibrary.message。值得注意的点是:library是一个结构,但是library.uesrID却相当于是一个int类型的变量,可以像使用其他int类型变量的情况去使用它。
例如:scanf("%d",...)需要一个int类型的值,而library.uesrID正符合要求的话,那么就可以这么写:scanf("%d",&library.uesrID),&比 . 的优先级高

结构的初始化器

C99和C11对结构提供了指定初始化器,使用点运算符和成员名标识特定的元素,这也初始化结构的一种手段。如下图所示,可以按照任意顺序给初始化项进行赋值。
请添加图片描述

结构数组

结构数组的声明

结构数组的声明和其他类型数组的声明类似
struct book library[MAXBKS];library声明成一个具有MAXBKS个元素的数组,数组的每个元素都是一个book类型的结构变量。library[0]是第一个book类型的结构变量,library[1]是第二个book类型的结构变量,以此类推。结构数组示意图如下:

请添加图片描述

结构数组的成员标识

library[0].userID:表示第一个数组元素与userID相关联
library[4].mssage:表示第五个数组元素与message相关联
请添加图片描述

结构的嵌套

嵌套结构即在结构中包含中另一个结构,使用如下图所示,将结构数组与嵌套结构结合在了一起。
请添加图片描述

结构指针

使用结构指针的优点:指向结构的指针通常比结构本身更容易操控;结构作为参数传递的时候传递指针更有效率
和数组不同的是,数组名是数组的地址或者说是数组首元素的地址,即有arr = &arr[0],但结构名不是结构的地址。
请添加图片描述

struct guy * him;声明了一个指向struct guy结构的指针him.上图中那个fellow是一个结构数组,也就是说fellow[0]是一个结构变量,要让him指向fellow[0],可以写为:him = &fellow[0],him + 1 = &fellow[1]

him是一个指针(struct guy类型的),是fellow[0]所在的地址,所以如果想要通过指针拿到fellow[0].income的值,写法为:*him,因为*him = fellow[0](因为him = &fellow[0])*& 可以相互抵掉。

fellow[0].income == (*him).income

fellow[0].handle.first = (*him).handle.first
fellow[1].handle.first = (*(him + 1)).handle.first

->运算符

him = &fellow[0]
那么:him->income 也就是fellow[0].income

总之,如果him是指向guy类型的结构barney的指针,下列的关系恒成立。
barney.income == (*him).income == him ->income

再加一个结构指针的例子⑧。需要注意的是声明指针之后需要指向结构变量,这样才能生效。(*him).first == him ->first
请添加图片描述

结构作为参数在函数中传递

结构作为参数在函数中传递的时候既可以传递结构本身,也可以传递指向结构的指针,还可以传递结构中的成员,但前提是改成员为具有单个之的数据类型,即int、char、指针等。

将结构成员作为参数进行传递

函数并不关心被传入的参数是否为结构的成员,她只关注被传入参数是否符合相关要求的数据类型即可。
请添加图片描述

将结构地址(指向结构的指针)作为参数进行传递

请添加图片描述

sum函数的形参列表要求传入的就是一个指针,函数在被调用的时候也传入了&DDD,使用&来获取结构的地址,和数组名不同,结构名只是其地址的别名。

将整个结构作为参数进行传递

此方法只适用于允许将结构作为参数的编译器,就是将【将结构地址(指向结构的指针)作为参数进行传递】中的指针换成结构就可以啦,而且几乎用的很少,所以就不再赘述啦。

结构和结构指针的选择

在设计与结构相关的函数时,选择结构或者结构指针作为参数都可以,两者各有优缺点:

指针的优点:执行起来比较快,因为只需要一个地址,而且不管是以前的C还是现在的C都适用。
指针的缺点:无法保护数据。被调函数中的某些操作可能会意外影响原来结构中的数据。
结构的优点:数据受到保护,因为函数处理的是原本数据的副本,而且代码风格也比较清晰。
结构的缺点:相较于指针而言,执行缓慢一些。


http://www.ppmy.cn/news/425191.html

相关文章

csgo服务器找不到,csgo社区服务器进不去

在steam 的快捷方式上点右键-属性,然后在目标处结尾输入空格-tcp ,点击确定即可,以后通过这个加了参数的快捷方式执行steam即可。加参数的方式其实和cs1.5加控制台或者加去除鼠标加速度的方法是一样的。 详细答案: 在steam 的快捷…

Day_50小结

目录 一. 比较和分析各种查找算法 二. 描述各种排序算法的特点和基本思想&比较分析各种排序算法 1. 插入排序 2. 交换排序 3. 选择排序 4. 外部排序 三. 设计一个自己的 Hash 函数和一个冲突解决机制 1. 对于哈希函数的构造: 2. 处理冲突的办法&#…

游戏王决斗连接显示服务器错误,游戏王决斗链接进不去 国服常见问题解决方案...

核心提示:游戏王决斗链接进不去 国服常见问题解决方案,相信很多小伙伴对这一块不太清楚,接下来小编就为大家介绍一下游戏王决斗链接进不去 国服常见问题解决方案,有兴趣的小伙伴可以来了解一下哦。 游戏王决斗链接进不去 国服常见问题解决方案…

地下城与勇士手游服务器一直维护是为什么,地下城与勇士手游版进不去 DNF手游进不去解决方法...

对于不少喜爱地下城与勇士这款游戏的玩家来说,DNF手游是最为期待的了,不过在游玩之前需要解决的一个问题就是,地下城与勇士手游版进不去怎么办,这里就给大家带来了DNF手游进不去的一些解决方法。 第一种情况:服务器维护…

android手机版打不开,游戏王决斗链接安卓版打不开 游戏进不去解决方法

相信最近有很多玩家发现了一款新策略卡牌游戏吧,那就是游戏王决斗链接了,听说马上要在国服开始公测了,所以很多玩家想知道游戏王决斗链接安卓版打不开怎么办?所以小编带来了游戏进不去解决方法,希望可以帮助到各位玩家…

决斗场 - 实验吧 隐写术 打不开的文件

题目链接:http://www.shiyanbar.com/ctf/1878 题目解题链接打开,是一个加载不出来的图片,由于加载不出来的图片不能右键另存为……这里小编直接把图片链接在迅雷中添加任务下载的。 尝试打开这个下载好的图片,发现直接双击是打不…

梦想世界3手游服务器维护,梦想世界手游进不去 闪退及登录不上解决方法

梦想世界手游进不去,梦想世界手游无法连接服务器,梦想世界手游登陆失败,梦想世界手游进去就死机,更新失败,或更新之后进不去了,梦想世界手游闪退是怎么回事,黑屏怎么回事,闪退怎么办…

dnf 跨服 服务器 位置,dnf跨区怎么跨_dnf国服跨区表_快吧游戏

DNF国服跨区须知,什么时候跨区?跨区需要什么东西?跨区有什么限制?角色跨区有什么东西能转移?下面快吧小编就给大家带来7.28更新内容AFQ付费跨区解答,希望小伙伴们别懵了哦! DNF国服跨区须知 跨区…