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

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7

在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤&#xff1a; 第一步&#xff1a; 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为&#xff1a; // 改为 v…...

uni-app学习笔记三十五--扩展组件的安装和使用

由于内置组件不能满足日常开发需要&#xff0c;uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件&#xff0c;需要安装才能使用。 一、安装扩展插件 安装方法&#xff1a; 1.访问uniapp官方文档组件部分&#xff1a;组件使用的入门教程 | uni-app官网 点击左侧…...

32位寻址与64位寻址

32位寻址与64位寻址 32位寻址是什么&#xff1f; 32位寻址是指计算机的CPU、内存或总线系统使用32位二进制数来标识和访问内存中的存储单元&#xff08;地址&#xff09;&#xff0c;其核心含义与能力如下&#xff1a; 1. 核心定义 地址位宽&#xff1a;CPU或内存控制器用32位…...

未授权访问事件频发,我们应当如何应对?

在当下&#xff0c;数据已成为企业和组织的核心资产&#xff0c;是推动业务发展、决策制定以及创新的关键驱动力。然而&#xff0c;未授权访问这一隐匿的安全威胁&#xff0c;正如同高悬的达摩克利斯之剑&#xff0c;时刻威胁着数据的安全&#xff0c;一旦触发&#xff0c;便可…...

接口 RESTful 中的超媒体:REST 架构的灵魂驱动

在 RESTful 架构中&#xff0c;** 超媒体&#xff08;Hypermedia&#xff09;** 是一个核心概念&#xff0c;它体现了 REST 的 “表述性状态转移&#xff08;Representational State Transfer&#xff09;” 的本质&#xff0c;也是区分 “真 RESTful API” 与 “伪 RESTful AP…...