目录

前言

一、 联合体类型的声明

介绍:

注意:

二、 联合体的特点

介绍:

代码举例:

三、联合体⼤⼩的计算

介绍:

联合体大小的计算规则

1. 基础规则

1. 确定最大成员大小

2. 计算对齐模数的最小公倍数

3. 最终大小

结论

关键总结

结论

四、枚举类型的声明

介绍:

五、枚举类型的优点

介绍:

总结


前言

上一篇文章讲解结构体类型的声明、结构体变量的创建和初始化、结构成员访问操作符、结构体内存对⻬知识的相关内容,本篇文章将讲解联合体类型的声明、联合体的特点、联合体⼤⼩的计算、枚举类型的声明、枚举类型的优点、枚举类型的使⽤知识的相关内容。

一、 联合体类型的声明

介绍:

在C语言中,联合体(Union) 是一种特殊的数据类型,它允许在同一段内存空间中存储不同类型的数据,但同一时刻只能保存其中一种类型的值。以下是联合体类型的常见声明方式:

union 联合体标签名 {成员类型1 成员名1;成员类型2 成员名2;// ... 其他成员
};
  • 使用场景:声明后可通过 union 联合体标签名 定义变量。

代码例:

union Data {int num;float f;char str[20];
};
union Data data; // 定义联合体变量

注意:

1.像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以是不同的类型。

2.联合体的关键字是union. 但是编译器只为最⼤的成员分配⾜够的内存空间。

3.联合体的特点是所有成员共⽤同⼀块内存空间。所 以联合体也叫:共⽤体。 给联合体其中⼀个成员赋值,其他成员的值也跟着变化。

二、 联合体的特点

介绍:

联合的成员是共⽤同⼀块内存空间的,这样⼀个联合变量的⼤⼩,⾄少是最⼤成员的⼤⼩(因为联合 ⾄少得有能⼒保存最⼤的那个成员)。

代码举例:

#include <stdio.h>
//联合类型的声明
union Un
{char c;int i;
};
int main()
{
//联合变量的定义union Un un = {0};
//输出的结果是⼀样的吗?printf("%p\n", &(un.i));printf("%p\n", &(un.c));printf("%p\n", &un);return 0;
}

由此我们可以得出联合的成员是共⽤同⼀块内存空间的,那么,改其中一个成员的地址,其他成员的地址受到影响吗?

例:


#include <stdio.h>
//联合类型的声明
union Un
{char c;int i;
};
int main()
{
//联合变量的定义union Un un = {0};un.i = 0x11223344;un.c = 0x55;printf("%x\n", un.i);return 0;
}

由代码以及结果,我们可知:我们改其中一个成员的地址,其他成员的地址受到影响,通过改c,将i的第4个字节的内容修改为55了。

这处我们通过图来讲解:

详细讲解:

    • union Un 包含 char c(1字节)和 int i(4字节),因此联合体大小为 4字节(取最大成员 int 的大小)。
    • 所有成员共用这4字节内存,c 存储在内存的最低地址字节(取决于系统字节序,默认这是小端字节序,即低字节存低位数据)。
  1. 初始赋值与修改过程

    • 步骤1un.i = 0x11223344
      在小端字节序下,4字节内存的存储形式为(从低地址到高地址):
      44(0x44)、33(0x33)、22(0x22)、11(0x11)。

    • 步骤2un.c = 0x55
      char c 会覆盖内存中最低地址的1字节,将原 44 替换为 55。此时内存变为:
      55(0x55)、33(0x33)、22(0x22)、11(0x11)。

  2. 最终读取 un.i 的值
    内存中的4字节数据组合为 0x11223355(高地址字节 11 为最高位,低地址字节 55 为最低位),因此 printf("%x\n", un.i) 输出 11223355

既然联合体是公用内存,那我们来对⽐⼀下相同成员的结构体和联合体的内存布局情况。

先列出联合体:

#include <stdio.h>
union Un
{char c;int i;
};
int main()
{   union Un un = {0};printf("%p\n", &(un.i));printf("%p\n", &(un.c));printf("%p\n", &un);return 0;
}

结构体:

#include <stdio.h>
struct s
{char c;int i;
};
int main()
{   struct s un = {0};printf("%p\n", &(un.i));printf("%p\n", &(un.c));printf("%p\n", &un);return 0;
}

结合图:

三、联合体⼤⼩的计算

介绍:

联合体计算大小和结构体相同,有内存对齐规则:

下面解释一下:

联合体大小的计算规则

联合体(Union)的大小由最大成员的大小内存对齐规则共同决定,核心原则是:联合体的总大小必须能容纳最大的成员,且满足所有成员的对齐要求

1. 基础规则
  • 取最大成员大小:联合体的大小首先至少是所有成员中占用内存最大的那个成员的大小。
  • 满足内存对齐:最终大小需向上调整为所有成员对齐模数的最小公倍数的倍数(对齐模数通常为成员类型的大小,如int为4字节,double为8字节等)。

列举下例子:

union Test1 {char a;    // 1字节int b;     // 4字节double c;  // 8字节
};

1. 确定最大成员大小
  • 成员 achar):1字节
  • 成员 bint):4字节
  • 成员 cdouble):8字节
  • 最大成员大小 = 8字节double c)。
2. 计算对齐模数的最小公倍数

各成员的对齐数(通常为类型大小):

  • char:1字节
  • int:4字节
  • double:8字节 (最⼤对⻬数)
  • 最小公倍数 = 8(1、4、8的最小公倍数为8)。
3. 最终大小

联合体大小需满足:

  • 容纳最大成员(8字节);
  • 是对齐模数最小公倍数(8)的倍数。

因此,union Test1 的大小为 8字节 ✅。

结论

union Test1 在内存中占用 8字节,由最大成员 double c 的大小和对齐要求共同决定。

例:

#include <stdio.h>
union Un1
{char c[5];int i;
};
union Un2
{short c[7];int i;
};
int main()
{printf("%d\n", sizeof(union Un1));printf("%d\n", sizeof(union Un2));return 0;
}

接下来,将对其详解:

union Un1 的大小计算

  • 最大成员大小char c[5] 占5字节(大于 int i 的4字节)。
  • 对齐模数
    • char 数组的对齐数 = 1字节(基础类型 char 的大小);
    • int 的对齐数 = 4字节。
    • 最小公倍数 = 4(1和4的最小公倍数)。
  • 调整对齐:5字节需向上调整为4的倍数(5 → 8,因为 4×2=8)。
  • 结果sizeof(union Un1) = 8

2. union Un2 的大小计算

  • 最大成员大小short c[7] 占14字节(大于 int i 的4字节)。
  • 对齐模数
    • short 数组的对齐数 = 2字节(基础类型 short 的大小);
    • int 的对齐数 = 4字节。
    • 最小公倍数 = 4(2和4的最小公倍数)。
  • 调整对齐:14字节需向上调整为4的倍数(14 → 16,因为 4×4=16)。
  • 结果sizeof(union Un2) = 16

关键总结

联合体大小需同时满足 “容纳最大成员” 和 “对齐模数最小公倍数的倍数” 两个条件,当最大成员大小不满足对齐要求时,需向上补齐 💡。

注意:基础类型 short 的大小为2个字节。

当然,联合体可以帮助我们解决很多问题,例如:求系统的大小端字节序:

如果不了解的可一看一下数据在内存中的存储该章节内容。

#include <stdio.h>
union Un1
{int i;char c;};
int main()
{union Un1 a;a.i=1;a.c=*((char*)&a.i);if(a.c==1){printf("小端字节序\n");}else{printf("大端字节序\n");}return 0;
}

解释:

  • 联合体成员共享同一块内存空间,i 和 c 的起始地址相同。
  • char c 仅访问内存中 第一个字节 的数据。

字节序判断原理

  • a.i = 1:将整数 1 存入 int i,其二进制表示为(假设32位系统):
    00000000 00000000 00000000 00000001(高位字节在前,低位字节在后)。

  • 字节序影响内存存储

    • 小端字节序:低位字节存低地址 → 第一个字节为 00000001(值为1)。
    • 大端字节序:高位字节存低地址 → 第一个字节为 00000000(值为0)。
  • a.c = *((char*)&a.i):直接读取 i 的第一个字节数据到 c

条件判断结果

  • 若 a.c == 1 → 第一个字节为 1 → 小端字节序。
  • 若 a.c == 0 → 第一个字节为 0 → 大端字节序

结论

程序通过联合体共享内存的特性,读取整数 1 的第一个字节数据,最终判断当前系统为 小端字节序 💡。

四、枚举类型的声明

介绍:

枚举顾名思义就是⼀⼀列举,把可能的取值⼀⼀列举。

代码示例:

enum Color{RED,GREEN,BLUE
};

详解:

  1. 默认值规则

    • 首个常量默认值为 0,后续常量默认值为 前一个常量值 + 1
    • 可通过 = 显式指定任意整数(支持负数),未指定的后续常量自动递增。
enum Color{RED=2,GREEN,BLUE
};

这样实现。

五、枚举类型的优点

介绍:

1. 增加代码的可读性和可维护性。

2. 和#define定义的标识符⽐较枚举有类型检查,更加严谨。

3. 便于调试,预处理阶段会删除 #define 定义的符号。

4. 使⽤⽅便,⼀次可以定义多个常量。

5. 枚举常量是遵循作⽤域规则的,枚举声明在函数内,只能在函数内使⽤。

使用示例:

#include <stdio.h>// 声明并定义枚举
typedef enum {SPRING = 1,  // 显式从1开始SUMMER,      // 2AUTUMN,      // 3WINTER       // 4
} Season;int main() {Season s = SUMMER;printf("当前季节编号:%d\n", s);  // 输出:2return 0;
}

总结

 以上就是今天要讲的内容,本文介绍了联合体类型的声明、联合体的特点、联合体⼤⼩的计算、枚举类型的声明、枚举类型的优点、枚举类型的使⽤知识的相关内容,为本章节知识的内容,希望大家能喜欢我的文章,谢谢各位,同时自定义类型:结构体、联合与枚举部分也结束了,下篇文将为大家带来新的知识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/98281.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/98281.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/98281.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Oceanbase下使用TPC-H模式生成数据

1.下载tpc-h http://www.tpc.org/ 点击下载始终弹出这个画面&#xff0c;尝试了多种方法无效&#xff0c;最后选择科学上网工具&#xff0c;才正常下载。 通过网盘分享的文件&#xff1a;TPC-H-Toolv3.zip 链接: https://pan.baidu.com/s/14CXrp7v_7XkPtXfFLkziBQ?pwdqf5t 提…

LeetCode 面试经典 150_哈希表_单词规律(41_290_C++_简单)

LeetCode 面试经典 150_哈希表_单词规律&#xff08;41_290_C_简单&#xff09;题目描述&#xff1a;输入输出样例&#xff1a;题解&#xff1a;解题思路&#xff1a;思路一&#xff08;哈希表&#xff09;&#xff1a;代码实现代码实现&#xff08;思路一&#xff08;哈希表&a…

librespeed c++ 上传下载带宽测试 排坑全流程

在搭建 LibreSpeed 测速服务并实现基于 curl/API 的上传下载测试时&#xff0c;遇到 Nginx 配置冲突、PHP 权限异常等问题。本文将梳理从环境搭建到功能验证的全流程&#xff0c;针对 “curl 上传报 404/405”“PHP-FPM 权限拒绝”等典型问题&#xff0c;提供可复现的解决方案。…

重读生成概率模型1----基础概念

1 KL 散度 KL 散度的作为是描述两个分布的差异的&#xff0c;首先是度量一个分布&#xff0c;用熵来度量。 1.1 熵 在介绍熵之间&#xff0c;首先要度量单个事件的信息量 I(x)−logP(x)I(x)-logP(x)I(x)−logP(x) 整体的信息量 H(P)Ex P[−logP(x)]−∑P(x)logP(x) \begin{alig…

排查解决磁盘占用高问题(容器挂载的磁盘)

最近遇到磁盘占用高的告警&#xff0c;记录一下解决的思路。 首先是系统触发告警&#xff0c;通知我们某台机器磁盘占用高。&#xff08;或其他途径得知&#xff09; 通过XShell登录该机器。 执行df-h命令查看挂载占用情况找到真正占用高的挂载点挂载点/home目录占用高&#xf…

流体(1)

流体 Minecraft 中的流体(Fluid),也常被称为液体(Liquid),是一类能够自由流动、形成河流、瀑布或湖泊的特殊方块。它们的行为基于简化的流体力学,是游戏世界中动态环境的重要组成部分。 💧 流体是什么? 在 Minecraft 中,流体核心特点包括: 源方块与流动:每个流…

机器学习-卷积神经网络(CNN)

全连接层->卷积层 用有一个隐藏层的MLP训练ImageNet数据集&#xff08;300*300的图像&#xff0c;有1000个类别&#xff09;&#xff0c;要有10000个输出 会有10亿个可学习的参数&#xff0c;量太大 全连接&#xff1a;一个输出是根据所有输入加权得到在图片中识别物体&…

Ubuntu 磁盘扩容与扩容失败问题解决( df -h 与 GParted 显示空间不一致的问题 -LVM)

在管理 Linux 磁盘时&#xff0c;你是否遇到过这样的困惑&#xff1a;正常扩容之后&#xff0c;发现GParted 显示某个分区还有几十 GiB 可用&#xff0c;但 df -h 却提示该分区已接近满额&#xff1f;这种 “空间幻觉” 背后是系统存储管理的分层设计&#xff0c;本文将从原理到…

PyQt5中QLineEdit控件数值显示与小数位数控制

在PyQt5应用程序开发中&#xff0c;QLineEdit控件常用于显示和编辑文本内容。当需要用它来显示数值并控制小数位数时&#xff0c;开发者需要掌握一些特定的技巧。本文将深入探讨几种实现方法&#xff0c;每种方法都附带完整独立的代码示例。 数值格式化基础 在Python中&#xf…

LangChain使用方法以OpenAI 的聊天模型GPT-4o为例

以使用 OpenAI 的聊天模型&#xff08;如 GPT-4&#xff09;为例&#xff0c;从设置环境、初始化模型、调用模型到处理响应的各个方面进行介绍&#xff1a; 1. 环境设置 安装 langchain-openai 包。设置环境变量 OPENAI_API_KEY&#xff0c;用于认证&#xff08;以linux为例&am…

Oracle为数据大表创建索引方案

在日常业务中&#xff0c;避免不了为数据量大表补充创建索引的情况&#xff0c;如果快速、有效地创建索引成了一个至关重要的问题&#xff08;注意&#xff1a;虽然提供有ONLINE在线执行的方式&#xff0c;理想状态下不会阻塞DML操作&#xff0c;但ONLINE在开始、结束的两个时刻…

网站服务相关问题

目录 HTTP常见的状态码 http和https的区别以及使用的端口号 http处理请求的过程 https认证过程 正向代理和反向代理的区别 HTTP常见的状态码 HTTP&#xff08;超文本传输协议&#xff09;定义了一系列的状态码&#xff0c;用于表示客户端请求的处理结果。以下是一些常见的…

Go并发编程实战:深入理解Goroutine与Channel

Go并发编程实战&#xff1a;深入理解Goroutine与ChannelGo并发编程实战&#xff1a;深入理解Goroutine与Channel概述1. 为什么是Go的并发&#xff1f;从“线程”与“协程”说起2. Goroutine&#xff1a;如何使用&#xff1f;3. Channel&#xff1a;Goroutine间的安全通信创建与…

2025服贸会“海淀之夜”,点亮“科技”与“服务”底色

2025年9月12日傍晚&#xff0c;北京颐和园&#xff0c;十七孔桥旁&#xff0c;2025年中国国际服务贸易交易会“海淀之夜”如约而至。在“海淀之夜”&#xff0c;科技机构、金融机构、咨询服务机构、出海服务企业以及跨国企业和国际友人等&#xff0c;将目光聚焦于此。被第三方机…

qt使用camke时,采用vcpkg工具链设置VTK的qt模块QVTKOpenGLNativeWidget

下载:QVTKOpenGLNativeWidget嵌入qt应用中资源-CSDN下载 1.通过vcpkg安装VTK,目前的VTK里面默认为qt6,如果需要安装qt5,需要将端口配置进行修改 笔者的vcpkg的vtk端口路径:D:\vcpkg\ports\vtk portfile.cmake 修改点: #第一处 #file(READ "${CURRENT_INSTALLED_DIR}/sh…

Axios在鸿蒙应用开发中的使用

目录一、简介二、安装与配置三、axios用法1.axios泛型参数(1).第三个泛型参数-约束data请求参数的类型(2).第二个泛型参数-决定后台返回数据的类型2.axios拦截器3.请求工具封装统一处理业务状态码错误统一处理401或404错误一、简介 Axios 是一个基于 Promise 的网络请求库&…

第九周文件上传

文件上传漏洞 不同的网站要不同的webshell。我们使用是php开发的网站。 一服务器白名单绕过 服务端白名单(Whitelist)是⼀种安全机制&#xff0c;它只允许预定义的合法元素通过&#xff08;只有有限的元素进入&#xff09;&#xff0c;其他所有内容默认被拒绝。相比黑名单&am…

计算机视觉必读论文:从经典到前沿

计算机视觉必读论文:从经典到前沿 一、前言 二、经典论文解读​ 2.1 图像分类​ 2.1.1 《ImageNet Classification with Deep Convolutional Neural Networks》(AlexNet)​ 2.1.2 《Very Deep Convolutional Networks for Large-Scale Image Recognition》(VGGNet)​ 2.1.…

对比PowerBI的字段参数,QuickBI的已选字段还有改进的空间

对比PowerBI的字段参数&#xff0c;QuickBI的已选字段还有改进的空间 之前分享过QuickBI的已选字段 vs PowerBI的字段参数&#xff0c;QuickBI可以在表格中实现PowerBI的字段参数效果&#xff0c;甚至比PowerBI实现的过程和使用方式更丝滑。 但如果应用到图形中会怎么样呢&am…

飞算JavaAI:Java开发新时代的破晓之光

免责声明&#xff1a;此文章的所有内容皆是本人实验测评&#xff0c;并非广告推广&#xff0c;并非抄袭。如有侵权&#xff0c;请联系&#xff0c;谢谢&#xff01;【#飞算JavaAl炫技赛】 【#Java开发】摘要&#xff1a;飞算JavaAI作为全球首款聚焦Java的智能开发助手&#xff…