5、C语言:结构

结构

  • 结构的基本知识
  • 结构与函数
    • 传递结构
  • 结构数组、指向结构的指针
  • 自引用结构(二叉树)
  • 表查找
  • 类型定义(typedef)
  • 联合
  • 位字段

结构也是一种数据类型。类似于int、char、double、float等。
结构是一个或多个变量的集合,这些变量可能为不同的类型,为了处理的方便而将这些变量组织在一个名字之下。
结构可以拷贝、赋值、传递给函数,函数也可以返回结构类型的返回值。

结构的基本知识

  • 关键字struct 引入结构声明。结构声明由包含在花括号内的一系列声明组成。
  • 关键字struct后面的名字是可选的,称为结构标记。结构标记用于为结构命名,在定义之后,结构标记就代表花括号内的声明,可以用它作为该声明的简写形式。
  • 结构中定义的变量称为成员。
struct point {int x;int y;
};
  • 结构中定义的变量称为成员。结构成员、结构标记和普通变量(即非成员)可以采用相同的名字,它们之间不会冲突,因为通过上下文分析总可以对它们进行区分。
  • 如果结构声明的后面不带变量表,则不需要为它分配存储空间,它仅仅描述了一个结构的模板或轮廓。
  • 结构的初始化可以在定义的后面使用初值表进行。
struct point maxpt = {320, 200};
  • 可以通过下列形式引用某个特定结构中的成员:结构名.成员
printf("%d,%d", pt.x, pt.y);
  • 结构可以嵌套。
struct rect {struct point pt1;struct point pt2;
};

结构与函数

结构的合法操作只有几种:作为一个整体复制和赋值,通过&运算符取地址,访问其成员。

传递结构

  1. 分别传递各个结构成员
  2. 传递整个结构(可采用函数返回值)
  3. 传递指向结构的指针
struct point *pp;

假定p 是一个指向结构的指针,可以用p->结构成员,这种形式引用相应的结构成员。

结构数组、指向结构的指针

下面两种类型相同:

struct key {char *word;int count;
};
struct key keytab[NKEYS];
struct key {char *word;int count;
} keytab[NKEYS];

自引用结构(二叉树)

用结构体来实现二叉树。

  • 结构体的自引用:
struct tnode { /* the tree node: */char *word; /* points to the text */int count; /* number of occurrences */struct tnode *left; /* left child */struct tnode *right; /* right child */
};
  • 两个结构相互引用
struct t {...struct s *p; /* p points to an s */
};
struct s {...struct t *q; /* q points to a t */
};

表查找

该算法采用的是散列查找方法——将输入的名字转换为一个小的非负整数,该整数随后将作为一个指针数组的下标。数组的每个元素指向某个链表的表头,链表中的各个块用于描述具有该散列值的名字。如果没有名字散列到该值,则数组元素的值为NULL。
在这里插入图片描述

链表中的每个块都是一个结构,它包含一个指向名字的指针、一个指向替换文本的指针以及一个指向该链表后继块的指针。如果指向链表后继块的指针为NULL,则表明链表结束。

struct nlist { /* table entry: */struct nlist *next; /* next entry in chain */char *name; /* defined name */char *defn; /* replacement text */
};

类型定义(typedef)

C语言提供了一个称为typedef的功能,它用来建立新的数据类型名.

typedef int Length;    //将Length定义为与int具有同等意义的名字。
typedef char* String;

typedef 中声明的类型在变量名的位置出现,而不是紧接在关键字typedef 之后。这里以大写字母作为typedef定义的类型名的首字母,以示区别。
从任何意义上讲,typedef 声明并没有创建一个新类型,它只是为某个已存在的类型增加了一个新的名称而已。
typedef 声明也没有增加任何新的语义:通过这种方式声明的变量与通过普通声明方式声明的变量具有完全相同的属性。实际上,typedef类似于#define 语句,但由于typedef 是由编译器解释的,因此它的文本替换功能要超过预处理器的能力。

typedef int (*PFI)(char *, char *);

该语句定义了类型PFI 是“一个指向函数的指针,该函数具有两个char *类型的参数,返回值类型为int”,它可用于某些上下文中。
除了表达方式更简洁之外,使用typedef还有另外两个重要原因。首先,它可以使程序参数化以提高程序的可移植性。如果typedef声明的数据类型同机器有关,那么,当程序移植到其它机器上时,只需改变typedef类型定义就可以了。一个经常用到的情况是,对于各种不同大小的整型值来说,都使用通过typedef 定义的类型名,然后,分别为各个不同的宿主机选择一组合适的short、int 和long 类型大小即可。
typedef 的第二个作用是为程序提供更好的说明性——Treeptr 类型显然比一个声明为指向复杂结构的指针更容易让人理解。

联合

联合是可以(在不同时刻)保存不同类型和长度的对象的变量,编译器负责跟踪对象的长度和对齐要求。联合提供了一种方式,以在单块存储区中管理不同类型的数据,而不需要在程序中嵌入任何同机器有关的信息。
联合的目的:一个变量可以合法地保存多种数据类型中任何一种类型的对象。

union u_tag {int ival;float fval;char *sval;
} u;

变量u 必须足够大,以保存这3 种类型中最大的一种,具体长度同具体的实现有关。这些类型中的任何一种类型的对象都可赋值给u,且可使用在随后的表达式中,但必须保证是一致的:读取的类型必须是最近一次存入的类型。

  • 访问联合中成员
    联合名.成员、 联合指针->成员
  • 联合使用
if (utype == INT)printf("%d\n", u.ival);
if (utype == FLOAT)printf("%f\n", u.fval);
if (utype == STRING)printf("%s\n", u.sval);
elseprintf("bad type %d in utype\n", utype);
  • 结构体中联合使用:与嵌套结构相同
struct {char *name;int flags;int utype;union {int ival;float fval;char *sval;
} u;
} symtab[NSYM];symtab[i].u.ival;

实际上,联合就是一个结构,它的所有成员相对于基地址的偏移量都为0,此结构空间要大到足够容纳最“宽”的成员,并且,其对齐方式要适合于联合中所有类型的成员。

  • 初始化
    联合只能用其第一个成员类型的值进行初始化,因此,上述联合u 只能用整数值进行初始化。

位字段

在存储空间很宝贵的情况下,有可能需要将多个对象保存在一个机器字中。

#define KEYWORD 01
#define EXTRENAL 02
#define STATIC 04enum { KEYWORD = 01, EXTERNAL = 02, STATIC = 04 };

C语言仍然提供了另一种可替代的方法,即直接定义和访问一个字中的位字段的能力,而不需要通过按位逻辑运算符。位字段(bit-field),或简称字段,是“字”中相邻位的集合。“字”(word)是单个的存储单元,它同具体的实现有关。

struct {
unsigned int is_keyword : 1;
unsigned int is_extern : 1;
unsigned int is_static : 1;
} flags;

字段的所有属性几乎都同具体的实现有关。字段是否能覆盖字边界由具体的实现定义。字段可以不命名,无名字段(只有一个冒号和宽度)起填充作用。特殊宽度0 可以用来强制在下一个字边界上对齐。

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

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

相关文章

c++学习笔记-STL案例-机房预约系统1-准备工作

前言 准备工作包括:需求分析、项目创建、主菜单实现、退出功能实现 目录 1 机房预约系统需求 1.1 简单介绍 1.2 身份介绍 1.3 机房介绍 1.4 申请介绍 1.5 系统具体要求 1.6 预约系统-主界面思维导图 2 创建项目 2.1 创建项目 2.2 添加文件 ​编辑 3 创建…

页面跳转后,默认选中tree节点并高亮显示

1.场景 操作步骤: 1.点击数据连接数,打开弹窗 2.点击连接状态跳转到数据连接模块 3.默认选中tree的数据源id节点 2.代码 参数解释: 3.实现逻辑 首先将id通过组件传参的方式传过去,数据连接接收后,在tree里设置…

ubuntu 挂载新硬盘

1、检测新硬盘 新增加硬盘,检测硬盘识别情况。 命令检查:sudo fdisk -l 3、格式化磁盘 格式化:sudo mkfs.ext4 /dev/sdb 其中,/dev/sdb是新分区的设备文件名,ext4是要使用的文件系统类型。 4、挂载新分区 sudo mk…

【银行测试】24年金融银行项目,10道高频测试面试题汇总...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 面试题1&#xff…

使用AUTOSAR来开发汽车基础软件的优点

1、高质量。以前我们采用手写代码的方式,是几个工程师在战斗。现在我们采用平台,BSW代码都是供应商提供的,我们相当于后面还有一个团队陪着我们在战斗。 2、低成本。大家都说采用AUTOSAR平台好贵,但是从长远来看是值得的&#xff…

计算机毕业设计----ssm开发的Java快递代拿系统

使用技术 采用 Spring SpringMVC MyBatisPlus,连接池采用 Druid,安全框架使用 Shiro,前端采用 Bootstrap layer 实现。 支付采用支付宝沙箱环境,支付APP下载链接,[点击这里](https://sandbox.alipaydev.com/user/…

SpringBoot中使用SpringEvent业务解耦神器实现监听发布事件同步异步执行任务

场景 SpringBoot中使用单例模式ScheduledExecutorService实现异步多线程任务(若依源码学习): SpringBoot中使用单例模式ScheduledExecutorService实现异步多线程任务(若依源码学习)-CSDN博客 设计模式-观察者模式在Java中的使用示例-环境监测系统: 设…

GPT实战系列-简单聊聊LangChain

GPT实战系列-简单聊聊LangChain LLM大模型相关文章: GPT实战系列-ChatGLM3本地部署CUDA111080Ti显卡24G实战方案 GPT实战系列-Baichuan2本地化部署实战方案 GPT实战系列-大话LLM大模型训练 GPT实战系列-探究GPT等大模型的文本生成 GPT实战系列-Baichuan2等大模…

SpringBoot中使用LocalDateTime踩坑记录

文章目录 前言一、为什么推荐使用java.time包的LocalDateTime而不是java.util的Date?二、使用LocalDateTime和LocalDate时遇到了哪些坑?2.1 Redis序列化报错2.1.1 问题现象2.1.2 问题分析2.1.3 解决方案 2.2 LocalDateTime和LocalDate类型的属性返回给前…

类型特质和静态断言

static_assert( constant-expression, string-literal );static_assert( constant-expression ); // C17 (Visual Studio 2017 and later) constant-expression 可以转换为布尔值的整型常量表达式。 如果计算出的表达式为零 (false),则显示 string-literal 参数&…

PyTorch|view(),改变张量维度

在构建自己的网络时,了解数据经过每个层后的形状变化是必须的,否则,网络大概率会出现问题。PyToch张量有一个方法,叫做view(),使用这个方法,我们可以很容易的对张量的形状进行改变,从而符合网络的输入要求。…

React 18中新钩子 useDeferredValue 使用

React是一个流行的用于构建用户界面的JavaScript库,它不断发展以为开发人员提供优化性能的工具。 React 18中引入的此类工具之一是useDeferredValue钩子,它旨在通过优先渲染更新来提高应用程序的性能。 useDeferredValue钩子是什么? useDeferredValue钩子是React性能优化工…

SAP PP配置学习(五)

查找 四、 其它 设置 MM 过帐号码范围 定义凭证号码范围 OB52 打开期间 MMPV 开帐 (下篇见)

K-【学习Diffusers 四】 读取模型参数 bin格式、safetensors格式

该操作多用于推理 safetensors格式的参数读取方法 1 拿到pipeline中的unet的办法 unet pipeline.pipe.unet 2 safetensors格式文件的参数读取方法 state_dict safetensors.torch.load_file(args.model_id, device"cpu") unet.load_state_dict(state_dict) # 读入…

随心玩玩(十二)通义千问——LLM大模型微调

写在前面:使劲的摸鱼,摸到的鱼才是自己的~ 文章目录 简介环境配置模型加载jupyter远程配置快速使用微调示例部署方案总结附录: ReAct Prompting 示例准备工作一:样例问题、样例工具准备工作二:ReAct 模版步骤一&#x…

MySQL:DML数据操作语言(添加,删除,修改),DDL数据查询语言(条件查询,分组查询,排序查询,分页查询)

目录 1.DML(数据操作语言)1.添加数据2.修改数据3.删除数据 2.DQL(数据查询语言)1.DQL-语法2.基本查询3.条件查询(WHERE)1.语法:2.条件:3.案例: 4.聚合函数1.介绍2.常见聚合函数3.语法4.案例 5.分组查询(GROUP BY&#…

物联网通讯协议NB-lot和LoRa差异分析

像把大象装冰箱一样,物联网,万物互联也是要分步骤的。 一、感知层(信息获取层),即利用各种传感器等设备随时随地获取物体的信息; 二、网络层(信息传输层),通过各种电信网络与互联网的融合,将物体的信息实时准确地传递…

力扣LCR 166. 珠宝的最高价值(java 动态规划)

Problem: LCR 166. 珠宝的最高价值 文章目录 解题思路思路解题方法复杂度Code 解题思路 思路 改题目与本站64题实质上是一样的,该题目在64题的基础上将求取最小路径和改成了求取最大路径和。具体实现思路如下: 1.定义一个int类型的二维数组dp大小为给定…

17- Echarts 配置系列之:单轴 singleAxis

singleAxis: 用于展示只有一个数据维度的数据。它通常用于展示时间序列数据或者数值序列数据。 对于单轴的应用和绘制,其实就相当于我们平时的直角坐标系少一个 X 或者 Y ,然后进行图形绘制。 注意: 1.在使用单轴时&#xff0…

1.10号io网络

信号量(信号灯集) 1> 信号灯集主要完成进程间同步工作,将多个信号灯,放在一个信号灯集中,每个信号灯控制一个进程 2> 每个灯维护了一个value值,当value值等于0时,申请该资源的进程处于阻…