C语言之旅:自定义类型(联合和枚举)

news2024/11/23 1:23:53

目录

一.联合体

1.1 联合体的声明

1.2 联合体的使用

1.3 为什么输出 4呢?

1.4 相同成员的结构体和联合体对比

1.5 联合体大小对比

1.6使用联合体判断大小端

二.枚举类型

2.1枚举类型的例举:

 2.2枚举类型的优点

2.3 枚举类型的使用


在上篇文章中已经介绍了结构体。另外,C语言还提供了另外两种数据类型——联合体(union)和枚举(enum),它们各自具有独特的功能和用途。本文将带你深入了解联合体和枚举的概念、用法以及它们在实际编程中的应用。

一.联合体

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

但是编译器只为最⼤的成员分配⾜够的内存空间。联合体的特点是所有成员共⽤同⼀块内存空间。

所以联合体也叫:共⽤体。 给联合体其中⼀个成员赋值,其他成员的值也跟着变化。

1.1 联合体的声明

union Un
{
 char c;
 int i;
};

1.2 联合体的使用

#include <stdio.h>
//联合类型的声明 
union Un
{
 char c;
 int i;
};
int main()
{
 //联合变量的定义 
 union Un un = {0};
 //计算连个变量的⼤⼩ 
 printf("%d\n", sizeof(un));
 return 0;
}

输出结果:4

1.3 为什么输出 4呢?

 int类型的大小通常是4个字节(byte)。由于联合体的大小至少足够大以容纳其最大的成员,因此Un联合体的大小至少应该是int类型的大小,所以输出为 4。

代码1:

#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;
}

输出结果:

012FFD0C
012FFD0C
012FFD0C

这段代码输出了三个地址,它们分别是联合体Un的int成员i的地址、char成员c的地址,以及整个联合体变量un的地址。 

 代码2:

#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;
}

输出结果:

11223355

 

 un.i赋值0x11223344,这是一个十六进制数,它会被存储在un联合体所分配的内存中。因为int类型通常占用4个字节,所以0x11223344会被完整地存储在这4个字节中。

然后,代码又对un.c赋值0x55。由于un.c和un.i共享同一块内存,这个赋值会覆盖un.i的最低有效字节(即char类型所占用的字节)。

那么,0x55会覆盖0x11223344的最低字节,变成0x11223355

最后,代码打印un.i的值,由于我们已经修改了它的最低字节,所以输出的是11223355。(小端机器)。

1.4 相同成员的结构体和联合体对比

代码示例:

struct S
{
	char  c;
	int i;
};
struct S s = { 0 };

union Un
{
	char c;
	int i;
};
union Un un = { 0 };

1.5 联合体大小对比

• 联合的大小至少是最⼤成员的⼤⼩。

• 当最大成员大小不是最⼤对⻬数的整数倍的时候,就要对齐到最大对齐数的整数倍。

代码示例:

#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;
}

输出结果:
8
16

由于 char 数组的大小是5个字节,而 int 通常需要4字节对齐,编译器可能会选择增加1个字节的填充(padding),使得整个 union Un1 的大小为8个字节,以满足 int 的对齐要求。 

short c[7] 需要14个字节,这超过了 int 的4个字节,所以 union Un2 的大小将是14个字节。与 union Un1 类似,由于内存对齐的原因,编译器可能会增加额外的填充。在这种情况下,编译器可能会添加2个字节的填充,使 union Un2 的总大小为16个字节。

使用联合体可以节省空间。

1.6使用联合体判断大小端

代码示例:

#include <stdio.h>    
  
int check_sys()    
{    
    union    
    {    
        int i;    
        char c[sizeof(int)]; // 使用字符数组以便访问int的各个字节    
    } un;    
    
    un.i = 1; // 设置int为1    
    
    // 检查int的最低有效字节(在小端系统中应该是1)    
    return *(char *)&un.i == 1; // 如果返回true(非零),则是小端系统;如果返回false(零),则是大端系统    
}    
  
int main()    
{    
    if (check_sys()) {    
        printf("这是一个小端系统。\n");    
    } else {    
        printf("这是一个大端系统。\n");    
    }    
    return 0;    
}

二.枚举类型

枚举类型(enum)是一种用户定义的数据类型,枚举(enum)顾名思义就是⼀⼀列举。把可能的取值⼀⼀列举。

2.1枚举类型的例举:

例如:

一周的星期⼀到星期日是有限的7天,可以一一列举

 //星期
enum Weekday 
{  
    Sunday,  
    Monday,  
    Tuesday,  
    Wednesday,  
    Thursday,  
    Friday,  
    Saturday  
};

性别有:男、女、保密,也可以一一列举 

//性别
enum Sex 
{  
    Male,  
    Female,  
    Cfidntl  
};

 2.2枚举类型的优点

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

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

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

4. 使方便便,一次可以定义多个常量

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

2.3 枚举类型的使用

#include <stdio.h>  
  
 
enum Color 
{  
    Red,  
    Green,  
    Blue,     
};  
  
int main()
 {  
    // 声明一个Color类型的变量  
    enum Color myColor;  
  
  
    myColor = Red;  
    switch (myColor) {  
        case Red:  
            printf("颜色是红色。\n");  
            break;  
        case Green:  
            printf("颜色是绿色。\n");  
            break;  
        case Blue:  
            printf("颜色是蓝色。\n");  
            break;  
        default:  
            printf("未知的颜色。\n");  
            break;  
    }  
      
    return 0;  
}

 注意,在C语言中,枚举常量默认从0开始,并且每个后续常量比前一个常量大1。因此,在这个例子中,Red的值为0,Green的值为1,Blue的值为2

当然也以拿整数给枚举变量赋值。在C语⾔中是可以的,但是在C++是不行的,C++的类型检查⽐ 较严格。

代码示例:

enum Color 
{  
    Red = 1,  
    Green = 2,  
    Blue = 3  
};

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何利用命令提示符列出文件?这里提供了几个实例供你参考

序言 什么命令可以用来列出目录中的文件&#xff1f;如何在命令提示符Windows 10/11中列出文件&#xff1f;很多人对这些问题感到困惑。在这篇文章中&#xff0c;我们详细解释了命令提示符列出文件的主题。 CMD&#xff08;命令提示符&#xff09;是一个功能强大的Windows内置…

Python学习之路 | Python基础语法(二)

Python3 面向对象 封装、继承、多态。 基础 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。方法&#xff1a;类中定义的函数。类变量&#xff1a;类变量在整个实例化的对象中是公用的。类变量定义在类中…

与禹老师学前端vue3学习汇总

24.5.15&#xff1a; 创建Vue3工程 1.确定自己电脑有没有nodejs环境&#xff0c;在cmd中输入node&#xff0c;如果出现Node.js的版本号说明已经有这个环境了&#xff0c;否则搜索Node.js安装 2.先在D盘创建一个文件夹Vue3_Study&#xff0c;然后在这个空文件夹中右键选择终端…

【069】基于SpringBoot+Vue实现的企业资产管理系统

系统介绍 基于SpringBootVue实现的企业资产管理系统管理员功能有个人中心&#xff0c;用户管理&#xff0c;资产分类管理&#xff0c;资产信息管理&#xff0c;资产借出管理&#xff0c;资产归还管理&#xff0c;资产维修管理。用户可以对资产进行借出和归还操作。因而具有一定…

Git系列:Git Switch 高效使用技巧

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

实时网络监控 - 一目了然网络状况

网络问题排查一直是IT管理员头痛的问题。随着网络规模的不断扩大和业务复杂度的提升&#xff0c;如何快速定位和解决网络故障变得尤为关键。本文详细介绍了一款名为 AnaTraf 的网络流量分析工具,它能提供全流量回溯分析、实时网络监控、性能分析等功能,助力企业快速诊断和解决各…

每日两题 / 236. 二叉树的最近公共祖先 124. 二叉树中的最大路径和(LeetCode热题100)

236. 二叉树的最近公共祖先 - 力扣&#xff08;LeetCode&#xff09; dfs统计根节点到p&#xff0c;q节点的路径&#xff0c;两条路径中最后一个相同节点就是公共祖先 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* …

鸿蒙 DevEcoStudio:简单实现网络请求登录案例

使用http或axios实现登录案例 在entry/src/main/ets/pages路径下新建Page9.ets文件&#xff1a; import http from ohos.net.http import router from ohos.router Entry Component struct Page9 {State message: string Hello WorldState username: string State password:…

学习了java编程后,你就只能做java程序员吗?

在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「java的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01; 学习了Java编程后&#xff0c;…

KNN算法用于回归分析

生成数据集 from sklearn.datasets import make_regression import matplotlib.pyplot as plt# 生成特征数量为1&#xff0c; 噪音为50的数据集 X, y make_regression(n_features1, n_informative1, noise50, random_state8)# 散点图 plt.scatter(X, y, c"orange",…

CTF例题:[SWPU2019]Web1(无列名注入)

网址&#xff1a;BUUCTF在线评测 搜索web1 启动靶机 点击链接进入题目 进入题目后发现有登录和注册接口&#xff0c;直接注册登录。 首先通过1进行测试&#xff0c;查看是否有注入点 出现报错&#xff0c;说明可能存在注入点 然后继续测试发现该服务器过滤了&#xff1a; or、…

SFTPGO 整合minio AD群组 测试 |sftpgo with minio and ldap group test

SFTP-GO 研究 最近在测试sftpgo&#xff0c;发现中文的资料比较少&#xff0c;在企业中很多存储开始支持S3&#xff0c;比如netapp 于是想尝试把文件服务器换成sftpgoS3的存储&#xff0c;sftp go和AD 群组的搭配测试比较少 自己测试了一把&#xff0c;觉得还是没有server-u的A…

三类银行互联网贷款迎新规!速看菊风信贷智能双录解决方案

​​继2020年《商业银行互联网贷款管理暂行办法》&#xff08;下称《办法》&#xff09;和2021年《关于进一步规范商业银行互联网贷款业务的通知》之后&#xff0c;时隔三年&#xff0c;股份制银行、城商行、民营银行&#xff08;简称“三类银行”&#xff09;互联网贷款业务再…

shell脚本实现linux系统自动化配置免密互信

目录 背景脚本功能脚本内容及使用方法 1.背景 进行linux自动化运维时需要先配置免密&#xff0c;但某些特定场景下&#xff0c;做了互信的节点需要取消免密&#xff0c;若集群庞大节点数量多时&#xff0c;节点两两之间做互信操作非常麻烦&#xff0c;比如有五个节点&#x…

C++二叉搜索树搜索二叉树二叉排序树

C二叉搜索树 1. 二叉搜索树的概念 二叉搜索树&#xff08;BST,Binary Search Tree)&#xff0c;也称为二叉排序树或二叉查找树。它与一般二叉树的区别在于&#xff1a;每个结点必须满足“左孩子大于自己&#xff0c;右孩子小于自己”的规则。在这种规则的约束下&#xff0c;二…

海外云手机的运作原理和适用场景

海外云手机是一种基于云计算技术的虚拟手机服务&#xff0c;通过将手机操作系统和应用程序托管在远程服务器上&#xff0c;实现用户可以通过互联网连接来使用和管理手机功能&#xff0c;而无需实际拥有物理手机。以下是有关海外云手机的相关信息&#xff1a; 海外云手机的运作原…

【Linux】-Linux的实用操作:快捷键与软件安装操作、构建软连接、日期时区的设置[4]

目录 一、各类小技巧&#xff08;快捷键&#xff09; 1、ctrl c 强制停止 2、ctrl d 退出或登出 3、历史命令搜索 4、光标移动快捷键 5、清屏 二、软件安装 1、yum命令 2、apt命令 - 扩展&#xff08;ubuntu&#xff09; 三、systemctl命令 四、软连接 1、ln命令…

【PG数据库】PostgreSQL 日志归档详细操作流程

1.1 日志归档的目的 pg数据库日志归档是将PostgreSQL数据库的日志文件进行归档的过程。 归档的主要目的是为了保留历史数据&#xff0c;确保数据的一致性和完整性&#xff0c;同时为数据恢复提供必要的支持。 pg数据库日志归档的目的包括&#xff1a; 1.数据恢复&#xff1…

【MySQL】SQL基本知识点DDL(1)

目录 1.SQL分类&#xff1a; 2.DDL-数据库操作 3.DDL-表操作-创建 4.DDL-表操作-查询 5.DDL-表操作-数据类型 6.DDL-表操作-修改 1.SQL分类&#xff1a; 2.DDL-数据库操作 3.DDL-表操作-创建 注意&#xff1a;里面的符号全部要切换为英文状态 4.DDL-表操作-查询 5.DDL…

html基础(全)

html简介 目录 什么是网页 什么是 HTML 常用浏览器 WebE标准的构成 基本语法概述 第一个HTML页面 文档类型声明标签 lang 语言种类 字符集 标题标签 段落和换行标签 文本格式化标签 div和span标签 图像标签和路径 超链接标签 表格的主要作用 表头单元格标签 列…