C语言(C语言结构基础使用)

news2024/9/21 16:02:31

目录

一.结构

1.结构声明

2.初始化结构

3.访问结构成员

4.结构的初始化器

5.定义无结构标记

6.结构数组

7.嵌套结构

8.复合字面量和结构(C99)

9.伸缩性数组成员

10.伸缩性数组得特殊处理请求

11.匿名结构(C11)

12.使用结构数组得函数

一.结构

1.结构声明

结构声明时描述一个数据结构的组织布局,我们来看个例子

struct book{

        char title[MAXTITL];

        char author[MAXAUTL];

        float value;

};

该声明描述了一个由两个字符数组和一个float数组变量组成的结构。该声明并未创建实际的数组对象。只描述了改对象由什么组成(而我们也把结构声明为模板,因为它描述了结构是如何存储数据的),你可以把它理解成int,double类型,其实它们本质都是一样的,都是为了存储对应的数据。

主要是为了存储图书信息,这里我们知道图书的信息其实分类很多,要有书名,作者,价格,内容等。这里我们用title数组存储书名,用author数组存储作者名,value变量存储书价格。

struct就是声明结构的关键字。

book是结构布局。

title,author,value我们成为成员或字段,它们可以是普遍的数据类型,也可以是其他结构(和自己本身一样的结构也可以)

存储在一个结构中的整套信息被称为记录

而我们创建这个结构声明,而struct book就类似于int,double这样的数据类型名。

下面我们来使用这个结构

struct book library;

这把library声明为一个使用book结构布局的结构变量

可以把这个声明放在所有函数的外部,也可以放在一个函数定义的内部。如果把结构声明置于一个函数的内部,它的标记就只限于该函数内部使用。如果把结构声明置于函数的外部,那么该声明之后的所有函数都能使用它的标记

struct book所起的作用相当于一般声明中的int或float,可以定义两个struct book类型的变量,或者甚至是指向struct book类型的指针

struct book doyle,panshin,* ptbook;

结构变量doyle和panshin中都包含title,author和value部分。指针ptbook可以指向doyle,panshin或者任何其他book类型的结构变量

2.初始化结构

struct book library = {

        "hello world",  

        "you", 

        13 

};

这里"hello world"就初始化给了title成员

和char title[MAXTITL] = "hello world";一样

"you"初始化给了author成员,13初始化给了value成员。

3.访问结构成员

使用结构成员运算符(.)访问结构中的成员。

library.value即使访问library的value的部分,.value的作用相当于book结构的下标。

这里我们使用libray.title来打印书名。因为title成员的类型就是char数组,所以在任何使用char数组的地方都可以正常的使用libray.title。

libray你可以理解为一个包含不同类型的袋子。而int,float这些类型变量就是存储数据的工具,工具在哪都是工具,而针对不同的任务,有目的的选择工具装入到袋子中,可以方便我们存储数据。

而前面我们说过,结构本质上来说就是一个存储数据的复杂类型,因为它其中可能包含了众多类型的数据。而只要是数据类型,我们就可以使用指针来操作。我们先来看例子。

struct book* pf = &libray;

这里我们使用了一个指针pf,pf指向一个struct book数据类型的指针。所以我们把libray变量的地址赋给了pf。这个时候pf的保存的就是libray变量的地址。

而如果我们想要访问这个变量地址上面对象成员的值,有两种方法,第一种就是将.变为->。还有一种就是使用(*pf).title的方式进行访问,这里主要因为*pf其实就是libray了,所以可以使用.

演示代码:
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#define MAXTITL 100

#define MAXAUTL 40



struct book {

char title[MAXTITL]; //书名

char author[MAXAUTL]; //作者名

float value; //价格

};



int main()

{

struct book libray = { "hello world","you",13 };

struct book* pf = &libray;

printf("%s %s %f", pf->title,(*pf).author,libray.value);

return 0;

}

4.结构的初始化器

C99和C11为结构提供了指定初始化器,这个语法和数组的指定初始化器类似。结构的指定初始化器使用点运算符和成员们标识特定的元素。

struct book library = {

        .title = "hello world",

        .author = "ycj",

        0.25,

        .author = "me",

};

与数组的初始化器类似,在指定初始化器后面的普通初始化器,为指定成员后面的成员提供初始值。另外对特定成员的最后一次赋值才是它实际的值。

所以author的作者的名字以最后一个.author = "me"确定。

演示代码:
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#define MAXTITL 100

#define MAXAUTL 40



struct book {

char title[MAXTITL]; //书名

char author[MAXAUTL]; //作者名

float value; //价格

};



int main()

{

struct book libray =

{ .title = "hello world",

  .author = "you",

13,

  .author = "me"};

struct book* pf = &libray;

printf("%s %s %f", pf->title,(*pf).author,libray.value);

return 0;

}

5.定义无结构标记

这样的情况下,如果要使用结构布局,就必须在声明布局的地方的右花括号右边使用变量名。不然后面就因为没有结构布局名的原因无法使用了

struct{

        char title[MAXTITL];

        char author[MAXAUTL];

        float value;

}library

相当于struct book library;

这种布局可以在很多地方给我们省去给非必要结构布局起名的麻烦,后面的例子当中会有应用。

6.结构数组

之前说过结构就是复杂的数据类型,那么既然是类型,那么使用变量进行同类数据的存储是很有必要的。

struct book library[100];

数组的每个元素都是一个book类型的结构

而使用结构数组

Library[1].title,这里是使用第二个数组元素的title

而如果要取第二个数组元素的title字符串的第五个字符可以用

Library[1].title[4];

7.嵌套结构

有时,我们可以在一个结构这种包含另一个结构

这里我们在book结构中又嵌套了一个names结构

而在访问上,我们用library.option.age。进行二次(.)的解引用

8.复合字面量和结构(C99)

C99的复合字面量特性可用于结构和数组。如果只需要一个临时结构值,复合字面量很好用。列如,可以使用复合字面量创建一个结构作为参数或赋给另一个结构。语法是把类型名放在圆括号中,后面紧跟一个用花括号括起来的初始化列表。

struct book {

        char title[MAXTITL]; //书名

        char author[MAXAUTL]; //作者名

        float value; //价格

};

struct book libray = (struct book){ "hello world","ycj",13 };

这里我们其实就是创建了一个临时的结构变量,这个变量把对应成员值都赋给了libray。最终的打印效果是完全一样的。

演示代码:
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#define MAXTITL 100

#define MAXAUTL 40



struct book {

char title[MAXTITL]; //书名

char author[MAXAUTL]; //作者名

float value; //价格

};



int main()

{

struct book libray = (struct book){ "hello world","ycj",13 };

struct book* pf = &libray;

printf("%s %s %f", pf->title,(*pf).author,libray.value);

return 0;

}

还可以把复合字面量作为函数的参数,如果函数接受一个结构,可以把复合字面量作为实际参数传递

在这个例子中,我们使用一个liaray,和一个符合变量地址,将libray原本的价格加上复合变量对应的价格。

9.伸缩性数组成员

C99新增了一个特性:伸缩性数组成员,利用这项特性声明的结构,其最后一个数组成员具有一些特性。其最后一个数组成员具有一些特性。

第一个特性,该数组不会立即存在。

第二个特性,使用这个伸缩性数组成员可以编写合适的代码,就好像它确实存在并具有所需数目的元素一样。

声明一个伸缩性数组成员又如下规则:

1.伸缩性数组成员必须随时结构的最后一个成员

2.结构中必须有一个成员

3.伸缩性数组的声明类似于普通数组,只是它的方括号是空的

struct flex{

Int count;

Double average;

Double scores[];  //伸缩性数组成员

}

伸缩性数组的意图并不是让我们声明struct flex类型的变量,而是希望我们声明一个指向struct flex类型的指针,然后用malloc()来分配足够的空间,以存储struct flex类型结构的常规内容和伸缩性数组成员所需的额外空间。

比如,假设用scores表示一个内含5个double类型值得数组

Struct flex * fp;

Pf = malloc(sizeof(struct flex) + 5 * sizeof(double));

现在有足够得存储空间存储count,average和一个内含5个double类型值得数组,可以用指针fp来访问这些成员

10.伸缩性数组得特殊处理请求

第一,不能用结构进行赋值或拷贝

Struct flex * pf1,*pf2;

*pf2 = *pf1;  //不能这样做

不要这样操作,记住就好了

第二,不要以按值方法把这种结构传递给函数。原因相同,按值传递一个参数与赋值类似(和第一条原理类似)。要把结构得地址传递给函数

11.匿名结构(C11)

匿名结构和无结构标记类似,只不过匿名结构连变量名都不给了

不适用匿名结构

这里我们想要访问嵌套结构必须要使用x.names.last;

演示代码:
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>



struct name

{

char first[20];

char last[20];

};



struct person

{

int id;

struct name names;

};



int main()

{

struct person x = { 1,{"yu","tiancai"} };

printf("%s", x.names.last);

return 0;

}

如果使用匿名结构

不仅整个结构更加清晰明了,而且也会节省时间

演示代码:
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>



struct person

{

int id;

struct {

char first[20];

char last[20];

};

};



int main()

{

struct person x = { 1,{"yu","tiancai"} };

printf("%s", x.last);

return 0;

}

12.使用结构数组得函数

这里我们演示一下如何将结构传入到函数当中

首先数组名就是数组的地址,所以我们可以直接把结构数组名可以把它传递给函数。我们传入到函数当中的是一个不可修改值的指针。最后这个函数会分别取出bankfund和savefund的值进行相加返回。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/341752.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RiProRiProV2主题美化顶部增加一行导航header导航通知

背景: 有些网站的背景顶部有一行罪行公告,样式不错,希望自己的网站也借鉴过来,本教程将指导如何操作,并调整成自己想要的样式。 比如网友搭的666资源站 xd素材中文网

【C语言必经之路——第11节】初阶指针(2)

五、指针的运算1、指针与整数相加减看一下下面的代码&#xff1a;#include<stdio.h> int my_strlen(char* str) {int count0;while(*str!\0){count;str;//指针加减整数}return count; } int main() {int lenmy_strlen("abcdef");printf("%d\n",len);…

OpenCV实战(10)——积分图像详解

OpenCV实战&#xff08;10&#xff09;——积分图像详解0. 前言1. 积分图像计算2. 自适应阈值2.1 固定阈值的缺陷2.2 使用自适应阈值2.3 其它自适应阈值计算方法2.4 完整代码3. 使用直方图进行视觉跟踪3.1 查找目标对象3.2 完整代码小结系列链接0. 前言 我们知道直方图是通过遍…

方法递归调用

&#x1f3e1;个人主页 &#xff1a; 守夜人st &#x1f680;系列专栏&#xff1a;Java …持续更新中敬请关注… &#x1f649;博主简介&#xff1a;软件工程专业&#xff0c;在校学生&#xff0c;写博客是为了总结回顾一些所学知识点 ✈️推荐一款模拟面试&#xff0c;刷题神器…

【C++设计模式】学习笔记(4):观察者模式 Observer

目录 简介动机(Motivation)模式定义结构(Structure)要点总结笔记结语简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计算机专业,获得过国家奖学金…

渣土车智能识别检测 yolov5

渣土车智能识别检测通过yolov5网络模型深度学习技术&#xff0c;渣土车智能识别检测对禁止渣土车通行现场画面中含有渣土车时进行自动识别监测&#xff0c;并自动抓拍告警。YOLOv5是一种单阶段目标检测算法&#xff0c;该算法在YOLOv4的基础上添加了一些新的改进思路&#xff0…

【Redis场景3】缓存穿透、击穿问题

场景问题及原因 缓存穿透&#xff1a; 原因&#xff1a;客户端请求的数据在缓存和数据库中不存在&#xff0c;这样缓存永远不会生效&#xff0c;请求全部打入数据库&#xff0c;造成数据库连接异常。 解决思路&#xff1a; 缓存空对象 对于不存在的数据也在Redis建立缓存&a…

spark01-内存数据分区数量个数原理

原始代码如下&#xff1a;val conf: SparkConf new SparkConf().setMaster("local[*]").setAppName("wordcount")val scnew SparkContext(conf)val rdd: RDD[Int] sc.makeRDD(List(1,2,3,4)//将处理的数据保存分区文件rdd.saveAsTextFile("output2&…

分布式数据库(ShardingSphere)

单库单表数据量过大导致的问题与应对传统的将数据集中存储至单一数据节点的解决方案&#xff0c;在容量、性能、可用性和运维成本这三方面已经难于满足互联网的海量数据场景。我们在单库单表数据量超过一定容量水位的情况下&#xff0c;索引树层级增加&#xff0c;磁盘 IO 也很…

数据库(六): MySQL的主从复制和读写分离

文章目录一、为什么要使用主从复制和读写分离二、主从复制的原理三、如何实现主从复制3.1 master配置3.2 slave配置3.3 测试主从复制四、读写分离五、缺点一、为什么要使用主从复制和读写分离 注意到主从复制和读写分离一般是一起使用的。目的很简单&#xff0c;就是提高数据库…

Python:路径之谜(DFS剪枝)

题目描述 小张冒充 X 星球的骑士&#xff0c;进入了一个奇怪的城堡。 城堡里边什么都没有&#xff0c;只有方形石头铺成的地面。 假设城堡地面是 nn 个方格。如下图所示。 按习俗&#xff0c;骑士要从西北角走到东南角。可以横向或纵向移动&#xff0c;但不能斜着走&#xf…

Java类和对象超详细整理,适合新手入门

目录 一、驼峰命名法 二、Java注释 三、转义符 四、Java程序它的基本结构是什么&#xff1f; 五、Java中的类 六、创建类 七、定义main方法 八、执行代码输出语句 九、Java中的对象 十、创建对象 十一、类与对象的关系 一、驼峰命名法 包名&#xff1a;多单词组成所…

常用类详解(二)StringBuffer

StringBuffer类&#xff1a; 基本介绍&#xff1a; java.lang.StringBuffer代表可变的字符序列&#xff0c;可以对字符串内容进行增删 很多方法与String相同&#xff0c;但StringBuffer是可变长度的。 StringBuffer是一个容器。 我们进行查看StringBuffer&#xff0c;如下…

fpga设计中如何防止信号被优化

本文分别对quartus和vivado防止信号被优化的方法进行介绍。 为什么要防止信号被优化 ​ 在FPGA开发调试阶段&#xff0c;经常遇到这样的情况&#xff0c;需要临时添加信号&#xff0c;观察信号变化&#xff0c;用来定位代码中存在的问题&#xff0c;很多时候这些临时添加的信…

sg3_utils arm64 静态编译

需求背景 在进行ufs等scsi device测试时&#xff0c;需要进行power mode切换等测试&#xff0c;因此需要有一个简单地工具集来向scsi device&#xff08;ufs接口&#xff09;发送scsi命令&#xff0c;比如 scsi reset命令等。在网上调研后发现sg3_utils是一个比较全面的工具。…

本地代码提交至gitee仓库

1、新建仓库 新建一个私人访问的仓库 2、创建公钥 点开cmd 输入ssh-keygen -t rsa -C "xxxxxxxxxx.com" 邮箱填入自己使用的即可。 输入完毕后&#xff0c;连按三次enter。 命令就会执行完毕&#xff0c;会出现这个界面 此时已经代表ssh公钥已经创建完毕。 公…

自动驾驶TPM技术杂谈 ———— 摄像头标定

文章目录介绍摄像头内参标定摄像头模型的建立摄像头坐标系与环境坐标系的转换图像坐标系与图像像素坐标系小孔成像与图像物理坐标系环境坐标系与图像像素坐标系的转换摄像头畸变矫正常见内参标定方法平面标定自标定摄像头间外参标定介绍 标定传感器是自动驾驶感知系统中不可缺少…

Springboot集成工作流Activity

介绍 官网&#xff1a;https://www.activiti.org/ 一 、工作流介绍 1.工作流&#xff08;workflow&#xff09; 就是通过计算机对业务流程自动化执行管理&#xff0c;它主要解决的是“使在多个参与这之间按照某种预定义规则自动化进行传递文档、信息或任务的过程&#xff0c…

儿童绘本馆图书借阅租赁知识付费小程序源码交流

1.分类图书 2.书单推荐 4.会员卡次、期限购买 5.借阅时间选择 6.积分签到 7.优惠Q领取 前端uniapp开发 后端thinkphp开发 完全开源 <template> <view class"sp-section sp-index"> <!-- search --> <view class&qu…

【第30天】SQL进阶-查询优化- performance_schema系列实战五:查看最近的事务执行信息(SQL 小虚竹)

回城传送–》《32天SQL筑基》 文章目录零、前言一、 查看最近的事务执行信息数据准备&#xff08;如果已有数据可跳过此操作&#xff09;开启第一个会话&#xff0c;配置启用事务事件开启第二个会话&#xff0c;用于执行事务&#xff0c;并模拟事务回滚第一个会话查询活跃事件第…