当前位置: 首页 > news >正文

【C语言】结构体嵌套

结构体嵌套是指在一个结构体中定义另一个结构体作为其成员。这种方式可以实现更复杂的数据结构设计,便于对数据进行分层管理和组织,广泛应用于实际开发中,例如操作系统内核、嵌入式系统、网络协议解析等。下面是对结构体嵌套的详细介绍,包括语法、用法、内存布局和注意事项。

C语言中的结构体嵌套

1. 定义

语法:

struct Outer {struct Inner inner_member;  // 嵌套一个结构体int other_member;
};
  • Outer:外层结构体。
  • Inner:内层结构体,作为外层结构体的一个成员。

看起来很简单对不对,没错,在编程中,即便是看起来非常复杂的结构其底层也只是由最为简单的模块拼接而成的。结构体嵌套允许我们在一个结构体中通过组合的方式包含另一个结构体,这样,从而构建更复杂的数据结构。

代码片示例:

#include <stdio.h>// 定义内部结构体
struct Inner {int x;int y;
};// 定义外部结构体
struct Outer {struct Inner inner_member;  // 嵌套结构体int z;
};int main() {struct Outer outer;// 初始化嵌套的结构体成员outer.inner_member.x = 5;outer.inner_member.y = 10;outer.z = 15;// 打印嵌套结构体成员printf("Inner x = %d, y = %d\n", outer.inner_member.x, outer.inner_member.y);printf("Outer z = %d\n", outer.z);return 0;
}

输出:

Inner x = 5, y = 10
Outer z = 15
2. 结构体嵌套的初始化

2.1 逐个成员初始化: 可以通过指定每个嵌套结构体成员的值来初始化:

struct Outer outer;outer.inner_member.x = 5;
outer.inner_member.y = 10;
outer.z = 15;

2.2 使用复合字面量(C99支持): 可以直接通过复合字面量对嵌套结构体进行初始化:

struct Outer outer = {.inner_member = {.x = 5, .y = 10},  // 初始化内层结构体.z = 15
};

2.3 使用位置初始化
利用结构体成员的声明顺序进行初始化:

struct Outer outer = {{5, 10}, 15};

代码片

#include <stdio.h>struct Inner {int x;int y;
};struct Outer {struct Inner inner_member;int z;
};int main() {// 使用位置初始化struct Outer outer = {{5, 10}, 15};printf("Inner x = %d, y = %d\n", outer.inner_member.x, outer.inner_member.y);printf("Outer z = %d\n", outer.z);return 0;
}

输出:

Inner x = 5, y = 10
Outer z = 15

3. 内存布局

嵌套结构体的内存布局遵循C语言的对齐规则。外层结构体会根据嵌套结构体的大小和对齐要求分配内存。

代码片:

#include <stdio.h>struct Inner {char a;   // 1字节int b;    // 4字节
};struct Outer {struct Inner inner_member;  // 嵌套结构体double c;                   // 8字节
};int main() {printf("Size of Inner: %lu\n", sizeof(struct Inner));printf("Size of Outer: %lu\n", sizeof(struct Outer));return 0;
}

内存布局分析(假设 32 位系统,小端存储):

  1. Inner结构体:
    • char a 占 1 字节。
    • 为了满足 int b 的 4 字节对齐要求,插入 3 字节填充。
    • int b 占 4 字节。
    • 总大小为 8 字节(4 的倍数)。
  2. Outer结构体:
    • inner_member 占 8 字节。
    • double c 占 8 字节,按 8 字节对齐。
    • 总大小为 16 字节(8 的倍数)。

输出:

Size of Inner: 8
Size of Outer: 16

4. 匿名结构体嵌套

匿名结构体是指在结构体中嵌套一个不带标签(没有名字)的结构体。匿名结构体的成员可以直接访问,而不需要通过结构体变量名。

代码片

#include <stdio.h>struct Outer {struct {int x;int y;};  // 匿名结构体int z;
};int main() {struct Outer outer;// 直接访问匿名结构体的成员outer.x = 5;outer.y = 10;outer.z = 15;printf("x = %d, y = %d\n", outer.x, outer.y);printf("z = %d\n", outer.z);return 0;
}

输出:

x = 5, y = 10
z = 15

注意: 匿名结构体的成员名不能与外层结构体的其他成员名冲突。匿名结构体只能在支持 C11标准 的编译器中使用。

5. 结构体嵌套的多级结构

结构体嵌套可以是多级的,即结构体中嵌套另一个结构体,而被嵌套的结构体还可以嵌套其他结构体。

代码片

#include <stdio.h>// 定义多级嵌套结构体
struct Level3 {int l3_data;
};struct Level2 {struct Level3 level3;int l2_data;
};struct Level1 {struct Level2 level2;int l1_data;
};int main() {struct Level1 level1;// 设置多级嵌套结构体的成员level1.level2.level3.l3_data = 100;level1.level2.l2_data = 200;level1.l1_data = 300;printf("Level3 data: %d\n", level1.level2.level3.l3_data);printf("Level2 data: %d\n", level1.level2.l2_data);printf("Level1 data: %d\n", level1.l1_data);return 0;
}

输出:

Level3 data: 100
Level2 data: 200
Level1 data: 300

6. 使用结构体指针访问嵌套成员

在实际开发中,通常通过结构体指针访问嵌套结构体的成员,尤其是在嵌套层级较深时

代码片

#include <stdio.h>struct Inner {int x;int y;
};struct Outer {struct Inner inner_member;int z;
};int main() {struct Outer outer = {{5, 10}, 15};struct Outer *ptr = &outer;// 使用指针访问嵌套结构体成员printf("Inner x = %d, y = %d\n", ptr->inner_member.x, ptr->inner_member.y);printf("Outer z = %d\n", ptr->z);return 0;
}

输出:

Inner x = 5, y = 10
Outer z = 15

使用结构体嵌套的注意事项:

  1. 内存对齐:嵌套结构体的内存对齐规则会影响结构体的大小。为了优化内存使用,建议将较大对齐要求的成员放在前面。
  2. 命名冲突:如果嵌套结构体的成员名与外层结构体的成员名相同,访问时需要明确指定路径。
  3. 匿名结构体的兼容性:使用匿名结构体需要确保编译器支持C11标准
  4. 递归嵌套:C语言不允许结构体直接递归嵌套自己,但可以通过指针实现递归嵌套(如链表)。

综上,结构体嵌套在实际开发中具备多种优势:

  • 结构体嵌套是C语言中组织复杂数据的强大工具,允许在结构体中包含其他结构体,方便分层管理数据。
  • 嵌套结构体可以通过直接访问、初始化或指针访问来操作其成员。
  • 内存布局会受到对齐规则的影响,理解对齐规则有助于优化内存使用。
  • 使用嵌套结构体时,应注意命名冲突、内存对齐和跨平台兼容性。

以上。通过结构体嵌套,我们可以构建出灵活、高效的数据结构,满足实际开发中复杂数据组织的需求。

我是一个十分热爱技术的程序员,希望这篇文章能够对您有帮助,也希望认识更多热爱程序开发的小伙伴。
感谢!

相关文章:

【C语言】结构体嵌套

结构体嵌套是指在一个结构体中定义另一个结构体作为其成员。这种方式可以实现更复杂的数据结构设计&#xff0c;便于对数据进行分层管理和组织&#xff0c;广泛应用于实际开发中&#xff0c;例如操作系统内核、嵌入式系统、网络协议解析等。下面是对结构体嵌套的详细介绍&#…...

PDF view | Chrome PDF Viewer |Chromium PDF Viewer等指纹修改

1、打开https://www.browserscan.net/zh/ 2、将internal-pdf-viewer改为 internal-pdf-viewer-jdtest看下效果&#xff1a; 3、源码修改&#xff1a; third_party\blink\renderer\modules\plugins\dom_plugin_array.cc namespace { DOMPlugin* MakeFakePlugin(String plugin_…...

maxun爬虫工具docker搭建

思路来源开源无代码网络数据提取平台Maxun 先把代码克隆到本地&#xff08;只有第一次需要&#xff09; git clone https://github.com/getmaxun/maxun.git 转到maxun目录 cd maxun 启动容器 docker-compose --env-file .env up -d 成功启动六个容器 网址 http://local…...

JAVAWeb之javascript学习

1.js引入方式 1. 内嵌式&#xff1a;在head中&#xff0c;通过一对script标签引入JS代码&#xff1b;cript代码放置位置有一定的随意性&#xff0c;一般放在head标签中&#xff1b;2.引入外部js文件 在head中&#xff0c;通过一对script标签引入外部JS代码&#xff1b;注意&…...

vue3中是如何实现双向数据绑定的

在 Vue 3 中&#xff0c;双向数据绑定主要通过 v-model 指令实现。v-model 是一个语法糖&#xff0c;它内部实际上结合了 v-bind 和 v-on 指令来实现数据的双向绑定。下面详细介绍 Vue 3 中双向数据绑定的实现原理和使用方法。 双向数据绑定的基本原理 v-bind 指令&#xff1…...

JavaScript事件机制详解

JavaScript中的事件模型是指当用户与网页进行交互时&#xff0c;浏览器会触发不同类型的事件&#xff0c;开发者可以通过添加事件监听器来响应这些事件。事件流是描述事件在页面元素中传播的过程&#xff0c;从窗口对象开始&#xff0c;逐级向下传播到最具体的元素&#xff0c;…...

k8s运行运行pod报错超出文件描述符表限制

1.问题描述 运行pod超过文件描述符表 unable to allocate file descriptor table - out of memory/opt/COMMAND.sh: line 9: 2.查看设备的文件描述符限制 操作前一定要先查询这个值&#xff0c;2097152这个值即为我们可设置的最大值&#xff0c;超过这个值后将无法登录&am…...

vue 2 父组件根据注册事件,控制相关按钮显隐

目标效果 我不注册事件&#xff0c;那么就不显示相关的按钮 注册了事件&#xff0c;才会显示相关内容 实现思路 组件在 mounted 的时候可以拿到父组件注册监听的方法 拿到这个就可以做事情了 mounted() {console.log(this.$listeners, this.$listeners);this.show.search !…...

22智能 图

例题 根据下列顶点之间的关系&#xff0c;画出相应的图结构 A -> B, C, D B -> A, C, C -> A, D, E, D -> B, E, E -> C, 数据结构&#xff1a;使用邻接表表示图&#xff0c;每个顶点有一个链表来存储与它相邻的顶点。 功能&#xff1a; 创建图。 添加边。 打…...

Springfox、Swagger 和 Springdoc

Springfox、Swagger 和 Springdoc 是用于在 Spring Boot 项目中生成 API 文档的工具&#xff0c;但它们之间有显著的区别和演进关系&#xff1a; 1. Swagger 简介 Swagger 是一个开源项目&#xff0c;旨在为 RESTful APIs 提供交互式文档。最早由 SmartBear 开发&#xff0c;…...

编程基础篇

什么是编程&#xff1f; 原文地址 &#xff1a;样式不太熟悉&#xff0c;有点单一&#xff0c;原文地址 一千个人眼中有一千个哈姆雷特&#xff0c;以下是我眼中的编程&#xff1a; A每天出门需要关一下空调&#xff0c;在家喜欢室内温度在 20左右&#xff0c;6 点左右会打开灯…...

GPT视角下,如何在密码学研究中找到属于你的方向?

&#xff08;本文所有内容由GPT生成&#xff09;在密码学领域发现关键性的研究方向并成为一位优秀的密码学研究员&#xff0c;需要结合对领域趋势的洞察、扎实的理论基础以及创新的研究思维。以下是具体步骤和方法&#xff1a; 一、发现关键性研究方向 关注领域前沿动态 顶级会…...

【经典】星空主题的注册界面HTML,CSS,JS

目录 界面展示 完整代码 说明&#xff1a; 这是一个简单的星空主题的注册界面&#xff0c;使用了 HTML 和 CSS 来实现一个背景为星空效果的注册页面。 界面展示 完整代码 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8&…...

Linux学习——4_WEB服务器的部署及优化

WEB服务器的部署及优化 用户常用关于web信息 什么是www www是world wide web的缩写&#xff0c;即万维网&#xff0c;也就是全球信息广播 通常说的上网就是使用www来查询用户所需要的信息。 www可以结合文字、图形、影像以及声音等多媒体&#xff0c;超链接的方式将信息以…...

《Vue 组件化开发:构建可复用的模块》

一、Vue 组件化开发概述 组件化是 Vue.js 的核心概念之一&#xff0c;它允许将界面拆分成独立、可复用的组件&#xff0c;使得开发大型应用变得更加简单和高效。 组件的定义是实现应用中局部功能代码和资源的集合。Vue.js 的组件化用于将 UI 页面分割为若干组件进行组合和嵌套…...

贪心算法理论

系列博客目录 文章目录 系列博客目录贪心算法 (Greedy Algorithm)贪心算法的特点贪心算法的适用条件常见的贪心算法问题贪心算法的步骤贪心算法示例&#xff1a;活动选择问题贪心算法的优缺点 贪心算法 (Greedy Algorithm) 贪心算法是一种在每一步选择中都采取当前状态下最优的…...

JVM之Synthetic

Synthetic是人造&#xff0c;合成的意思&#xff0c;在虚拟机很多地方使用ACC_SYNTHETIC表示编译器自动生成的&#xff0c;区别于我们自己写的程序代码。这样说可能比较模糊&#xff0c;我们举个例子&#xff1a;我们创建一个内部类&#xff0c;如下 public class TestInnerCl…...

HCIE IGP双栈综合实验

实验拓扑 实验需求及解法 本实验模拟ISP网络结构&#xff0c;R1/2组成国家骨干网&#xff0c;R3/4组成省级网络&#xff0c;R5/6/7组成数据中 心网络。 配置所有ipv4地址&#xff0c;请自行测试直连。 R1 sysname R1 interface GigabitEthernet0/0/0ip address 12.1.1.1 255.…...

【k8s】监控metrics-server

metrics-server介绍 Metrics Server是一个集群范围的资源使用情况的数据聚合器。作为一个应用部署在集群中。Metric server从每个节点上KubeletAPI收集指标&#xff0c;通过Kubernetes聚合器注册在Master APIServer中。为集群提供Node、Pods资源利用率指标。 就像Linux 系统一样…...

第六届国际科技创新学术交流会暨管理科学信息化与经济创新发展(MSIEID 2024)

重要信息 大会官网&#xff1a;msieid2024.iaecst.org &#xff08;点击了解大会&#xff0c;参会等内容&#xff09; 大会时间&#xff1a;2024年12月6-8日 大会地点&#xff1a;中国-广州 大会简介 随着全球化和信息化的不断深入&#xff0c;管理科学、信息化和经济发展…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

边缘计算网关提升水产养殖尾水处理的远程运维效率

一、项目背景 随着水产养殖行业的快速发展&#xff0c;养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下&#xff0c;而且难以实现精准监控和管理。为了提升尾水处理的效果和效率&#xff0c;同时降低人力成本&#xff0c;某大型水产养殖企业决定…...

结构化文件管理实战:实现目录自动创建与归类

手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题&#xff0c;进而引发后续程序异常。使用工具进行标准化操作&#xff0c;能有效降低出错概率。 需要快速整理大量文件的技术用户而言&#xff0c;这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB&#xff0c;…...

RushDB开源程序 是现代应用程序和 AI 的即时数据库。建立在 Neo4j 之上

一、软件介绍 文末提供程序和源码下载 RushDB 改变了您处理图形数据的方式 — 不需要 Schema&#xff0c;不需要复杂的查询&#xff0c;只需推送数据即可。 二、Key Features ✨ 主要特点 Instant Setup: Be productive in seconds, not days 即时设置 &#xff1a;在几秒钟…...

基于Java项目的Karate API测试

Karate 实现了可以只编写Feature 文件进行测试,但是对于熟悉Java语言的开发或是测试人员,可以通过编程方式集成 Karate 丰富的自动化和数据断言功能。 本篇快速介绍在Java Maven项目中编写和运行测试的示例。 创建Maven项目 最简单的创建项目的方式就是创建一个目录,里面…...

开疆智能Ethernet/IP转Modbus网关连接鸣志步进电机驱动器配置案例

在工业自动化控制系统中&#xff0c;常常会遇到不同品牌和通信协议的设备需要协同工作的情况。本案例中&#xff0c;客户现场采用了 罗克韦尔PLC&#xff0c;但需要控制的变频器仅支持 ModbusRTU 协议。为了实现PLC 对变频器的有效控制与监控&#xff0c;引入了开疆智能Etherne…...

Ubuntu 安装 Mysql 数据库

首先更新apt-get工具&#xff0c;执行命令如下&#xff1a; apt-get upgrade安装Mysql&#xff0c;执行如下命令&#xff1a; apt-get install mysql-server 开启Mysql 服务&#xff0c;执行命令如下&#xff1a; service mysql start并确认是否成功开启mysql,执行命令如下&am…...

电脑定时关机工具推荐

软件介绍 本文介绍一款轻量级的电脑自动关机工具&#xff0c;无需安装&#xff0c;使用简单&#xff0c;可满足定时关机需求。 工具简介 这款关机助手是一款无需安装的小型软件&#xff0c;文件体积仅60KB&#xff0c;下载后可直接运行&#xff0c;无需复杂配置。 使用…...