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

【C语言】结构体、位段、枚举、联合(共用体)

结构体

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

结构体声明:struct是结构体关键字,结构体声明不能省略struct;

匿名结构体:只能在声明结构体的时候声明结构体成员,之后再想用这个结构体声明结构体成员时就不行了;因为匿名结构体只能用一次,没有结构体名字没有办法声明结构体成员;(只打算用一次的结构体)


 结构体变量的声明与初始化

结构体变量的初始化需要使用大括号进行初始化;

// 结构体成员的声明与初始化
struct student 
{ // 声明的是一个描写学生的结构体char name[20];int age;char sex[5];
} s1 = { "张三", 18, "男" }; // 声明的是结构体成员并初始化;
int main()
{struct student s2 = { "李四", 19, "女" }; // 声明的是结构体成员并初始化;struct student s3 = { .age = 20, .name = "王五", .sex = "男" }; // 指定初始化结构体成员变量,通过 . 指定;// 如果不指定初始化结构体成员变量,就顺序初始化;printf("%s %d %s\n", s1.name, s1.age, s1.sex);printf("%s %d %s\n", s2.name, s2.age, s2.sex);printf("%s %d %s\n", s3.name, s3.age, s3.sex);return 0;
}

 结构的自引用

可以包含同类型的结构体指针,但是不能包含同类型结构体;

#include <stdio.h>
struct Node
{int data; // 存储数据 -> 数据域struct Node* n; // 存放下一个节点的地址 -> 指针域// 可以包含同类型结构体指针,但是不能包含同类型结构体
};

结构体内存对齐

怎么对齐:

1、第一个成员在结构体偏移量为0的地址处存放;

2、其他成员变量要对齐到对齐数的整数倍的地址处;

3、对齐数:VS默认对齐数、结构体成员自身大小就是对齐数,取较小的对齐数

4、结构体总大小为最大对齐数的整数倍(每个成员都有一个对齐数),所有成员中的最大对齐数

5、嵌套结构体的对齐,嵌套的结构体要对齐到自身最大对齐数的整数位;结构体的大小就是所有成员中的最大对齐数的整数倍

为什么对齐:

1、不是所有硬件平台都能访问任意地址上的数据的,有些只能在特定位置处取某些特定数据;

2、结构体(尤其是栈)应该尽可能在自然边界上对齐;未对齐的内存,处理器需要访问两次;而对齐的只需访问一次;

3、结构体的内存对齐就是拿空间换取时间的;

如何节省空间:让占用空间小的成员集中在一起;

代码验证: 
#include <stdio.h>
int main()
{struct S{char c1;int a;double b;char c2;}s;struct S1{int a;char c1;char c2;double b;}s1;printf("%d\n", sizeof(s));printf("%d\n", sizeof(s1));return 0;
}

百度笔试题: 

 写一个宏,计算结构体中某变量相对于首地址的偏移(offsetof宏);

 offsetof宏的使用:
#include <stdio.h>
#include <stddef.h>
int main()
{struct S{char c1;int a;double b;char c2;}s;struct S1{int a;char c1;char c2;double b;}s1;// offsetof宏:结构体成员变量相对于首地址的偏移量printf("%d %d %d %d\n", offsetof(struct S, c1), offsetof(struct S, a), offsetof(struct S, b), offsetof(struct S, c2));printf("%d %d %d %d\n", offsetof(struct S1, a), offsetof(struct S1, c1), offsetof(struct S1, c2), offsetof(struct S1, b));printf("%d\n", sizeof(s));printf("%d\n", sizeof(s1));return 0;
}

结构体传参:

1、传值调用,形参相当于一份临时拷贝,修改形参不会改变实参;

2、传址调用,如果不加上const,修改新参就会改变实参;

3、传址调用比传值调用更节省空间,结构体传参尽量传址;


位段

1、设计位段的目的就是为了节省空间;

2、位段的成员必须是int、unsigned int、signed int(c99之后,其他类型也可以,但是基本都是int、char类型);

3、位段的成员名后边有一个冒号和一个数字(数字表示几个比特位);

4、位段:为表示二进制位;

#include <stdio.h>
int main()
{struct S1 // 结构体{int a;int b;char c;};struct S2 // 位段{int a : 2;int b : 4;char c : 1;};printf("%d\n", sizeof(struct S1));printf("%d\n", sizeof(struct S2));return 0;
}

 位段的内存分配

1、不知道是从低位开始分配还是从高位才是分配,这是不确定的;


 位段的跨平台问题:

1、int位段被当成有符号数还是无符号数是不确定的;

2、位段中最大位的值是不确定的;

3、位段中的成员在内存中,从右到左还是从左到右分配标准未定义;

4、一个结构包含两个位段,第二个位段无法容纳于第一个位段剩余的位时,是舍弃位还是利用,是不确定的;


枚举

枚举类型的定义:

1、把可能的取值一一列举(月份、星期);

2、必须包含关键字enum;

3、枚举的值是默认从0一次递增的;

4、枚举常量的默认值是可以修改的;

#include <stdio.h>
enum Color
{RED, // 注意,这是逗号,不是分号GREEN,BLUE  // 最后这里什么符号都没有
};
enum Sex
{MALE = 2, // 枚举常量的默认值是可以修改的FEMALE = 4,CECRECY = 1
};
int main()
{printf("%d\n", RED);printf("%d\n", GREEN);printf("%d\n", BLUE); // 打印枚举常量printf("%d\n", FEMALE);return 0;
}

 枚举的优点:

1、枚举可以增加代码的可读性和可维护性;

2、#define是用于替换的,没有类型的,但枚举有类型检查;

3、可以一次定义多个常量;


联合(共用体)

1、联合定义的变量包含一系列的成员;

2、这些成员共用同一块空间,所以也叫做共用体;

3、在同一时间段内,联合体内的成员不能同时使用,只能使用其中一个;

4、如果修改联合体内其中一个成员的值,则另一个的值也会改变;

5、联合体的关键字:union;

#include <stdio.h>
union Un
{int a;char b;
};
int main()
{union Un un;un.a = 10;un.b = 'a'; printf("%d\n", sizeof(un)); // 大小是成员中较大的那个大小printf("%p\n", &un);printf("%p\n", &(un.a));printf("%p\n", &(un.b)); // 说明联合体共用一块空间return 0;
}

 联合体大小的计算

1、联合体的大小是最大成员的大小,这句话是错的;

2、联合体的大小至少是最大成员的大小;

3、当最大成员大小没有对齐到最大对齐数的整数倍时,就要对齐到最大对齐数的整数倍处;

#include <stdio.h>
union Un
{short a[7]; // 对齐数 2int b; // 对齐数 4// a占14个字节// 但是不是最大对齐数的整数倍// 所以联合体的大小是16
}un;
int main()
{printf("%d\n", sizeof(un));return 0;
}

相关文章:

【C语言】结构体、位段、枚举、联合(共用体)

结构体 结构&#xff1a;一些值的集合&#xff0c;这些值称为成员变量。结构体的每个成员可以是不同类型的变量&#xff1b; 结构体声明&#xff1a;struct是结构体关键字&#xff0c;结构体声明不能省略struct&#xff1b; 匿名结构体&#xff1a;只能在声明结构体的时候声…...

“Python+”集成技术高光谱遥感数据处理与机器学习深度应用

涵盖高光谱遥感数据处理的基础、python开发基础、机器学习和应用实践。重点解释高光谱数据处理所涉及的基本概念和理论&#xff0c;旨在帮助学员深入理解科学原理。结合Python编程工具&#xff0c;专注于解决高光谱数据读取、数据预处理、高光谱数据机器学习等技术难题&#xf…...

Excel 转为 PDF,PNG,HTML等文件

1.安装 Spire.XLS for Java,下载jar包 下载地址 2.引入方式一&#xff08;我这里这种方式一直无法引入&#xff0c;都是失败&#xff0c;所以用的方式二&#xff09; <repositories><repository><id>com.e-iceblue</id><name>e-iceblue</na…...

docker中使用GPU+rocksdb

配置环境 delldell-Precision-3630-Tower  ~  lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.6 LTS Release: 20.04 Codename: focaldelldell-Precision-3630-Tower  ~  nvcc --version nvcc: NVIDIA (R) Cuda comp…...

好用的跨平台同步笔记工具,手机和电脑可同步的笔记工具

在这个快节奏的工作环境中&#xff0c;每个人都在寻找一种方便又高效的方式来记录工作笔记。记录工作笔记可以帮助大家统计工作进展&#xff0c;了解工作进程&#xff0c;而如果工作中常在一个地方办公&#xff0c;直接选择电脑或者手机中笔记工具来记录即可&#xff0c;但是对…...

【Python 千题 —— 基础篇】浮点数转换为整数

题目描述 题目描述 整数转换为浮点数。 输入描述 输入一个整数。 输出描述 程序将整数转换为浮点数并输出。 示例 示例 ① 2输出&#xff1a; 2.0代码讲解 下面是本题的代码&#xff1a; # 描述: 整数转换为浮点数。 # 输入: 输入一个整数。 # 输出: 程序将整数转换…...

金融科技论文D部分

总结 以每周为例&#xff0c; 动量因子定义每种货币为前一周的回报率 价值因子定义为当前市值与其区块链中过去 7 天平均链上交易价值 利差因子定义为前 7 天硬币发行总量的负数除以在7天期限开始时未偿还的硬币量。 因素定义 为了避免过拟合&#xff0c;我们试图定义每一…...

Apache Tomcat下载安装配置使用超详细

下载安装 tomcat官网 在此我们以Tomcat 9.0.81为例&#xff0c;点击下载压缩包&#xff0c;解压到自己的文件夹。 tar.gz是linux操作系统下的安装版本。zip是windows系统下的压缩版本。Windows Service Installer是windows操作系统下的exe安装版本。 检查是否配置JDK 1.…...

基于Seata的分布式事务方案

在Seata中&#xff0c;有4种分布式事务实现方案 XA、AT、TCC、Saga 其中XA利用了数据库的分布式事务特性&#xff0c;AT相当于框架去控制事务回滚。TCC手写三个方法&#xff0c;saga手写两个方法。 AT的性能和编写比较折中&#xff0c;是最常用的一种。TCC一些视频教程中介绍…...

指令跳转:原来if...else就是goto

目录 CPU 是如何执行指令的&#xff1f; 从 if…else 来看程序的执行和跳转 如何通过 if…else 和 goto 来实现循环&#xff1f; 小结 你平时写的程序中&#xff0c;肯定不只有 int a 1 这样最最简单的代码或者指令。我们总是要用到 if…else 这样的条件判断语句、while 和…...

【数据库系统概论】第四章数据库安全性

数据库的安全性&#xff1a;保护数据库以防止不合法使用所造成的数据泄露、更改或破坏 grant和revoke语法...

如何正确的关闭Redis服务器

Redis官方原生版本是在Linux平台上开发和测试的&#xff0c;但是大多数初学者都是使用Windows系统来学习如何开发的。因此&#xff0c;官方提供了一个叫做“Microsoft Open Tech Redis”的项目&#xff0c;该项目专门为Windows平台提供了一个官方支持的Redis版本&#xff0c;但…...

MySQL日志管理和权限管理(重点)

目录 一、日志管理1.错误日志2.二进制日志3.慢查询日志 二、权限管理(重点)1.用户登录管理2.创建用户及授权3.刷新权限4.权限简介5.查看权限7.修改密码8、删除用户9、查看密码复杂度 一、日志管理 日志类型 1、错误日志&#xff1a;启动&#xff0c;停止&#xff0c;关闭失败报…...

Maven 使用教程(二)

一、如何创建JAR并将其安装在本地存储库中&#xff1f; 制作JAR文件非常简单&#xff0c;可以通过执行以下命令来完成&#xff1a; mvn package现在可以查看${project.basedir}/target目录&#xff0c;您将看到生成的JAR文件。 现在&#xff0c;您需要将生成的工件&#xff0…...

[Swift]同一个工程管理多个Target

1.准备 先创建一个测试工程“ADemo”&#xff0c;右键其Target选择Duplicate&#xff0c;再复制一个Target为“ADemo2”。 再选择TARGETS下方的“”&#xff0c;添加一个APP到项目中&#xff0c;这个命名为“BDemo”。 2、管理多个Target 可以对三个target分别导入不同的框…...

DevExpress Reporting中文教程 - 如何在macOS等系统中生成导出报表文档

DevExpress Reporting是.NET Framework下功能完善的报表平台&#xff0c;它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集&#xff0c;包括数据透视表、图表&#xff0c;因此您可以构建无与伦比、信息清晰的报表。 在本文中&#xff0c;我们将讨论如何在.NET MA…...

1967作为子字符串出现在单词中的字符串数目

java解法&#xff0c;程度&#xff1a;简单 说明 给你一个字符串数组 patterns 和一个字符串 word &#xff0c;统计 patterns 中有多少个字符串是 word 的子字符串。返回字符串数目。 子字符串 是字符串中的一个连续字符序列。 示例 1&#xff1a; 输入&#xff1a;patter…...

CocosCreator 面试题(二)JavaScript中的prototype的理解

1、原型&#xff08;prototype&#xff09;的作用 在JavaScript中&#xff0c;每个函数都有一个特殊的属性叫做"prototype"&#xff0c;它是一个对象。 原型&#xff08;prototype&#xff09;在JavaScript中用于实现对象之间的继承和共享属性。当创建一个函数时&am…...

python:从Excel或者CSV中读取因变量与多个自变量,用于训练机器学习回归模型,并输出预测结果

作者:CSDN @ _养乐多_ 本文详细记录了从Excel读取用于训练机器学习模型的数据,包括独立变量和因变量数据,以供用于机器学习模型的训练。这些机器学习模型包括但不限于随机森林回归模型(RF)和支持向量机回归模型(SVM)。随后,我们将测试数据集应用于这些模型,进行预测和…...

pycharm连接gitlab

1、下载安装gitlab 下载地址&#xff1a;Git - Downloading Package 下载后傻瓜式安装&#xff0c;注意勾选配置环境变量 未配置自己配置&#xff0c;电脑-属性-高级系统配置-环境变量 系统变量path&#xff1a;添加git安装目录下bin目录 2、检验安装完成 桌面右键git-open…...

【C/C++数据结构 - 2】:稳定性与优化揭秘,揭开插入排序、希尔排序和快速排序的神秘面纱!

文章目录 排序的稳定性插入排序插入排序的优化 希尔排序快速排序 排序的稳定性 稳定排序&#xff1a;排序前2个相等的数在序列中的前后位置顺序和排序后它们2个的前后位置顺序相同。&#xff08;比如&#xff1a;冒泡、插入、基数、归并&#xff09; 非稳定排序&#xff1a;排…...

PCL点云处理之基于强度特征的SIFT关键点提取法 (二百一十五)

PCL点云处理之基于强度特征的SIFT关键点提取法 (二百一十五) 一、算法介绍二、具体实现1.代码2.效果一、算法介绍 继续SIFT关键点的提取介绍,之前已经基于高程和颜色分别提取了关键点,这里是基于强度信息,若遇到文件无法读取强度问题,请参考上一篇博文,下面是具体的实现…...

uniapp打包配置

安卓&#xff1a; 首先不管是什么打包都需要证书&#xff0c;安卓的证书一般都是公司提供或者自己去申请。然后把包名等下图框住的信息填上&#xff0c;点击打包即可。 ios&#xff1a;ios需要使用mac到苹果开发者平台去申请证书&#xff0c;流程可以参考下边的链接 参考链接…...

人大金仓分析型数据库最大量限制

数据库支持的最大量限制&#xff1a; 维度 限制 数据库大小 无限 表大小 无限 行大小 1.6 TB 域大小 1 GB 每个表的行数 281474976710656 (2^48) 每个表 / 视图的列数 1600 每个表的索引数 无限 每个索引的列数 32 每个表的表级约束 无限 表名长度 63 字节 列出的“无限”…...

centos 里面的service自启动app.jar,出现两个java进程,app是同一个端口

当使用jps -lv查看java虚拟机进程 app.jar启动后&#xff0c;居然出现两个启动进程&#xff0c;而且他们的端口都一样&#xff0c;同一端口&#xff0c;是不允许启动两个相同app的。 使用进程ps查看进程工具 #ps -aux 参数说明&#xff1a; a: 显示跟当前终端关联的所有进…...

【算法|双指针系列No.7】leetcodeLCR 007. 三数之和

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…...

ubuntu修改IP地址

参考&#xff1a;ubuntu修改配置IP地址和DNS的方法总结&#xff08;4种&#xff09;_ubuntu设置ip地址-CSDN博客 面对ubuntu18以上的版本&#xff0c;主要有两种界面&#xff1a;图形化界面和纯命令行界面。 图形化界面配置比较简单&#xff0c;命令行配置稍许复杂&#xff0c…...

java springboot 通过ConfigurationProperties给第三方bean注入属性

之前我们的文章 java boot将一组yml配置信息装配在一个对象中 讲过了 通过ConfigurationProperties将配置文件中的内容默认装配进属性类 但 这建立在 bean是自己定义的 如果 这是个第三方的类呢&#xff1f; 就比如 我们在 application 中写了一套数据源的加载规则 但需要用第…...

windows系统安装openssl并且转换证书格式

概述 碎碎念&#xff0c;如果你有MAC电脑&#xff0c;就别折腾了&#xff0c;直接用MAC电脑吧,不用安装直接用openssl 本文主要讲到了openssl的基本使用方法&#xff0c;开发环境为windows&#xff0c;开发工具为VS2019.本文主要是说明openssl如何使用&#xff0c;不介绍任何理…...

【GO】基础速成

简单介绍一下go好处 编译语言&#xff0c;可以提前报错同时又有python的一些优点&#xff0c;自带多线程 开始学习 学习网站&#xff1a;学习网站 值 包含&#xff1a;字符串、整型、浮点型、布尔型等等 字符串可以 进行拼接。 需要注意的是布尔型在go里面不自动转化为in…...