首页 > 其他分享 >C语言自定义类型:联合体

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

时间:2024-09-28 18:21:54浏览次数:8  
标签:自定义 int 联合体 C语言 char union un printf

目录


前言

前面我讲到C语言中的自定义结构——结构体,其实C语言中的自定义结构不只有结构体,还有枚举和联合体,我们今天就来学习一下这两个C语言中的自定义类型的其中一个——联合体;话不多说,正文开始:


一、联合体

1.1 联合体类型的声明

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

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

给联合体其中⼀个成员赋值,其他成员的值也跟着变化

这是什么意思呢?

union Un 
{
	char c;
	int i;
};


int main()
{
	union Un un = { 0 };

	printf("%zd\n", sizeof(un));

	return 0;
}

大家可以猜猜这个结构体是多大字节的:

在这里插入图片描述
为啥是4呢?

1.2 联合体的特点

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

union Un 
{
	char c;
	int i;
};


int main()
{
	//联合变量的定义
	union Un un = { 0 };
	printf("%zd\n", sizeof(un));

	// 下⾯输出的结果是⼀样的吗?
	printf("%p\n", &un);
	printf("%p\n", &(un.i));
	printf("%p\n", &(un.c));

	return 0;
}

在这里插入图片描述
他们的地址一样?到这我们就不难理解联合体的共用空间是什么意思了:
在这里插入图片描述
那也就是说两个成员不能同时使用,如果同时使用,会互相干扰,我们来验证一下:

union Un
{
	char c;
	int i;
};

int main()
{
	union Un un = { 0 };
	un.i = 0x11223344;
	un.c = 0x55;

	printf("%x ", un.i);

	return 0;
}

运行结果:
在这里插入图片描述
代码1输出的三个地址⼀模⼀样,代码2的输出,我们发现将i的第4个字节的内容修改为55了。我们仔细分析就可以画出,un的内存布局图。

在这里插入图片描述

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

我们再对⽐⼀下相同成员的结构体和联合体的内存布局情况。

在这里插入图片描述

在这里插入图片描述

1.4 联合体大小的计算

通过刚刚的例子,我们对联合体的大小有了初步的认识,联合体的大小是最大成员的大小?
我们来看看下面的例子:

union Un
{
	char c[5];
	int i;
};


int main()
{
	union Un un = { 0 };
	printf("%zd\n", sizeof(un));
	return 0;
}

这个结果是否是5,我们来看看结果:
在这里插入图片描述
结果与我们想的并不一样,那联合体的大小到底如何计算,我们往下看:

• 联合的⼤⼩⾄少是最⼤成员的⼤⼩。
• 当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候,就要对⻬到最⼤对⻬数的整数倍

char [5]的类型是char,所以他的对齐数就是1,int i的对齐数就是4,所以联合体的大小必须是4的倍数,最小是5,所以结果为8;

来点练习:

union Un2
{
 short c[7];
 int i;
};
int main()
{
 //下⾯输出的结果是什么?
 printf("%d\n", sizeof(union Un2));
 return 0;
}

结果可以在评论区打出

使⽤联合体是可以节省空间的,

举例:
⽐如,我们要搞⼀个活动,要上线⼀个礼品兑换单,礼品兑换单中有三种商品:图书、杯⼦、衬衫。
每⼀种商品都有:库存量、价格、商品类型和商品类型相关的其他信息。
图书:书名、作者、⻚数
杯⼦:设计
衬衫:设计、可选颜⾊、可选尺⼨

那我们不耐⼼思考,直接写出⼀下结构

struct gift_list
{
 //公共属性
 int stock_number;//库存量
 double price; //定价
 int item_type;//商品类型
 
 //特殊属性
 char title[20];//书名
 char author[20];//作者
 int num_pages;//⻚数
 
 char design[30];//设计
 int colors;//颜⾊
 int sizes;//尺⼨
};

上述的结构其实设计的很简单,⽤起来也⽅便,但是结构的设计中包含了所有礼品的各种属性,这样使得结构体的⼤⼩就会偏⼤,⽐较浪费内存。因为对于礼品兑换单中的商品来说,只有部分属性信息是常⽤的。⽐如:
商品是图书,就不需要design、colors、sizes。

在这里插入图片描述

所以我们就可以把公共属性单独写出来,剩余属于各种商品本⾝的属性使⽤联合体起来,这样就可以介绍所需的内存空间,⼀定程度上节省了内存。

struct gift_list
{
 int stock_number;//库存量
 double price; //定价
 int item_type;//商品类型
 
 union{
 struct
 {
 char title[20];//书名
 char author[20];//作者
 int num_pages;//⻚数
 }book;
 struct
 {
 char design[30];//设计
 }mug;
 struct
 {
 char design[30];//设计
 int colors;//颜⾊
 int sizes;//尺⼨
 }shirt;
 }item;
};

1.5 联合体的⼀个练习

写⼀个程序,判断当前机器是⼤端?还是⼩端?

在这里插入图片描述
这里我们利用联合体共用空间的特点,我们创建一个联合体,里面放一个int类型和char类型,我们赋值个int类型1,然后返回char如果是1则是小端,0则是大端;

int check_sys()
{
 union
 {
 int i;
 char c;
 }un;
 un.i = 1;
 return un.c;//返回1是⼩端,返回0是⼤端
}

这个代码两个字形容:优雅;
我们可以验证一下:

int check_sys()
{
	union
	{
		int i;
		char c;
	}un;
	un.i = 1;
	return un.c;//返回1是⼩端,返回0是⼤端
}

int main()
{
	if (check_sys() == 1)
		printf("小端");
	else
		printf("大端");
	return 0;
}

在这里插入图片描述
结果是如我们所料,VS是小端存储;


总结

到这我们对联合体有了基本的了解,再日后通过进一步使用,我们可以掌握联合体的使用规则,到这这期就结束了,下期我们来讲C语言的最后一个自定义类型——枚举,下期见。


标签:自定义,int,联合体,C语言,char,union,un,printf
From: https://blog.csdn.net/2303_78558007/article/details/142616901

相关文章

  • C语言-文件操作这一篇足够
    目录 1.文件是什么2.文件类型 2.1 程序文件 2.2 数据文件  2.3文件名3.文件的打开与关闭 3.1文件指针3.2文件的打开与关闭 3.2.1fopen和fclose 4.文件的顺序读写 4.1fgetc和fputc4.2fgets和fputs 4.3fscanf和fprintf4.4fread和fwrite 5.......
  • C语言-动态内存管理(malloc、calloc、realloc)
    目录1.内存布局2.动态内存函数2.1malloc2.1.1malloc是什么2.1.2如何用​编辑2.2free2.2.1free是什么2.2.2如何用2.3calloc2.3.1calloc是什么2.4realloc2.4.1realloc是什么2.4.2realloc如何使用2.4.3realloc可以实现与malloc同样的功能3.常见的动态......
  • C语言指针plus版
            本篇文章,我们将一起探讨指针高级版一、指针数组、数组指针    1.1指针数组    就是存放指针的数组,因此指针数组是一个数组,不是指针    例如:   int*pa[5];   //整型指针的数组   char*pb[2];  //字符型指针......
  • C语言语句
    C语言语句C语言中的的代码是由一条条语句构成,而基本语句分为:•空语句•表达式语句•函数调⽤语句•复合语句•控制语句空语句简而言之,无语句,一个分号为一条语句#include<stdio.h>//主函数intmain(){ ;//空语句 return0;}表达式语句表达式语句......
  • 初始C语言
    C语言程序设计初始C语言初始C语言主要讲解其基础语法、常量变、运算符等等,这是C语言最基本得语法结构,这些是支撑一个程序的必需品,是重中之重。基础语法C语言的令牌主要包括以下几种类型:关键字(Keywords)标识符(Identifiers)常量(Constants)字符串字面量(StringLiterals)......
  • 深入剖析 MyBatis-Plus:操作总结、对比与实践案例(CRUD 操作、分页、条件构造器、自动填
    MyBatis-Plus是MyBatis的增强工具,它极大简化了MyBatis的配置和操作,提高了开发效率。本文从基本操作到高阶用法,详细介绍了MyBatis-Plus的常见功能及与MyBatis的区别,并通过实际案例展示其强大的扩展能力。MyBatis-Plus基于MyBatis,但旨在减少开发者的代码量,增强可......
  • 实验1 c语言输入输出和简单程序编写
    任务1:task1.11#include<stdio.h>2345intmain()6{7printf("o\n");8printf("<H>\n");9printf("II\n");10printf("o\n"......
  • 【C语言用筛选法求质数】
    C语言用筛选法求质数筛选法,另一种思路的求质数方法上面的方法数越大判断次数越多,运算时间越长,效率越差,如果对于给定的一个集合,可以用筛选法,思路是将集合中的非质数(合数)标出来,余下来的就是质数了。给定的字符数组charprime[100]={0};,初始化为0,默认全是质数:-)!prime[0]=......
  • 【C语言标准库函数】标准输入输出函数详解2:字符串输入输出
    目录一、字符串输入函数1.1.gets函数(已废弃)1.1.1.函数简介1.1.2.注意和废弃原因1.2.fgets函数1.2.1.函数简介1.2.2.使用场景1.2.3.注意事项1.2.4.示例二、字符串输出函数2.1.puts函数2.1.1.函数简介2.1.2. 使用场景2.1.3.注意事项2.1.4.示例2.2.......
  • C语言 16 系统库
    前面了解了如何使用#include引入其他文件,接着来了解一下系统提供的一些常用库。字符串计算字符串长度:#include<stdio.h>#include<string.h>intmain(){char*c="HelloWorld!";//使用strlen计算长度,注意返回值类型是size_t(别名而已,本质上就是unsignedlong)......