自定义类型——结构体、枚举和联合
自定义类型——结构体、枚举和联合
- 结构体
- 结构体的声明
- 匿名结构体
- 结构体的自引用
- 结构体的初始化
- 结构体的内存对齐
- 修改默认对齐数
- 结构体传参
- 位段
- 枚举
- 联合
结构体
- 结构是一些值的集合,这些值被称为成员变量,结构的每个成员可以是不同类型的变量。
数组是一些值的结合,类型是相同的
结构体的声明
struct tag{member_list;}variable_list;//全局变量
- 这里通过前面的列表创建的变量是全局变量
typedef struct tag{member_list;}tag;//相当于struct tag
- typedef可以将复杂的类型简化
匿名结构体
struct{member_list;}variavle_list;//必须存在
- 匿名结构体类型,如果没有对结构体类型重命名,只能使用一次
结构体的自引用
//结构体的自引用
struct stu
{int age;struct stu* next;
};
typedef struct stu
{int age;struct stu* next;
}stu;
结构体的初始化
//结构体的初始化#include<stdio.h>
struct student
{char name[10];unsigned int age;char sex[5];
};int main(void)
{//初始化struct student n1 = { "张三",21,"男"};//打印printf("%s %u %s", n1.name, n1.age, n1.sex);return 0;
}
运行截图
结构体的内存对齐
//结构体的内存对齐
#include<stdio.h>
struct eg1
{int i;char j;char k;
};struct eg2
{char x;int y;char z;
};int main(void)
{//打印eg1printf("%zd\n", sizeof(struct eg1));//8//打印eg2printf("%zd\n", sizeof(struct eg2));//12return 0;
}
- 结构体对齐规则
1.结构体的第一个成员,对齐到结构体在内存中存放位置的0偏移处
2.从第二个成员开始,每个成员都要对齐到(一个对齐数)的整数倍处
对齐数:
结构体成员自身大小和默认对齐数的较小值在VS中:默认对齐数为8
Linux gcc:没有对齐数,对齐数就是成员自身大小
3.结构总大小为最大对齐数的较小值
4.如果结构体中嵌套了结构体成员,要将嵌套的成员对齐到自己的成员中最大对齐数的整数倍处
5.结构体的总大小必须是最大对齐数的整数倍,这里的最大对齐数是:包含嵌套结构体成员中的对齐数的所以对齐数中的最大值
- 结构体内存对齐的原因:
1.平台原因:
不是所有的硬件平台都能访问任意地址上的任意数据的,某些硬件平台只能在地址处取某些特定类型的数据,否则会抛出硬件异常
2.性能原因:
数据结构(尤其是栈)应该尽可能的在自然边界上对齐,原因在于,为了访问来对齐的内存,处理器需要作俩次内存访问,而对齐的内存仅需要一次访问
总结:
结构体的内存对齐是拿空间来换取时间的做法(满足对齐,节省空间:让占用空间小的成员尽量集中在一起)
修改默认对齐数
#pragma pack()可以设置默认对齐数
//修改默认对齐数
#include<stdio.h>
//修改默认对齐数为2
#pragma pack(2)struct eg1
{char s1;int s2;
};//恢复默认对齐数
#pragma pack()struct eg2
{char s1;int s2;
};int main(void)
{//打印eg1printf("%zd\n",sizeof(struct eg1));//6//打印eg2printf("%zd\n", sizeof(struct eg2));//8return 0;
}
总结:
结构在对齐方式不合适的时候,可以自己更改默认对齐数
结构体传参
//结构体传参
#include<stdio.h>struct eg
{int arr[100];char ch[20];
}s1 = { {1,2,3,4,5} ,"abcdef"};
//结构体传参
void print1(struct eg s1)
{printf("%s\n",s1.ch);
}
//结构体地址传参
void print2(struct eg* ps)
{printf("%s\n",ps->ch);
}
int main(void)
{//结构体传参print1(s1);//结构体地址传参print2(&s1);return 0;
}
运行截图:
- 总结:结构体传参的时候,要传结构体的地址
-
原因在于,函数传参的时候,参数是需要压栈,会有时间和空间上的系统开销
-
如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,所以导致性能下降
位段
- 位段的声明和结构体的声明基本相似,但也存在俩点不同:
1.位段的成员必须为int,unsigned int或者 signed int
2.位段的成员名后面有一个冒号和一个数字
//位段
#include<stdio.h>
struct eg
{int _a : 2;int _b : 5;int _c : 10;int _d : 20;
};int main(void)
{printf("%zd",sizeof(struct eg));return 0;
}
运行截图:
- 位段:二进制位,可以节省空间
位段的内存分配:
1.位段的成员可以是int,unsigned int,signed int或者是char (属于整数家族)类型
2.位段的空间上是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的
3.位段涉及很多不确定因素,位段时不跨平台的,注重可移植的程序应该避免使用位段
位段的跨平台问题:
1.int位段被当成有符号数还是无符号数是不确定的
2.位段中最大位的数目不能确定(16位机器最大16,32位机器最大32,写成27时可能在16位机器上出现问题)
3.位段中的成员在内存中从左到右分配,而且从右向左标准尚未定义
4.当一个结构包含俩个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的
总结:跟结构相比,位段可以达到同样的效果,但是可以很好的节省空间,但是有跨平台的问题存在
枚举
- 枚举:即一 一列举
//枚举
enum Day
{Mon,Tues,Wed,Thur,Fri,Sat,Sun
};enum Color
{Green,Blue,Red,Orange
};
enum Day和enum color都是枚举类型,{ }中的内容是枚举类型的可能取值,也叫枚举常量。这些枚举常量都是存在取值的,默认是从0开始,一次低递加1
- 也可以在定义的时候赋值
enum Day
{Mon = 1,Tues = 2,Wed = 3,Thur = 4,Fri = 5,Sat = 6,Sun = 7
};
枚举的优点:
1.增加代码的可读性和可维护性
2.和#define定义的标识符比较,枚举由类型检查,更加严谨
3.防止了命名污染(封装)
4.便于调试
5.使用方便,一次可以定义多个变量
联合
- 联合同样也是一种自定义类型,这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共同体)
//联合
union eg
{char i;int j;
};
- 特点:
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)
- 联合大小的计算:
1.联合的大小至少是最大成员的大小
2.当最大成员大小不是最大对齐数的整数的时候,就有对齐到最大对齐数的整数倍
//联合
#include<stdio.h>
union eg
{char i;int j;
};
int main(void)
{union eg s;printf("%p\n", &s.i);printf("%p\n", &s.j);return 0;
}
相关文章:

自定义类型——结构体、枚举和联合
自定义类型——结构体、枚举和联合 结构体结构体的声明匿名结构体结构体的自引用结构体的初始化结构体的内存对齐修改默认对齐数结构体传参 位段枚举联合 结构体 结构是一些值的集合,这些值被称为成员变量,结构的每个成员可以是不同类型的变量。 数组是…...

Windows11系统安装Mysql8之后,启动服务net start mysql报错“服务没有响应控制功能”的解决办法
问题 系统环境:Windows11 数据库版本:Mysql8 双击安装,一路下一步,完成,很顺利,但是开启服务后 net start mysql 报错: 服务没有响应控制功能。 请键入 NET HELPMSG 2186 以获得更多的帮助 不…...

WIFI模块的AT指令联网数据交互--第十天
1.1.蓝牙,ESP-01s,Zigbee, NB-Iot等通信模块都是基于AT指令的设计 初始配置和验证 ESP-01s出厂波特率正常是115200, 注意:AT指令,控制类都要加回车,数据传输时不加回车 1.2.上电后,通过串口输出一串系统…...

设计模式Java实现-迭代器模式
✨这里是第七人格的博客✨小七,欢迎您的到来~✨ 🍅系列专栏:设计模式🍅 ✈️本篇内容: 迭代器模式✈️ 🍱 本篇收录完整代码地址:https://gitee.com/diqirenge/design-pattern 🍱 楔子 很久…...

单页源码加密屋zip文件加密API源码
简介: 单页源码加密屋zip文件加密API源码 api源码里面的参数已改好,往服务器或主机一丢就行,出现不能加密了就是加密次数达到上限了,告诉我在到后台修改加密次数 点击下载...

47.全排列
1.题目 47. 全排列 II - 力扣(LeetCode)https://leetcode.cn/problems/permutations-ii/description/ 2.思路 注意剪枝的条件 3.代码 class Solution {vector<int> path;vector<vector<int>> ret;bool check[9]; public:vector<…...

呼叫中心系统选pscc好还是okcc好
选择PSCC(商业软件呼叫中心)还是OKCC(开源呼叫中心),应基于以下几个关键因素来决定: 技术能力:如果企业拥有或愿意投入资源培养内部技术团队,开源解决方案可能更合适,因为…...

【SRC实战】前端脱敏信息泄露
挖个洞先 https://mp.weixin.qq.com/s/xnCQQCAneT21vYH8Q3OCpw “ 以下漏洞均为实验靶场,如有雷同,纯属巧合 ” 01 — 漏洞证明 一、前端脱敏,请求包泄露明文 “ 前端脱敏处理,请求包是否存在泄露? ” 1、获取验…...

区块链 | NFT 水印:Review on Watermarking Techniques(三)
🍍原文:Review on Watermarking Techniques Aiming Authentication of Digital Image Artistic Works Minted as NFTs into Blockchains 一个 NFT 的水印认证协议 可以引入第三方实体来实现对交易的认证,即通过使用 R S A \mathsf{RSA} RSA…...

初识C语言——第十九天
for循环 1.简单概述 2.执行流程 3.建议事项:...

软件需求工程习题
1.(面谈)是需求获取活动中发生的需求工程师和用户间面对面的会见。 2.使用原型法进行需求获取,(演化式)原型必须具有健壮性,代码质量要从一开始就能达到最终系统的要求 3.利用面谈进行需求获取时…...

Win10弹出这个:https://logincdn.msauth.ne
问题描述: Win10脚本错误 Windows10家庭版操作系统开机后弹出这个 https://logincdn.msauth.net/shared/1.0/content/js/ConvergedLogin_PCore_vi321_9jVworKN8EONYo0A2.js 解决方法: 重启计算机后手动关闭第三方安全优化软件,然后在任务管理…...
Vue2 动态路由
VUE CLI 项目 router.js import Vue from "vue"; import Router from "vue-router"; import base from "/view/404/404.vue";const originalPush Router.prototype.push Router.prototype.push function push (location) {return originalPu…...

LeetCode746:使用最小花费爬楼梯
题目描述 给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 请你计算并返回达到楼梯顶部的最低花费。 代码 …...

DockerFile介绍与使用
一、DockerFile介绍 大家好,今天给大家分享一下关于 DockerFile 的介绍与使用,DockerFile 是一个用于定义如何构建 Docker 镜像的文本文件,具体来说,具有以下重要作用: 标准化构建:提供了一种统一、可重复…...
Java基础知识(六) 字符串
六 字符串 6.1 String字符串 1、String类对象创建 定义String类对象格式:** 1)String 字符串变量名“字符串常量”; 2)String 字符串变量名new String(字符串常量); 3)String 字符串变量名; 字符串变量名“字符串常…...

为什么跨境电商大佬都在自养号测评?看完你就懂了!
在跨境电商的激烈竞争中,各大平台如亚马逊、拼多多Temu、shopee、Lazada、wish、速卖通、煤炉、敦煌、独立站、雅虎、eBay、TikTok、Newegg、Allegro、乐天、美客多、阿里国际、沃尔玛、Nike、OZON、Target以及Joom等,纷纷成为商家们竞相角逐市场份额的焦…...
AtCoder Beginner Contest 353
A 题意:检查是否有比第一个数大的数 #include<bits/stdc.h>using namespace std;int main() {int n;cin>>n;int a;cin>>a;int f0;for(int i2;i<n;i){int k;cin>>k;if(k>a){cout<<i<<endl;f1;break;}}if(f0){cout<&l…...

深度解读《深度探索C++对象模型》之虚继承的实现分析和效率评测(一)
目录 前言 具有虚基类的对象的构造过程 通过子类的对象存取虚基类成员的实现分析 接下来我将持续更新“深度解读《深度探索C对象模型》”系列,敬请期待,欢迎左下角点击关注!也可以关注公众号:iShare爱分享,或文章末…...

计算机Java项目|Springboot房产销售系统
作者主页:编程指南针 作者简介:Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容:Java项目、Python项目、前端项目、人工智能与大数据、简…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...
高防服务器价格高原因分析
高防服务器的价格较高,主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因: 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器,因此…...
[特殊字符] 手撸 Redis 互斥锁那些坑
📖 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作,想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁,也顺便跟 Redisson 的 RLock 机制对比了下,记录一波,别踩我踩过…...

Mysql故障排插与环境优化
前置知识点 最上层是一些客户端和连接服务,包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念,为通过安全认证接入的客户端提供线程。同样在该层上可…...
2.2.2 ASPICE的需求分析
ASPICE的需求分析是汽车软件开发过程中至关重要的一环,它涉及到对需求进行详细分析、验证和确认,以确保软件产品能够满足客户和用户的需求。在ASPICE中,需求分析的关键步骤包括: 需求细化:将从需求收集阶段获得的高层需…...