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

自定义类型——结构体、枚举和联合

自定义类型——结构体、枚举和联合

  • 结构体
    • 结构体的声明
    • 匿名结构体
    • 结构体的自引用
    • 结构体的初始化
    • 结构体的内存对齐
    • 修改默认对齐数
    • 结构体传参
  • 位段
  • 枚举
  • 联合

结构体

  • 结构是一些值的集合,这些值被称为成员变量,结构的每个成员可以是不同类型的变量。

数组是一些值的结合,类型是相同的

结构体的声明

	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;
}

在这里插入图片描述

相关文章:

自定义类型——结构体、枚举和联合

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

Windows11系统安装Mysql8之后,启动服务net start mysql报错“服务没有响应控制功能”的解决办法

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

WIFI模块的AT指令联网数据交互--第十天

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

设计模式Java实现-迭代器模式

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

单页源码加密屋zip文件加密API源码

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

47.全排列

1.题目 47. 全排列 II - 力扣&#xff08;LeetCode&#xff09;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&#xff08;商业软件呼叫中心&#xff09;还是OKCC&#xff08;开源呼叫中心&#xff09;&#xff0c;应基于以下几个关键因素来决定&#xff1a; 技术能力&#xff1a;如果企业拥有或愿意投入资源培养内部技术团队&#xff0c;开源解决方案可能更合适&#xff0c;因为…...

【SRC实战】前端脱敏信息泄露

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

区块链 | NFT 水印:Review on Watermarking Techniques(三)

&#x1f34d;原文&#xff1a;Review on Watermarking Techniques Aiming Authentication of Digital Image Artistic Works Minted as NFTs into Blockchains 一个 NFT 的水印认证协议 可以引入第三方实体来实现对交易的认证&#xff0c;即通过使用 R S A \mathsf{RSA} RSA…...

初识C语言——第十九天

for循环 1.简单概述 2.执行流程 3.建议事项&#xff1a;...

软件需求工程习题

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

Win10弹出这个:https://logincdn.msauth.ne

问题描述&#xff1a; Win10脚本错误 Windows10家庭版操作系统开机后弹出这个 https://logincdn.msauth.net/shared/1.0/content/js/ConvergedLogin_PCore_vi321_9jVworKN8EONYo0A2.js 解决方法&#xff1a; 重启计算机后手动关闭第三方安全优化软件&#xff0c;然后在任务管理…...

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 &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用&#xff0c;即可选择向上爬一个或者两个台阶。 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 请你计算并返回达到楼梯顶部的最低花费。 代码 …...

DockerFile介绍与使用

一、DockerFile介绍 大家好&#xff0c;今天给大家分享一下关于 DockerFile 的介绍与使用&#xff0c;DockerFile 是一个用于定义如何构建 Docker 镜像的文本文件&#xff0c;具体来说&#xff0c;具有以下重要作用&#xff1a; 标准化构建&#xff1a;提供了一种统一、可重复…...

Java基础知识(六) 字符串

六 字符串 6.1 String字符串 1、String类对象创建 定义String类对象格式&#xff1a;** 1&#xff09;String 字符串变量名“字符串常量”&#xff1b; 2&#xff09;String 字符串变量名new String(字符串常量); 3&#xff09;String 字符串变量名; 字符串变量名“字符串常…...

为什么跨境电商大佬都在自养号测评?看完你就懂了!

在跨境电商的激烈竞争中&#xff0c;各大平台如亚马逊、拼多多Temu、shopee、Lazada、wish、速卖通、煤炉、敦煌、独立站、雅虎、eBay、TikTok、Newegg、Allegro、乐天、美客多、阿里国际、沃尔玛、Nike、OZON、Target以及Joom等&#xff0c;纷纷成为商家们竞相角逐市场份额的焦…...

AtCoder Beginner Contest 353

A 题意&#xff1a;检查是否有比第一个数大的数 #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对象模型》”系列&#xff0c;敬请期待&#xff0c;欢迎左下角点击关注&#xff01;也可以关注公众号&#xff1a;iShare爱分享&#xff0c;或文章末…...

计算机Java项目|Springboot房产销售系统

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

学习3D几何和特征一致的高斯溅射目标去除

earning 3D Geometry and Feature Consistent Gaussian Splatting for Object Removal 学习3D几何和特征一致的高斯溅射目标去除 Yuxin Wang 王玉欣 HKUST &Qianyi Wu Monash University &Guofeng Zhang Zhejiang University &Dan Xu HKUST 香港科技大学&吴倩…...

PHP 使用常量实现枚举类

PHP 使用常量实现枚举类 <?php abstract class Enum {private static $constCacheArray NULL;private static function getConstants() {if (self::$constCacheArray NULL) {self::$constCacheArray [];}$calledClass get_called_class();if (!array_key_exists($call…...

Linux操作系统基础题库

一. 单选题&#xff08;共2题&#xff0c;40分&#xff09; 1. (单选题)Linux操作系统自诞生至今&#xff0c;有数十万的程序开发人员参与到了它的开发与完善中&#xff0c;如今Linux已发展成为是一个成熟、稳定的操作系统。从以下选项中选出关于Linux特点描述完全正确的一项。…...

Java抽象类:为何它是你代码架构的基石?

目录 1、抽象类的概念 2、抽象类语法 3、抽象类特性 4、抽象类的作用 5、 完结散花 个人主页&#xff1a;秋风起&#xff0c;再归来~ 文章专栏&#xff1a;javaSE的修炼之路 个人格言&#xff1a;悟已往之不谏&#xff0c;知来者犹可追 克…...

Flutter 中的 ToggleButtons 小部件:全面指南

Flutter 中的 ToggleButtons 小部件&#xff1a;全面指南 在 Flutter 中&#xff0c;ToggleButtons 是一种允许用户在一组选项中进行切换选择的控件。它通常用于展示一组相关选项&#xff0c;让用户可以快速切换选择。ToggleButtons 是一种水平排列的按钮集合&#xff0c;其中…...

【MYSQL】一颗B+树可以保存多少条数据

引言 事万物都有自己的单元体系&#xff0c;若干个小单体组成一个个大的个体。就像拼乐高一样&#xff0c;可以自由组合。所以说&#xff0c;如果能熟悉最小单元&#xff0c;就意味着我们抓住了事物的本事&#xff0c;再复杂的问题也会迎刃而解。 存储单元 存储器范围比较大…...

ssm125四六级报名与成绩查询系统+jsp

四六级报名与成绩查询系统的设计与实现 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对四六级报名信息管理混乱&am…...

【Unity从零开始学习制作手机游戏】第01节:控制3D胶囊体运动

1. 新建Project L01 使用3D Mobile模板。 2. 建立一个平面&#xff0c;用来承载物体 3. 导入Unity库内的胶囊体 下载 StandardAssets https://download.unitychina.cn/download_unity/e80cc3114ac1/WindowsStandardAssetsInstaller/UnityStandardAssetsSetup-5.6.7f1.exe …...

内容安全(DPI和DFI解析)

内容安全前言&#xff1a; 防火墙的本质其实就是包过滤&#xff0c;我们通常所说的安全设备&#xff08;如&#xff1a;IPS、IDS、AV、WAF&#xff09;的检测重心是应用层。下一代防火墙基于传统防火墙的拓展能力&#xff0c;就是可以将以上的安全设备模块集成在一起&#xff0…...

2024数维杯数学建模A题B题C题思路+模型+代码(开赛后第一时间更新)

2024数维杯数学建模A题B题C题思路模型代码&#xff08;开赛后第一时间更新&#xff09; https://mbd.pub/o/bread/ZpWakpdq https://mbd.pub/o/bread/ZpWakpdq 2024年第九届数维杯大学生数学建模挑战赛参赛规则 竞赛要求及论文提交方式; ①本次参赛作品统一在线提交到竞赛…...