news 2026/8/7 22:11:19

C语言、自定义类型:联合体、枚举

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C语言、自定义类型:联合体、枚举

📚 目录

  • 1.联合体声明定义
  • 1.联合体的特点
  • 1.联合体的内存大小
  • 4.联合体与结构体的对比
  • 5.联合体判断编译器的大小端
  • 6.枚举类型的声明
  • 7.枚举类型的优点
  • 8.枚举类型的使用


前言:
今天我们又来学习一种自定义类型:联合体;那么什么是联合体和枚举呢?接下来我们就来学习学习。




联合体(也可以成为共用体):联合体就像一个一个结构一样,就好像结构体,都是由多个成员组合而成,这些成员可以是不同的类型,关键字:union
特点:编译器只为最大的内存分配空间,所有成员共用一块内存空间;给联合体内任意一个成员赋值,其他成员的值也跟着发生改变。




1. 联合体的声明定义

接下来演示联合体的声明定义

#include<stdio.h>//联合体类型的声明unionpf{chara;intc;};intmain(){//联合体类型定义unionpf opp={0};return0;}

以上就是我们联合体简单的声明和定义。

🔙 返回目录




2. 联合体的特点

联合体的成员是共用一块内存空间的,联合体的内存大小至少是最大成员体的内存大小;只有这样才能保证每一个联合体成员都能够存得下。
我们通过Vs调试窗口内存来探究他的结果:
代码1:

#include<stdio.h>//联合体类型的声明unionpf{chara;intc;};intmain(){//联合体类型定义unionpf opp={0};//打印每个成员的地址printf("%p\n",&opp);printf("%p\n",&(opp.a));printf("%p\n",&(opp.c));return0;}

代码2:

#include<stdio.h>//联合体类型的声明unionpf{chara;intc;};intmain(){//联合体类型定义unionpf opp={0};opp.c=0x11223344;opp.a=0x55;printf("%x\n",&(opp.a));return0;}


代码1:我们发现了他们三个的结果都是相同的第一个地址。
我们再看看他opp.c的内存和opp.a的内存地址。



代码2:我们发现了原本opp.c这个位置原本上应该存放的是0x11223344这里的44被opp.a里面的0x55给占用了。
从结果上看,我们得到的地址都是相同的地址,这就说明了联合体每个成员的内存大小都是共用的。

联合体共用内存情况:

4个字节分别对应着4个地址。

🔙 返回目录




3. 联合体的内存大小

那么我们联合体的内存大小是怎么算的呢?
联合体的大小最小为最大成员的内存大小。
当联合体中最大内存成员的大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

例如:

//计算下列结构体的大小。#include<stdio.h>unionpf1{chara[5];intc;};unionpf2{shorta[7];intc;};intmain(){printf("%zu\n",sizeof(unionpf1));printf("%zu\n",sizeof(unionpf2));return0;}

结果:

为什么会是这个结果呢?我们来分析一下。

🔙 返回目录



4.结构体与联合体的对比

那么结构体和联合体有什么区别呢?

structS{charc;inti;};unionUn{charc;inti;};#include<stdio.h>intmain(){structSs={0};unionUn un={0};return0;}


我们通过图片可以知道结构体的内存浪费比较大,而我们联合体浪费的内存远远没有结构体那么多。当我们结构体里面内存非常多的时候,浪费的内存也会不断增多。
而我们的联合体采用的是共用内存空间的形式,对于内存的利用比较高。
总结:联合体可以适当减少内存,但是当我们给其中一个成员赋值的时候,其他成员的值也会发生改变。

🔙 返回目录



联合体判断编译器的大小端

#include<stdio.h>inttest(){union{//建立一个联合体inti;charc;}un;un.i=1;returnun.c;//因为是联合体所以c和i的内存是共用的,我们返回char类型的c让他访问一个字节。返回1是小端返回0是大端}intmain(){intr=test();if(r==1){printf("小端\n");}else{printf("大端\n");}return0;}


我们使用的Vs编译器为小端。

🔙 返回目录



枚举类型:
枚举:就是一个一个把可能的值给列举出来。
就像我们生活中星期一到星期天、月份、颜色、价格等等这些东西给一一列举出来。像这些数字我们就能够使用枚举给他们列出来。
在以后写代码过程中避免不了大量的代码,代码一多就会出现各种各样的问题。

例如:(以订单为例子) ```c#include<stdio.h>//我们用#defind定义了一些毫无关系的常量#defineORDER_PENDING_PAYMENT1#defineORDER_PENDING_DELIVERY2#defineORDER_DELIVERED3#defineORDER_COMPLETED4voidList(intstatus){switch(status){caseORDER_PENDING_PAYMENT:printf("订单待付款\n");break;caseORDER_PENDING_DELIVERY:printf("订单待发货\n");break;case30:printf("订单已发货\n");break;caseORDER_COMPLETED:printf("订单已完成\n");break;default:printf("状态未知\n");break;}}intmain(){List(3);return0;}

问题1:常量无归类,代码量大了后难以管理
问题2:容易写错值(比如把3写成30),编译器无法校验
问题3:无法直观看出这些常量是一组的
调用时只能传数字,语义不清晰

6.枚举类型的声明

举例我们上面的例子:

#include<stdio.h>enumDay{Mon,Tues,Wed,Thur,Fri,Sat,Sun};

颜色

enumColor{RED,GREEN,bLUE};

注意:
我们每写完一个枚举成员用逗号隔开而不是分号,最后一个枚举成员不用添加分号。
在枚举成员{ }外面必须添加分号。
我们定义的枚举类型的成员可能都是有值的,默认从1开始,依次加1在声明枚举类型的时候我们可以进行赋值。

例如:

enumColor{RED=3,GREEN=4,bLUE=6};

当我们进行赋值完成后,在使用过程中就类似#defind定义常量,如果只对第一个进行了赋值,那么后面的就会在第一个的基础上加1。

enumColor{RED=9,GREEN,//这里就会变成10bLUE// 这里就会变成11};
🔙 返回目录



7.枚举类型的优点

我们知道了#defind也能定义常量,为什么还会有枚举呢?
我们就要学学枚举的优点了。
优点:
增加我们代码的可读性和可维护性;#define 定义的常量是全局的,无归属关系,易命名冲突。
相比较#defind我们的枚举有类型检查,更加严谨。
枚举变量本质是整型变量,所以可以用%d输出其数值。
枚举成员是编译期常量,不能修改
便于调试。我们编译器在编译过程中会删掉#defind定义的符号。

🔙 返回目录



8.枚举类型的使用

例如:

enumColor{RED=1,GREEN=2,BLUE=3};intmain(){enumColorr=GREEN;//使⽤枚举常量给枚举变量赋值return0;}
🔙 返回目录



完!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/14 15:22:42

OpenClaw 超级 AI 实战专栏【实战案例】(九)OpenClaw 生产环境部署全攻略:性能优化 + 安全加固 + 监控运维

目录 一、生产环境定位与架构设计 1.1 适用场景 1.2 推荐生产架构 二、环境准备与标准化安装 2.1 系统要求 2.2 一键安装依赖(生产脚本) 三、生产配置文件(必须固化) 3.1 OpenClaw 生产配置 config_prod.py 四、进程守护(生产 724 必备) 4.1 Supervisor 配置 /…

作者头像 李华
网站建设 2026/8/7 22:11:04

AI 工具加持:ComfyUI 节点开发极速上手

文章目录安装已有节点开发节点最后参考在AI生成式内容爆发的当下&#xff0c;ComfyUI以其灵活的节点化工作流、高度可定制的特性&#xff0c;成为 Stable Diffusion 相关开发与创作的首选工具之一。不同于传统的可视化界面&#xff0c;ComfyUI的核心魅力在于“节点”——每一个…

作者头像 李华
网站建设 2026/7/14 15:22:43

简述 AI 应用落地的三个阶段

文章目录前言阶段一&#xff1a;对话&#xff08;Promot、Context、Memory&#xff09;阶段二&#xff1a;简单智能体&#xff08;Agent、RAG、Function Calling、MCP&#xff09;阶段三&#xff1a;流程化智能体&#xff08;LangChain、workflow、Skill、subAgent&#xff09;…

作者头像 李华
网站建设 2026/7/14 15:22:45

基于计算机视觉的万物识别模型性能优化策略

基于计算机视觉的万物识别模型性能优化策略 你有没有遇到过这样的情况&#xff1a;好不容易部署了一个万物识别模型&#xff0c;结果在实际用的时候&#xff0c;发现识别速度慢得像蜗牛&#xff0c;或者经常把“猫”认成“狗”&#xff1f;别担心&#xff0c;这几乎是每个做计…

作者头像 李华
网站建设 2026/7/14 15:22:47

Excel 实战技巧:利用 OFFSET 统计 “标识行” 下方的数值总和

1. 场景背景 在财务报销或项目费用管理中&#xff0c;数据录入往往遵循一种特定的结构&#xff1a;“费用名称”与“具体金额”分行存储。 例如&#xff0c;当单元格标记为“差旅补贴”时&#xff0c;其正下方的单元格才是具体的报销金额。我们需要快速提取所有“差旅补贴”对应…

作者头像 李华