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

C语言自定义类型结构体

 

variable

adj.易变的,多变的;时好时坏的;可变的,可调节的;

(数)(数字)变量的;(植,动)变异的,变型的;(齿轮)变速的

n.可变性,可变因素;(数学中的)变量,变元;

(计算机)变量(元);(天文)变星的简称;

(东北信风带以北或南半球的东南信风带与西风带之间的)变风区

前言:

在一开始学习C语言时,我们学习的是int,char...(内置类型),之后又学习数组(自定义类型),然后又学习了指针类型,基本的类型我们都学习的差不多了,今天在为大家带来自定义类型中的三大类型:结构体类型、共用体类型和枚举类型。

1.定义

结构体其实就是各种类型数据的结合体。

比如:对于一个学生而言,学生的属性就有他的名字,性别,年级,成绩等等,为了将这些属性都存储在一起,这时就需要新的自定义类型来进行将不同类型的数据进行整合,这就是结构体类型。

2.创建方式

 ⚀声明方式:

struct  str_name
{number_var;number_var;...
};
  • struct        创建结构体类型时的关键字        
  • str_name        struct_name结构体类型的名字
  • number_var        number_varible结构体内的成员变量

注意:

  1. 结构体类型的成员变量不能被初始化
  2. struct str_name这两个合在一起才被称为结构体类型。
  3. 结构体的声明一定在使用前进行声明不能在后声明。
  4. 结构体成员变量可以是任何类型,但绝对不可以成员变量含有自身结构体结构体。

        对于这种结构体是不允许创建的,因为你的结构体成员里面的又有自身的结构体,你这个成员变量的结构体里面又含有结构体,如此下去,结构体里含结构体,那么这个结构体的大小的有多大?答案是:不知道,很大很大很大!!!大到溢出!!!所以这种方式是不允许的!!! 

例子:

//以一个学生为例,声明一个结构体
struct Stu
{char name;//名字int age;//年龄int height;//体重int arr[10];//各科的成绩
}

typedef重命名

//以一个学生为例,声明一个结构体
typedef struct Stu //定义的结构体前加上typedef关键字
{char name;//名字int age;//年龄int height;//体重int arr[10];//各科的成绩
}Stu;//在定义完后面加上重新命名的名字
struct Stu S1;//使用struct定义的名字创建变量
Stu S2;//使用typedef重命名的名字创建变量
//不在声明时重命名
typedef struct Stu Stu;//typedef关键字+原名+新名字;

变量创建方式:

A.在声明时

//以一个学生为例,声明一个结构体
struct Stu 
{char name;//名字int age;//年龄int height;//体重int arr[10];//各科的成绩
}S1,S2,S3;
//在声明完结构体后,在后面接着创建结构体变量

B.通过结构体类型

//以上面的struct Stu结构体为例
struct Stu S1;//通过结构体类型创建结构体变量

 特殊声明:

struct    //不声明结构体类型名字
{char name;//名字int age;//年龄int height;//体重int arr[10];//各科的成绩
}S1;//创建结构体变量
  • 这种在声明结构体时不声明结构体类型名,而在声明后接着创建结构体变量的操作就称为结构体的匿名声明。
  • 对于这种没有将结构体类型名的结构体,就意味着不能通过结构体类型来创建结构体变量,这种只能使用它后面的结构体变量,可以称为一次性结构体。

 自引用:

        在结构体声明时,我们讨论过不能在结构体内部创建自身的结构体变量进行使用,因为会使得结构体内存大小溢出,那么有什么方法可以实现能在结构体中自引用自己这个结构体呢?

答案是:自己的结构体指针

3.使用方式

访问成员操作:

A.操作符' . '

结构体变量名.成员变量名

str_name.number_var_name1
S1.age = 21;

通过结构体类型变量访问

B.操作符" -> "

结构体指针->成员变量名

str_piont_name.number_var_name1
struct Stu* p;//结构体指针
p->age = 21;

通过结构体指针变量访问 

初始化操作:

按照结构体变量初始化的位置分:

A.在声明时创建变量时

B.通过结构体类型创建时

按照成员变量初始化的顺序分:

A.声明时顺序初始化:

B.指定顺序初始化:

结构体的传值or传址 ?

        由于结构体在内存中的存储满足内存对齐,就会存在内存浪费,加之结构体时多种的数据类型的集合,内存空间就会非常大,就不推荐使用传值调用,会拷贝数据压栈(在栈区上开辟空间,会浪费空间,溢出等),所以结构体进行调用时最好时传址调用。

4.存储方式

        首先我们来看一下下面这个结构体的内存大小:

Why?为啥不是6个字节,不是这几个类型得字节数相加?难道是2倍关系 ?

其实小编可以告诉大家不是啦,结构体在内存中得存储是一种新的方式:内存对齐

那么下面让我们一起看一下什么是内存对齐,小编先为大家介绍内存对齐的规则,嘻嘻

内存对齐规则:

假设有段内存空间,结构体就存储在这上面,那么在存储前先要对这块空间的内存单元进行编号,而成员变量的存储方式就与这些编号有关,这种方式就是内存对齐。

  1. 第一个成员变量默认从编号0的位置开始存储。
  2. 后面的成员变量对齐的编号(对齐数)是{编译器默认的对齐数,成员变量的大小(字节)}min的整数倍。
  3. 最后结构体的内存空间大小还需满足是:{编译器默认的对齐数,成员变量的大小(字节)}min的整数倍。

注意:

  • 如果是结构体里面含有结构体,那么不是按照这结构体的大小去和编译器默认的对其数比较,而是该结构体内部最大的成员变量的字节数去进行比较。
  • VS编译器默认的对其数是8,gcc编译器没有默认的对齐数,对其数就是成员变量本身。

例子:

结构体里嵌套结构体

修改默认对齐数:

对于VS编译器,我们可以通过#pragma操作修改默认对其数:

对其数为8时
对其数为1时

为什么存在内存对齐? 

【补充】

结构体的内存对齐是为了**提高数据访问的效率以及满足特定硬件和操作系统的要求**。具体原因包括:

  1. 性能优化:CPU访问内存时,对齐的内存可以更快被读取。不对准的内存访问可能会导致多次内存访问才能获取全部数据,降低效率。
  2. 硬件要求:某些硬件平台要求特定的数据类型必须在特定地址边界上开始,如2的幂次方边界(4字节、8字节等)。
  3. 减少填充:对齐可以减少或消除数据结构中的填充字节,使得结构更紧凑,节省内存空间。
  4. 跨平台兼容性:不同的系统可能有不同的对齐要求,对齐可以确保代码在不同平台上的一致性和兼容性。
  5. 指令集优化:某些CPU指令集在处理对齐数据时更为高效,因此对齐可以提高指令执行的速度。
  6. 缓存机制:现代CPU的缓存机制通常以特定的对齐边界来存储和检索数据,对齐有助于提高缓存命中率。
  7. 数据结构对齐规则:结构体的第一个成员与结构体的起始地址对齐,其他成员根据其类型的最大对齐要求进行对齐。
  8. 默认对齐数:编译器通常有默认的对齐数值,但可以通过编译器指令或特定的编译器选项来修改。
  9. offsetof宏:在处理结构体时,`offsetof`宏可以用来获取成员在结构体中的偏移量,这对于理解和操作结构体非常有用。

综上所述,结构体的内存对齐是计算机编程中的一个重要概念,它关系到程序的性能、硬件兼容性以及代码的可维护性。了解并正确应用内存对齐规则,对于编写高效且健壮的程序至关重要。

【转载自百度】

5.位段

定义:

  • 结构体的位段是一种特殊类型的成员,它允许程序以bit(比特位)为单位来定义结构体成员变量在内存中所占空间的大小。
  • 位段的定义是在成员变量后面+冒号+大小(比特位)进行限定大小。
  • 成员必须是int,unsigned int或[signed] char,在C99标准中也可以使用其他类型。
  • 位段的主要目的是节约存储空间。
int a:5;
char b:3;

存储方式:

  1. 含有位段的结构体进行存储时,按需来开辟空间的,如果是int类型就开4个字节,char类型就开1个字节
  2. 位段成员是优先存为上个位段开辟空间里,如果下个位段成员存不进上一个位段成员开辟的空间,是舍弃空间还是利用空间是无法确定的。
  3. 多个位段是可能共用同一块内存空间的。
  4. 因为只有内存单元有地址,那么对于位段的成员变量的存储是从内存单元的左边开始存还是右边开始存是未知的

下面以VS编译器为例:


 

正确解析
错误解析

注意事项:

  • 位段中最大位的数目不能确定,比如16位机器最大16,32位机器最大32,写成27,在16位机器会出问题。
  • 通过前面的分析,在位段的存储方式上和最大位数上有很大的不确定性,所以位段是不跨平台的,注重可移植的程序应该避免使⽤位段。
  • 位段是按位存储的,所以对于位段成员的结构体,不要用scanf取地址存数值,存的数值可能会被截取,就不是想要的数据。

本章内容结束,下章见,拜拜!!!

相关文章:

C语言自定义类型结构体

variable adj.易变的,多变的;时好时坏的;可变的,可调节的; (数)(数字)变量的;(植,动)变异的,变型的&#xff1…...

【SpringBoot框架篇】37.使用gRPC实现远程服务调用

文章目录 RPC简介gPRC简介protobuf1.文件编写规范2.字段类型3.定义服务(Services) 在Spring Boot中使用grpc1.父工程pom配置2.grpc-api模块2.1.pom配置2.2.proto文件编写2.3.把proto文件编译成class文件 3.grpc-server模块3.1.pom文件和application.yaml3.2.实现grpc-api模块的…...

投资的三个匹配

许多人亏钱都是犯了同样错误,要么对投资的预期过高,要么是投资期限不匹配,要么是波动承受能力不匹配。投资想要赚钱,先解决匹配问题。 1.预期收益率要匹配 就是明确自己做投资,每年想赚多少钱。凡事都要有个目标&…...

[Netty实践] 请求响应同步实现

目录 一、介绍 二、依赖引入 三、公共部分实现 四、server端实现 五、client端实现 六、测试 一、介绍 本片文章将实现请求响应同步,什么是请求响应同步呢?就是当我们发起一个请求时,希望能够在一定时间内同步(线程阻塞&am…...

Java进阶—哈希冲突的解决

1. 什么是哈希冲突 哈希函数:哈希函数是一种将输入数据(键)映射到固定大小范围的输出值(哈希值)的函数。哈希函数通常用于存储 数据存储和检索领域,例如哈希表中。 哈希表:哈希表(Hash Table),也成为哈希映射(Hash Map)或字典&…...

css的border详解

CSS的border属性是一个简写属性,用于设置以下四个边框属性: border-width:定义边框的宽度。可以使用具体的像素值,或者使用预定义的关键字如thin、medium和thick。border-width不支持百分比值。默认情况下,边框的宽度是…...

如何保障消息一定能发送到RabbitMQ?

我们知道,RabbitMQ的消息最终是存储在Queue上的,而在Queue之前还要经过Exchange,那么这个过程中就有两个地方可能导致消息丢失。第一个是Producer到Exchange的过程,第二个是Exchange到Queue的过程。 为了解决这个问题&#xff0c…...

【web前端】CSS语法

CSS语法 1. CSS语法格式 通常情况下语法格式如下: 选择器{属性名:属性值;属性名:属性值;属性名:属性值;... }2. CSS添加方式 2.1 行内样式 直接将样式写在本行的标签内。 <h1><p style"font-size: 48px; color:red;";>行内样式测试</p></…...

JS+CSS3点击粒子烟花动画js特效

JSCSS3点击粒子烟花动画js特效 JSCSS3点击粒子烟花动画js特效...

docker镜像复制与常见命令

一、前言 最近通过阿里的镜像仓库远程拉取镜像&#xff0c;发现以前的版本不见了&#xff0c;拉取了最新的镜像&#xff0c;有发现版本不配问题。那么想使用老版本的镜像那就要从别的环境获取。于是就需要进行离线镜像复制&#xff0c;打包&#xff0c;上传&#xff0c;重新导入…...

如何在linux环境上部署单机ES(以8.12.2版本为例)

ES安装&#xff08;以8.12.2版本为例&#xff09; 首先创建好对应的文件夹然后在对应的文件夹下执行依次这些命令 1.wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.12.2-linux-x86_64.tar.gz 2.wget https://artifacts.elastic.co/downloads/…...

如何利用人工智能技术实现企业营销效率提升10倍(下)

01. AI在私域运营中可扮演重要角色 私域用户体验历程中的不满&#xff0c;对企业来说&#xff0c;无疑是一记沉重的打击。这些不满不仅会让用户感到失望和沮丧&#xff0c;更会在无形中侵蚀企业的各个环节&#xff0c;给业务带来不可估量的损失。 在私域环境中&#xff0c;每…...

【PHP + 代码审计】数组函数

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…...

Keepalive与idle监测及性能优化

Keepalive 与 idle监测 Keepalive&#xff08;保活&#xff09;: Keepalive 是一种机制&#xff0c;通常用于TCP/IP网络。它的目的是确保连接双方都知道对方仍然存在并且连接是活动的。这是通过定期发送控制消息&#xff08;称为keepalive消息&#xff09;实现的。如果在预定时…...

DS-红黑树(RBTree)

一.红黑树 1.1 红黑树的起源 当对对AVL树做一些结构修改的操作时候&#xff0c;性能较为低下&#xff0c;比如&#xff1a;插入时要维护其绝对平衡&#xff0c;旋转的次数比较多&#xff0c;更差的是在删除时&#xff0c;有可能一直要让旋转持续到根的位置。 因此1972年Rudolf…...

ubuntu 如何使用阿里云盘

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…...

sqlite3 交叉编译

#1.下载源码并解压 源码路径如下&#xff0c;下载autoconf版本 SQLite Download Page 解压 tar -zxvf sqlite-autoconf-3450200.tar.gz cd sqlite-autoconf-3450200 mkdir build # 2. 配置源代码 # 假设你已经安装了交叉编译工具链&#xff0c;如gcc-arm-linux-gnueabih…...

【AI生成文章】flutter ChangeNotifierProvider 实用场景举例

内容由Ai 大模型生成&#xff0c;不能完全保障真实 ChangeNotifierProvider 是 Flutter 中一个非常实用的工具&#xff0c;用于在应用程序中管理和传递状态。以下是一些实用的场景举例&#xff1a; 1. 用户信息管理 在应用程序中&#xff0c;用户信息&#xff08;如用户名、…...

【0274】从shared init file或local init file加载relation cache(2 - 1)

上一篇: 【0273】深入分析 relcache(relation descriptor cache)初始化第一阶段(1) 【0264】深入分析relcache(relation descriptor cache)缓存初始化第2阶段(2) 1. 前言 本文内容是作为《【0264】深入分析relcache(relation descriptor cache)缓存初始化第2阶段…...

蓝桥杯-02-2023蓝桥杯c/c++省赛B组题目

参考 2023 年第十四届蓝桥杯 C/C B组省赛题解 2023蓝桥杯c/c省赛B组题目(最全版)&#xff1a; A&#xff1a;日期统计 这题方法应该很多&#xff0c;没有和别人讨论想法。我的解法思路是&#xff1a;先 load 函数生成所有这一年的合法日期&#xff0c;然后枚举所有可以从数据…...

深圳实体门店有必要做GEO AI代运营吗

深圳实体门店有必要做GEO AI代运营吗一、开篇引言2026年深圳本地实体商业竞争进入白热化阶段&#xff0c;全城数百万家线下实体门店涵盖本地生活、家装工装、汽车服务、餐饮娱乐、教育培训等全品类&#xff0c;传统线下地推、门店自然客流、传统团购平台引流效果持续下滑&#…...

[智能体-81]:工程化智能体 = 模型做脑力拆解 + 框架做流程落地。前者是决策者,后者是管理者,tools/function call是内部员工;mcp server是外部资源;

一、全角色人设 & 对应技术组件角色定位对应技术模块核心职责决策者&#xff08;脑力大脑&#xff09;大模型 LLM理解目标、任务拆解、逻辑判断、分支决策、内容生成&#xff0c;负责 “想方案、定步骤”管理者&#xff08;流程总管&#xff09;智能体编排框架&#xff08;…...

HarmonyOS ArkTS DateUtil 日期增减与日历计算完整指南

文章目录 背景一、引言二、日期增减方法详解使用示例 三、日历计算方法详解四、Demo 演示&#xff1a;日期增减结果展示五、Demo 演示&#xff1a;月历视图完整实现六、日历视图关键点解析为什么要填充前置空格&#xff1f;getLastDayOfMonth 的实现技巧 七、小结 背景 近期发现…...

Veo 2提示词性能瓶颈诊断:基于1726组AB测试的token敏感度热力图与阈值红线预警

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;Veo 2提示词编写最佳实践总览 Veo 2 是 Google 推出的高性能视频生成模型&#xff0c;其对提示词&#xff08;prompt&#xff09;的语义精度、结构清晰度和上下文控制能力高度敏感。高质量提示词并非简单堆砌关…...

CausalVLR基准测试报告:在IU X-Ray和MIMIC-CXR数据集上的性能分析

CausalVLR基准测试报告&#xff1a;在IU X-Ray和MIMIC-CXR数据集上的性能分析 【免费下载链接】CausalVLR CausalVLR: A Toolbox and Benchmark for Vision-Language Causal Reasoning (多模态因果推理开源框架) 项目地址: https://gitcode.com/gh_mirrors/ca/CausalVLR …...

LVGL多页面开发避坑:用内部Timer替代轮询,解决页面切换时的内存踩踏问题

LVGL多页面开发中的内存安全实践&#xff1a;用Timer机制替代轮询的工程解决方案 在嵌入式UI开发中&#xff0c;LVGL因其轻量级和跨平台特性成为热门选择。但当项目复杂度提升到多页面交互时&#xff0c;开发者往往会遇到一个棘手问题&#xff1a;如何在频繁切换页面的同时保证…...

对比按量计费与Token Plan套餐的实际成本差异

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 对比按量计费与Token Plan套餐的实际成本差异 在构建和运营基于大模型的应用时&#xff0c;成本控制是一个核心的工程考量。Taotok…...

中小企无需重型数据中台:轻量化数据体系搭建完整方案

过去几年&#xff0c;“数据中台”一度成为企业数字化的标配热词。大量中小企业盲目跟风搭建重型数据中台&#xff0c;投入高额成本、耗费数月甚至数年周期&#xff0c;最终落地效果极差&#xff1a;功能冗余、运维复杂、使用率低、投入产出比失衡。大量项目最终沦为“摆设式中…...

【仅限首批200家认证用户】DeepSeek v3.2.1重复检测私有化部署补丁包(含GPU内存泄漏热修复+增量扫描加速模块)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;DeepSeek代码重复检测 DeepSeek-R1 模型在训练过程中引入了严格的代码去重机制&#xff0c;其核心目标是消除训练语料中语义等价或高度相似的代码片段&#xff0c;从而提升模型对真实编程模式的学习能力…...

当“画笔”变成“画笔”,世界便不再扁平:上海科技大学师玉娇团队 BevSplat 论文深度解读

用高斯画笔为地面图像“补上高度”&#xff0c;让卫星图片与街景的配对不再尴尬 想象一下这幅情境&#xff1a;一辆自动驾驶汽车在密集的城市楼群中行驶。GPS 信号被摩天大楼遮挡得断断续续&#xff0c;车辆根本无法准确知道自己的位置。于是&#xff0c;它需要一种备用方案&am…...