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.hqwc.cn/news/339365.html

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

相关文章

初识MySQL:数据库相关概念,SQL语法以及DDL(数据库操作,表操作)

目录 1.数据库相关概念2.关系型数据库(RDBMS)3.SQL通用语法4.SQL分类5.DDL-数据库操作6.DDL-表操作1.查询表2.创建表3.数据类型1.数值类型2.字符串类型3.日期类型 4.修改表5.删除表 1.数据库相关概念 2.关系型数据库(RDBMS) 关系型…

【教程】通过Excel宏/Pandas两种方法来自动添加渐变数据条

这种数据真的很难看懂: 一般会对其画折线图或者数据条,相比起来就非常直观: 但是每一列都要手动这样设置就非常累了,所以这里就用到了VBA宏(或者Pandas)。 VBA宏方法 从这里进入宏: 随便写一个宏名后点创建&#xff1…

如何对制作好的查询进行编辑和导出?

发布者已经创建好了查询,如发现数据有误,想要进行修改,或者想要将收集好的表格进行导出,应该如何操作?本次就来介绍如何使用此功能。 📖案例:教师荣誉核对系统 在开启可修改列功能的教师荣誉核对…

4S店汽车行业万能通用小程序源码系统:功能强大,集合汽车在线展示+在线预约+贷款计算器......附带完整的搭建教程

在移动互联网高速发展的今天,越来越多的消费者选择通过手机端了解汽车信息、预约试驾、计算贷款等。4S店需要紧跟时代步伐,提供更加便捷、高效的服务。因此,开发一款集合汽车在线展示、在线预约、贷款计算器等多项功能的通用小程序成为市场趋…

Programming Abstractions in C阅读笔记:p242-p245

《Programming Abstractions in C》学习第67天,p242-p245总结,总计4页。 一、技术总结 6.2小结主要讲回溯算法及递归算法在迷宫求解中应用,当然,理解然后用代码实现出来还是有些难度的。不过,这并不影响我们进行下一…

圣诞节酷炫特效合集【含十几个HTML+CSS前端特效+34个桌面酷炫圣诞程序】

写在前面 ❤️源码获取:订阅后见文末 ❤️内容介绍:包含HTML+CSS等十几个圣诞特效;以及三十四个桌面酷炫圣诞树合集 ❤️订阅后所得如下: ❤️HTML圣诞+桌面圣诞程序效果如下: 下方展示代码仅举例其中几个 所有效果源码及文件订阅后找博主获取即可 🎄css3圣诞雪人动…

AirServer2024免费手机电脑高清投屏软件

AirServer 是适用于 Mac 和 PC 的先进的屏幕镜像接收器。 它允许您接收 AirPlay 和 Google Cast 流,类似于 Apple TV 或 Chromecast 设备。AirServer 可以将一个简单的大屏幕或投影仪变成一个通用的屏幕镜像接收器 ,是一款十分强大的投屏软件。 它能够通…

二叉树的最近公共祖先(算法村第八关黄金挑战)

236. 二叉树的最近公共祖先 - 力扣(LeetCode) 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 …

了解SSL证书、APNs证书、Jamf Push Proxy证书

在Jamf Pro内会涉及到SSL证书、APNs证书、Jamf Push Proxy证书,每一个证书都有其各自的作用和有效期,下面我们来详细了解一下。 SSL证书 Jmf Pro需要有效的SSL证书来确保计算机和移动设备是与Jamf Pro服务器通信,而不是冒名顶替的服务器。Jam…

css-文本垂直居中, 左侧border与文字作为导航标题

1.文本垂直居中 1.1 Flexbox 布局 <!DOCTYPE html> <html lang"en"> <head><style>.container {display: flex;align-items: center; /* 使用 align-items 属性垂直居中 */height: 200px; /* 设置容器高度 */border: 1px solid #ccc;}</…

深度学习目标跟踪简述

深度学习目标跟踪是一个活跃的研究领域&#xff0c;它涉及使用深度学习技术来跟踪视频或实时摄像头中的对象。这个领域通常包括以下几个关键方面&#xff1a; 目标检测&#xff1a;在开始跟踪前&#xff0c;首先需要在视频的初始帧中检测到目标。这通常是通过卷积神经网络&…

【SpringMVC快速使用】1.@RestController @RequestMapping 2.logback的使用

背景&#xff1a;为何从这个最简单的 例子写起呢&#xff1f; 那是因为我们的管理后台之类的都是别人写的&#xff0c;我也听说了大家说&#xff1a;只用Post请求就足够了&#xff0c;但是却发现&#xff0c;在浏览器中测试时&#xff0c;默认是GET请求&#xff0c;如果直接写…