【C语言】结构体

个人主页点这里~
结构体
- 一、结构体类型的声明
- 1、结构的声明
- 2、结构体变量的创建和初始化
- 3、声明时的特殊情况
- 4、自引用
- 二、结构体内存对齐
- 1、对齐规则
- 2、存在内存对齐的原因
- 3、修改默认对齐数
- 三、结构体传参
- 四、结构体实现位段
一、结构体类型的声明
我们在指针终篇中提到过结构体的这一部分内容(详情请阅拙作终の指针)现在我们来整个展开叙述一下
1、结构的声明
struct tag
{member-list;
}variable-list;
花括号 { } 中放的是成员变量,结构的每个成员变量都可以是不同的类型,每一个被定义的结构体中都要有至少一个成员变量,结构是一些值的集合。
定义一个人
struct man
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//身份证号
};
2、结构体变量的创建和初始化
#include <stdio.h>
struct Stu
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//身份证号int main(){struct Stu s = { "张三", 18, "男", "111111200602023215" };//结构体顺序初始化struct Stu s2 = { .age = 19, .name = "lisi", .id = "111111200502023222", .sex = "⼥" };//指定顺序初始化return 0;
};
3、声明时的特殊情况
匿名结构体类型,如果没有对结构体进行重命名的话,仅能使用一次
struct
{int a;char b;float c;
}x;
形如上面代码的结构体未重命名的话,使用这一次便被回收
4、自引用
自引用的正确方法:
struct Node
{int data;struct Node* next;
};
通过结构体指针的形式来进行自引用
并且结构体自引用是不能用typedef重命名的
像这个:
typedef struct
{int a;Node* next;
}Node;
我们会在创建Node结构体之前在结构体当中使用Node,所以不可取
二、结构体内存对齐
结构体内存对齐是计算结构体大小的一个必备条件
1、对齐规则
①结构体的第一个成员对齐到结构体变量起始位置的地址
②其他成员变量要对齐到对齐数的整数倍的地址处
对齐数:编译器默认的对齐数与该成员变量大小的较小值(我所使用的vs2022默认对齐数为8)
③结构体总大小一定为对齐数的整数倍
④如果结构体中嵌套了结构体,嵌套的结构体对齐到对齐到自己成员中最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数的整数倍
我们可以将大小看作一个数组,每一个位置都是一个字节
struct S1
{char c1;//1字节,<8,就将1字节放在0位置处int i;//4字节,<8,因为1,2,3位置不是4的整数倍,所以我们直接找到4位置,将4个字节放入char c2;//1字节,<8,放在8位置处
};
又因为现在指向9位置处,9不是最大对齐数4的整数倍,所以要指向12处,所以结构体S1的大小为12字节
printf打印一下:

struct S2
{char c1;//1字节,放到0位置char c2;//1字节,放到1位置int i;//4字节,2不是4的整数倍,放到4位置
};
最终指向8位置,是4的整数倍,故S2的大小为8字节

struct S3
{double d;//8字节,放到0位置处char c;//1字节,放到8位置处int i;//4字节,9不是4的整数倍,放到12位置处,最终指向16
};
因为最大对齐数为8,16为8的整数倍,所以结构体S3的大小就是16个字节
struct S4
{char c1;//1字节,放到0位置处struct S3 s3;//16字节,以8为对齐数,放到8位置,最后指向24位置处double d;//8字节,放到24位置,最终指向32位置
};
32是最大对齐数8的整数倍,所以结构体S4的大小就是32个字节
2、存在内存对齐的原因
在数据访问时,对齐的内存只需要一次访问,而不对齐的内存需要两次访问
结构体的内存对齐是拿空间来换取时间
我们可以将占用内存小的尽量集中在一起来节省空间
struct S1
{char c1;int i;char c2;
};
struct S2
{char c1;char c2;int i;
};
3、修改默认对齐数
#pragma
#include <stdio.h>
#pragma pack(1)//设置默认对⻬数为1
struct S
{char c1;//1字节,存到0位置int i;//4字节,默认对齐数为1小于4,存到1位置char c2;//1字节,存到5位置,指向6
};
#pragma pack()//取消设置的对⻬数,还原为默认
int main()
{printf("%d\n", sizeof(struct S));return 0;
}

三、结构体传参
struct S
{int data[100];int num;
};
struct S s = { {1,2,3,4}, 1000 };
void print(struct S* ps)
{printf("%d\n", ps->num);
}
int main()
{print(&s);return 0;
}
结构体传参的时候最好传一个地址,因为直接传一个结构体过去的话会造成时间和空间上不必要的开销,导致性能下降
四、结构体实现位段
位段的成员可以是int , unsigned int , signed int ,char类型的
位段不跨平台,可移植程序应该避免使用位段
struct S
{char a : 3;char b : 4;char c : 5;char d : 4;
};
struct S s = { 0 };
int main()
{s.a = 10;s.b = 12;s.c = 3;s.d = 4;printf("%d\n", s.a);printf("%d\n", s.b);printf("%d\n", s.c);printf("%d\n", s.d);}


这里的a存入了10,由于位段作用,被存入a的二进制数为010,用整数形式打印,第一位为0,为正数,以第一位补位到32位,即00000000 00000000 00000000 00000010,即为2
这里的b存入了12,由于位段作用,被存入b的二进制数为1100,用整数形式打印,第一位为1,为负数,补1到11111111 11111111 11111111 11111100,这是补码,然后取反加一为原码,即10000000 00000000 00000000 00000100,即为-4
这里的c存入了3,由于位段作用,被存入c的二进制数为00011,用整数形式打印,第一位为0,为正数,以第一位补位到32位,即00000000 00000000 00000000 00000011,即为3
这里的d存入了4,由于位段作用,被存入a的二进制数为0100,用整数形式打印,第一位为0,为正数,以第一位补位到32位,即00000000 00000000 00000000 00000100,即为4
但是它空间的开辟是这样的:

第一个数据:二进制的01100010,十六进制的0x62
第二个数据:二进制的00000011,十六进制的0x03
第三个数据:二进制的00000100,十六进制的0x04

可以看到我们的结构体中存放的数据是62 03 04 00,与上述分析相符
跟结构体相比,位段可以达到同样的效果,并且可以很好的节省空间,缺点是有跨平台的问题存在
因为地址的分配是以字节为单位的,位段下的某些数据是没有地址的,所以位段数据不能用指针来访问
今天的分享就到这了~

相关文章:
【C语言】结构体
个人主页点这里~ 结构体 一、结构体类型的声明1、结构的声明2、结构体变量的创建和初始化3、声明时的特殊情况4、自引用 二、结构体内存对齐1、对齐规则2、存在内存对齐的原因3、修改默认对齐数 三、结构体传参四、结构体实现位段 一、结构体类型的声明 我们在指针终篇中提到过…...
Git基础(24):分支回退
文章目录 前言放弃已修改的内容分支回退到指定commit 前言 将分支回退到之前的某个版本 开发中,可能开发某个功能不需要了,或者想要回退到之前历史的某个commit, 放弃后来修改的内容。 放弃已修改的内容 如果未提交,直接使用 …...
复试专业前沿问题问答合集1
复试专业前沿问题问答合集1 人工智能基础知识问答 Q1: 什么是人工智能(AI)? A1: 人工智能(AI)是计算机科学的一个分支,它涉及创建能够执行通常需要人类智能的任务的机器和软件。这些任务包括学习(获取信息并根据信息对其进行规则化以达到结论)、推理(使用规则达到近…...
C++标准库中提供的用于处理正则表达式的类std::regex
std 是 C 标准库的命名空间,包含了大量标准的 C 类、函数和对象。这些类和函数提供了广泛的功能,包括输入输出、容器、算法、字符串处理等。 通常,为了使用标准库中的对象和函数,需在代码中包含相应的头文件,比如 #in…...
.NET Core 服务实现监控可观测性最佳实践
前言 本次实践主要是介绍 .Net Core 服务通过无侵入的方式接入观测云进行全面的可观测。 环境信息 系统环境:Kubernetes编程语言:.NET Core ≥ 2.1日志框架:Serilog探针类型:ddtrace 接入方案 准备工作 DataKit 部署 DataK…...
AI基础知识扫盲
AI基础知识扫盲 AIGCLangchain--LangGraph | 新手入门RAG(Retrieval-Augmented Generation)检索增强生成fastGPT AIGC AIGC是一种新的人工智能技术,它的全称是Artificial Intelligence Generative Content,即人工智能生成内容。 …...
分布式系统面试全集通第一篇(dubbo+redis+zookeeper----分布式+CAP+BASE+分布式事务+分布式锁)
目录 分布式系统面试全集通第一篇什么是分布式?和微服务的区别什么是分布式分布式与微服务的区别 什么是CAP?为什么不能三者同时拥有分区容错性一致性可用性 Base理论了解吗基本可用软状态最终一致性 什么是分布式事务分布式事务有哪些常见的实现方案?2PC(Two Ph…...
Prompt-RAG:在特定领域中应用的革新性无需向量嵌入的RAG技术
论文地址:https://arxiv.org/ftp/arxiv/papers/2401/2401.11246.pdf 原文地址:https://cobusgreyling.medium.com/prompt-rag-98288fb38190 2024 年 3 月 21 日 虽然 Prompt-RAG 确实有其局限性,但在特定情况下它可以有效地替代传统向量嵌入 …...
线性代数 - 应该学啥 以及哪些可以交给计算机
AI很热,所以小伙伴们不免要温故知新旧时噩梦 - 线代。 (十几年前,还有一个逼着大家梦回课堂的风口,图形学。) 这个真的不是什么美好的回忆,且不说老师的口音,也不说教材的云山雾绕,单…...
力扣面试150 Pow(x, n) 快速幂 负指数
Problem: 50. Pow(x, n) 解题方法 👨🏫 参考题解 复杂度 时间复杂度: O ( l o g 2 n ) O(log_{2}n) O(log2n) 空间复杂度: O ( 1 ) O(1) O(1) Code class Solution {public double myPow(double x, int n){if (x 0.0f)return 0.0d;long b…...
连接navicat报错2059 解决办法
这里写自定义目录标题 连接navicat报错2059 解决办法 连接navicat报错2059 解决办法 打开终端工具输入 mysql -hlocalhost -uroot -p回车(enter),输入密码后进入 mysql 。(PS: -h 后面是数据库地址, -u 后…...
Unity-UGUI系统
UGUI是什么 UGUI是Unity引擎内自带的UI系统官方称之为:Unity Ul 是目前Unity商业游戏开发中使用最广泛的UI系统开发解决方案 它是基于Unity游戏对象的UI系统,只能用来做游戏UI功能 不能用于开发Unity编辑器中内置的用户界面 六大基础组件 概述 Canvas EventS…...
配置AC和AP上报KPI指标信息实验
配置AC和AP上报KPI指标信息示例 组网图形 图1 AP直接上报KPI指标 图2 AP通过AC透传上报KPI指标 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件 业务需求 在云管理的ACFIT AP组网中,通过WMI上报机制,将AC和AP的KPI指标信息上报到iMast…...
深度学习Trick
Vscode查看文件目录 cmdshiftp选择->查看:将焦点置于辅助侧栏 View: Focus into Secondary Side Bar把主边栏的大纲拖入 快捷查看卷积过程,利用 torchinfo 在 model 下打断点F5 运行调试,F10 运行下一步在调试控制台输入from torchinfo…...
c++顺序表(连续插入删除)
Description 建立顺序表的类,属性包括:数组、实际长度、最大长度(设定为1000) 该类具有以下成员函数: 构造函数:实现顺序表的初始化。 插入多个数据的multiinsert(int i, int n, int item[])函数&#x…...
[综述笔记]A Survey on Deep Learning for Neuroimaging-Based Brain Disorder Analysis
论文网址:Frontiers | A Survey on Deep Learning for Neuroimaging-Based Brain Disorder Analysis (frontiersin.org) 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论…...
【C++练级之路】【Lv.16】红黑树(冰与火的碰撞,红与黑的史诗)
快乐的流畅:个人主页 个人专栏:《C语言》《数据结构世界》《进击的C》 远方有一堆篝火,在为久候之人燃烧! 文章目录 引言一、红黑树的概念二、红黑树的模拟实现2.1 结点2.2 成员变量2.3 插入情况一:uncle在左ÿ…...
政安晨:【Keras机器学习实践要点】(三)—— 编写组件与训练数据
政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras实战演绎机器学习 希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正! 介绍 通过 Keras,您可以编写自定…...
数据库系统概论(超详解!!!) 第四节 关系数据库标准语言SQL(Ⅲ)
1.连接查询 连接查询:同时涉及多个表的查询 连接条件或连接谓词:用来连接两个表的条件 一般格式: [<表名1>.]<列名1> <比较运算符> [<表名2>.]<列名2> [<表名1>.]<列名1> BETWEEN [&l…...
如何使用Python进行网络安全与密码学【第149篇—密码学】
👽发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 用Python进行网络安全与密码学:技术实践指南 随着互联网的普及,网络…...
Nacos CVE-2021-29442:Spring Boot Actuator未授权访问漏洞深度解析
1. 这个漏洞不是“改个配置就能修好”的那种 Nacos CVE-2021-29442,这个名字在2021年中后期的Java中间件运维圈里,曾让不少团队在凌晨三点被电话叫醒。它不是那种需要你翻文档、查API、调参数的常规问题,而是一个典型的“默认行为埋雷”——…...
别再乱改sshd_config主文件了!Ubuntu 22.04下用sshd_config.d目录的正确姿势
Ubuntu 22.04下SSH配置管理的现代实践:告别直接修改sshd_config的时代 在Linux系统管理中,SSH服务的配置一直是个看似简单实则暗藏玄机的领域。许多管理员至今仍保持着直接修改 /etc/ssh/sshd_config 文件的习惯,却不知道Ubuntu等现代Linux…...
明日方舟桌宠Ark-Pets显卡优化配置指南:3步实现流畅桌面动画
明日方舟桌宠Ark-Pets显卡优化配置指南:3步实现流畅桌面动画 【免费下载链接】Ark-Pets Arknights Desktop Pets | 明日方舟桌宠 (ArkPets) 项目地址: https://gitcode.com/gh_mirrors/ar/Ark-Pets Ark-Pets是一款基于《明日方舟》角色模型的桌面宠物软件&am…...
文档自动化下载革命:30+平台一键下载解决方案
文档自动化下载革命:30平台一键下载解决方案 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档,但是相关网站浏览体验不好各种广告,各种登录验证,需要很多步骤才能下载文档,该脚本就是为了解决您的烦…...
Nodejs后端服务集成Taotoken多模型API的实践路径
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 Nodejs后端服务集成Taotoken多模型API的实践路径 对于Node.js后端开发者而言,将大模型能力集成到现有应用中是常见的需…...
哔哩下载姬DownKyi:零基础掌握B站视频高效下载与管理
哔哩下载姬DownKyi:零基础掌握B站视频高效下载与管理 【免费下载链接】downkyi 哔哩下载姬downkyi,哔哩哔哩网站视频下载工具,支持批量下载,支持8K、HDR、杜比视界,提供工具箱(音视频提取、去水印等&#x…...
因果机器学习在制造业返工决策中的应用:以白光LED产线为例
1. 项目概述:当因果推断遇上产线返工在制造业,尤其是像白光LED芯片制造这样的精密流程工业里,每天都有成千上万个生产批次(Lot)在产线上流转。每个批次在经过磷光体转换(Color Conversion)这一关…...
全面精通QuPath数字病理分析:实战应用全解析
全面精通QuPath数字病理分析:实战应用全解析 【免费下载链接】qupath QuPath - Open-source bioimage analysis for research 项目地址: https://gitcode.com/gh_mirrors/qu/qupath QuPath是一款专为生物医学研究和数字病理分析设计的开源软件,它…...
py每日spider案例之某视频网站请求接口完整代码
目标网址 const crypto = require(crypto); const https = require(https); const fs =...
2026运营经理进阶指南:从“执行者”到“数据操盘手”的能力跃迁
嘿,未来的运营总监们!👋 2026年的运营战场早已不是单纯拼“执行力”和“写文案”的时代了。你是否发现,只会盯着排期表催进度的运营,正逐渐被会用数据驱动业务增长、用AI提升效率的“操盘手”所取代?作为你…...
