当前位置: 首页 > 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…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...