当前位置: 首页 > 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;管理科学、信息化和经济发展…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...