首页 > 其他分享 >自定义类型:联合和枚举

自定义类型:联合和枚举

时间:2024-09-20 21:24:16浏览次数:9  
标签:return 自定义 int 联合体 char 枚举 printf 类型

一 ,联合体类型的声明

 与结构体相似,联合体也是由一个或者多个成员构成,这些成员可以是不同类型。

但是与结构体不同的是 : 编译器只为联合体成员中的最大成员分配足够的内存空间。 联合体的特点是所有成员共用一块内存空间。所以联合体 也称  ===>    共用体

那也就意味着联合体其中一个成员赋值,其他成员的值也跟着变化

 union tag

{

                member-list;

}variable - list ;  

//联合体类型声明
union U
{
	char c;
	int n;
};
int main()
{
	//联合体类型定义
	union U un = { 0 };
	//计算联合体变量的大小
	printf("%zd\n", sizeof(un));
	//4
	return 0;
}

 输出结果 : 4  

并不是 5 也不是 8 ;这就与联合体成员在内存中的分布有关;

二 ,联合体的特点

2.1 联合体的内存布局

 联合体的成员是共用一块内存空间的,这个联合变量的大小,至少是最大成员的大小(因为至少得有能力保存最大的那个成员)

union U
{
	char c;
	int n;
};
int main()
{
	union U u = { 0 };
	printf("联合体大小 : %zd\n", sizeof(u));
	printf("%p\n", &u);
	printf("%p\n", &u.c);
	printf("%p\n", &u.n);
	return 0;
}

 那就意味这在这块联合体的内存空间中,变量分布是:

初始化数值,进入调试,查看内存情况验证

 经过分析可以画出  ,  u 的内存布局图

2.2 联合体与结构体的对比 

struct S
{
	char c;
	int n;
};

union U
{
	char c;
	int n;
};
int main()
{
	printf("S : %zd\n", sizeof(struct S));
	printf("U : %zd\n", sizeof(union U));
	return 0;
}

 联合体与结构体的内存图:

三 ,联合体大小的计算

  •  联合的大小至少是最大成员的大小。
  • 最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍

例题一: 

union u
{
	char c[5];
	int n;
}un1;
int main()
{
	printf("%zd\n", sizeof(un1));
	return 0;
}

 例题二:

union u
{
	short c[7];
	int i;
}n1;
int main()
{
	printf("%zd\n", sizeof(n1));
	return 0;
}

 

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

比方说,有个活动,可以进行礼品兑换,可进行兑换中有三种商品:图书 ,杯子 ,衬衫。

每一种商品都有:库存量 ,价格 ,商品类型 和 商品类型相关的其他信息

  • 图书 : 书名 ,作者 ,页数
  • 杯子 : 设计
  • 衬衫 : 设计 ,可选颜色 ,可选尺寸

进而就会考虑到使用结构体 把数据统统放进去,可这样会对空间造成一定的浪费。结构中包含了所有的礼品的各种属性,但是只有部分属性信息是常用的,

比方说:商品是图书,就不需要 design , colors , sizies 。

struct gift_list
{
	//公共属性
	int stock_number;//库存量
	double price;//定价
	int item_type;//商品类型

	//特殊属性
	char title[20];//书名
	char author;//作者
	int num_pages;//页数

	char design[30];//设计
	int color;//颜色
	int sizes;//尺寸
};

所以可以把公共属性单独写出来,剩余属于各种商品本身的属性使用联合起来,这样就可以在一定程度上节省了空间。 

struct gift_list
{
	//公共属性
	int stock_number;//库存量
	double price;//定价
	int item_type;//商品类型

	union
	{
		struct {
			char title[20];//书名
			char author;//作者
			int num_pages;//页数
		}book;
		struct
		{
			char design[30];//设计
		}mug;
		struct
		{
			char design[30];//设计
			int color;//颜色
			int sizes;//尺寸
		}shirt;
	}item;
};

 需要用到谁,就可以开辟谁的空间。可以使用匿名结构体 和 匿名联合体 ,因为只需要用到成员就好了,不需要用到类型。

2.3 练习

写一个程序,判断当前机器是小端还是大端? 

//法一
int main()
{
	int a = 1;
	//0x00 00 00 01
	if (*(char*)&a == 1)
		printf("小端\n");
	else
		printf("大端\n");
	return 0;
}



//法二
int check_sys()
{
	int a = 1;
	if (*(char*)&a == 1)
		return 1;
	else
		return 0;
}
int main()
{
	int ret = check_sys();
	if (ret == 1)
		printf("小端\n");
	else
		printf("大端\n");
	return 0;
}


//法三 -- 联合体
int check_sys()
{
	union
	{
		char c;
		int n;
	}n;
	n.n = 1;
	return n.c;
}
int main()
{
	int ret = check_sys();
	if (ret == 1)
		printf("小端\n");
	else
		printf("大端\n");
	return 0;
}

四 ,枚举类型的声明

 枚举顾名思义就是      一 一 列举   (列举可能   有限  的值)

比如:

  • 一周中周一到周日 有限7天
  • 性别:男 , 女 ,保密
  • 月份有12个月
  • 三原色:红绿蓝

这些数据的表示就可以使用枚举

举例: 

enum Day//星期
{
	Mon,
	Tues,
	wed,
	Thur,
	Fri,
	Sat,
	sun
};

enum Sex//性别
{
	MALE,
	FEMALE,
	SACRET
};

enum Color//颜色
{
	RED,
	GREEN,
	BULE
};

 书写格式:

  1.  定义的 enum Day ,enum Sex , enum Color 都是枚举类型
  2. { } 中的内容是枚举类型的可能值 , 也叫枚举常量
  3. 这些枚举常量都是有值的 , 默认从0开始 , 依次递增 1 ,枚举常量是不可以被修改的,但是可以赋初始值。

1.三个都可以各自赋初始值 

 2. 仅对第一个常量赋值 , 其他常量依次增1

3.对中间的常量赋值 , 第一个常量会默认为0 , 往后依次增加 1 到 赋值的中间常量 , 中间常量往后 , 以中间常量的值为起始,依次增加 1 ;

五 ,枚举类型的优点

 为什么要使用枚举?

用#define 定义常量   或者说 在函数里创建一个变量 int sex = 0 // 1  2

也都可以表示男 , 女 这些值

枚举的优点

  • 增强代码的可读性可维护性
  • 和#define 定义的标识符比较   枚举有类型检查,更加严谨
  • 便于调试,预处理阶段会删除 #define 定义的符号
  • 使用方便 , 依次可以定义多个常量
  • 枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用

六 ,枚举类型的使用

enum color//颜色
{
	red,
	green,
	bule
};

int main()
{
	enum color crl = green;
	return 0;
}

 使用枚举常量给枚举变量赋值

 注意 : 在C语言中可以拿整数给枚举变量赋值,因为C中的类型检查不够严格 , 但是在C++中会报错

标签:return,自定义,int,联合体,char,枚举,printf,类型
From: https://blog.csdn.net/khjjjgd/article/details/142384541

相关文章

  • 自定义类型:结构体
    一,结构体类型的声明 1.1结构体回顾结构体是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量 1.2结构的声明structtag{        member-list;                         ......
  • 【数据类型】映射map
    小明正在备考英语四级考试,但他的词典太厚了,他记不住哪个单词在哪里。于是他准备开发一个可以直接找某单词在某页的应用。但是,他不会做,整天十分烦恼。好啦,进入正题,大家好,我是@学霸小羊,今天来讲讲map——映射map翻译为映射,是STL中的常用容器。其实,数组就是一种映射,比如:int......
  • JavaScript 中 for 循环的类型
    我们都知道并且喜欢经典的for循环,但是您知道javascript还有其他一些强大的for循环选项吗?1)for/in:这个对于迭代对象的键和操作对象属性非常有用。example:constobj={name:"javascript",type:"language"};for(letkeyinobj){console.log(key);//outputs"nam......
  • 类型转换 Cast a pandas object to a specified dtype ``dtype``.
    实践:修改列值分组、排序使用同一字段:整数--》区间名称字符串          FutureWarning:Settinganitemofincompatibledtypeisdeprecatedandwillraiseinafutureerrorofpandas.Value'[320,439)'hasdtypeincompatiblewithint64,pl......
  • SQL Server 数据类型转换详解
    在SQLServer中,数据类型转换是数据库开发中非常常见的任务。数据类型转换是指将一种数据类型的数据转换为另一种数据类型。SQLServer支持两种类型的转换方式:隐式转换和显式转换。本文将详细介绍SQLServer中数据类型转换的原理、使用方法、常见场景,并通过具体的例子进行解释和演示......
  • Android 他人开源库自定义imageview实现图片圆角,操作简单
    Android他人开源库自定义imageview实现图片圆角,操作简单效果图:1.导入依赖dependencies{implementation'io.github.FlyJingFish:ShapeImageView:1.5.6'}2.ShapeImageView示例<com.flyjingfish.shapeimageviewlib.ShapeImageViewandroid:id="@+id/i......
  • 数据类型自动转换的解决方案
    数据类型自动转换的解决方案java8、jdk8背景为方便测试框架数据处理以及方便查看一些数据,弄了一个工具类,部分要点简要说明。主要涉及到字符串与其他类型的相互转换,无其他类型之间的相互转换。轻量测试框架实现与使用的总篇可见此文。问题分析字符串转换为对象的方法......
  • 针对不同电机类型,如何选择防晃电装置?
    “晃电”是指因雷击、瞬间短路或其他原因引起电网电压波动或短时断电的现象,其中电压暂降是指电压有效值降至额定电压的10%~90%,持续时间在10ms~600ms的晃电,工业现场的电机主要有直接起动、变频起动和软起动等控制方式,直接起动通过接触器常开触点自保持构成控制回路,一般接触器可靠......
  • 云服务器异常报错类型及处理方法
     在现代互联网时代,云服务器已经成为了企业和个人用户的首选解决方案。一方面,云服务器提供了灵活、可扩展的计算资源,另一方面,其治理和维护也相对复杂。当云服务器出现异常报错时,如何有效地解决问题显得尤为重要。本文将就云服务器主机异常报错的常见类型、原因分析以及解决方案进行......
  • 兼收并蓄 TypeScript - 第三方库: 类型声明
    源码https://github.com/webabcd/TypeScriptDemo作者webabcd兼收并蓄TypeScript-第三方库:类型声明示例如下:third\typeDeclaration.ts/**类型声明用于TypeScript调用JavaScript*类型声明定义在.d.ts声明文件中*比如aes.js文件,其对应的声明文件为ae......