首页 > 其他分享 >65.【C语言】联合体

65.【C语言】联合体

时间:2024-10-03 14:47:10浏览次数:8  
标签:int 数为 联合体 C语言 union 65 printf 对齐

目录

目录

1.定义

2.格式

3.例题

答案速查

分析

4.练习

答案速查

分析

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

6.联合体的大小计算

2条规则

 答案速查

分析

练习

答案速查

分析

7.联合体的优点

8.匿名联合体


1.定义

和结构体有所不同,顾名思义:所有成员联合使用同一块内存空间,因此也叫共用体

注:编译器只为最大的成员分配足够的内存空间;如果不符合对齐数,则会增加一部分空间(有关联合体的大小计算见第6点)给联合体其中一个成员赋值,其他成员的值也跟着变化

2.格式

union 联合体标签
{
  //......
};

3.例题

求下列代码的执行结果

#include <stdio.h>
union U
{
	char a;
	int b;
};

int main()
{
	printf("%zd\n", sizeof(union U));
	union U u;
	printf("%p\n", &u);
	printf("%p\n", &u.a);
	printf("%p", &u.b);
	return 0;
}

答案速查

d4118c9946ba4652ad1c468a86b830dc.png

分析

01.printf("%zd\n", sizeof(union U));

编译器只为最大的成员分配足够的内存空间

char a 对齐数为1,int b对齐数为4(注:联合体对齐数的计算方法同结构体的),因此为a和b分配4字节的空间

02.printf("%p\n", &u); & printf("%p\n", &u.a); & printf("%p", &u.b);

所有成员联合使用同一块内存空间,因此取地址的结果一样

4.练习

求下列代码执行后,联合体在内存中存储的数据

#include <stdio.h>
union U
{
	char a;
	int b;
};

int main()
{
	union U u;
	u.b = 0x12345678;
	u.a = 0x99;
	return 0;
}

答案速查

VS2022按小端序存储

因此为99 65 43 21

分析

运行环境x86+debug

下断点(F9)至u.a = 0x99;,内存窗口输入&u

b9e13e41a08b461a9d4da5df5afd1d63.png

执行至return 0;

90a02df542a140eeac5840f939cea39a.png

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

union U
{
	char a;
	int b;
};

struct S
{
	char a;
	int b;
};

ac2dc47ab413436b94608d0967af1600.png025ef410d82543c893989cd7d66fa485.png

6.联合体的大小计算

2条规则

1.联合的大小至少是最大成员的大小

2.当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍(多数人往往会忽视第2点)

例如:

求下列代码的执行结果

#include <stdio.h>
union U
{
	char a[5];
	int b;
};

int main()
{
	printf("%zd", sizeof(union U));
	return 0;
}

 答案速查

8ed448d2452149db8085ca5330e76076.png

分析

如果不考虑第二点规则,答案应该是5

如果考虑第二点规则,

char a[5]; 自身对齐数:1,VS默认对齐数:8,所以对齐数为1

int b; 自身对齐数:4,VS默认对齐数:8,所以对齐数为4

a[5]与b的最大对齐数为4

所以联合体的大小至少为4的整数倍(4,8,12,...,4k),大于5且最近的4整数倍的数为8

练习

求下列代码的执行结果

#include <stdio.h>
union U
{
	short a[7];
	int b;
};

int main()
{
	printf("%zd", sizeof(union U));
	return 0;
}

答案速查

05214c9e024a433b9710d8eb6dc37303.png

分析

short a[7]; 自身对齐数:2,VS默认对齐数:8,所以对齐数为2

int b; 自身对齐数:4,VS默认对齐数:8,所以对齐数为4

如果不考虑第二点规则,答案应该是14(7*2=14)

如果考虑第二点规则,short a[7];与int b;的最大对齐数为4,所以联合体的大小至少为4的整数倍(4,8,12,...,4k),大于14且最近的4整数倍的数为16

7.联合体的优点

如果一些变量既有公共属性,又有各自的联合属性,可以把公共属性单独写出来,剩余属于各自本身的属性使用联合体起来(联合体内嵌结构体)

这样可以节省空间

8.匿名联合体

同匿名结构体,见文63.【C语言】再议结构体(上)

标签:int,数为,联合体,C语言,union,65,printf,对齐
From: https://blog.csdn.net/2401_85828611/article/details/142652318

相关文章

  • C语言 函数指针
    概念在C语言中,函数指针是一种特殊的指针类型,它指向的是函数而不是普通的数据变量。函数在内存中有其入口地址,函数指针就是用来存储这个地址的变量。函数指针的定义函数指针的定义形式如下:返回值类型(*指针变量名)(参数类型列表);例如,定义一个指向返回值为int,参数为int......
  • 实验1 C语言输入输出和简单程序编写
    实验1:#include<stdio.h>intmain(){printf("0\n");printf("<H>\n");printf("II\n");return0;}  实验2:#include<stdio.h>intmain(){doublea,b,c;scanf("%l......
  • C语言顺序表 逐行解析!!!
    1、顺序表的概念及结构线性表(linearlist)是n个具有相同特性的数据元素的有限序列。线性表是⼀种在实际中⼴泛使⽤的数据结构,常⻅的线性表:顺序表、链表、栈、队列、字符串...线性表在逻辑上是线性结构,也就说是连续的⼀条直线。但是在物理结构上并不⼀定是连续的,线性表在物......
  • 实验一 C语言开发环境使用和数据类型,运算符,表达式
    #include<stdio.h>intmain(){printf("0\n");printf("<H>\n");printf("II\n");printf("0\n");printf("<H>\n");printf("II\n");return0;......
  • 65_索引管理_定制化自己的dynamic mapping策略
    课程大纲1、定制dynamic策略true:遇到陌生字段,就进行dynamicmappingfalse:遇到陌生字段,就忽略strict:遇到陌生字段,就报错PUT/my_index{"mappings":{"my_type":{"dynamic":"strict","properties":{"title":{"type":&......
  • C语言 共用体
    概念在C语言中,共用体(Union)是一种特殊的数据类型。它可以在不同的时刻存储不同类型的数据,但所有成员共享同一块内存空间。这与结构体不同,结构体的每个成员都有自己独立的内存空间。定义和声明定义共用体的定义形式与结构体相似,使用关键字union。例如:unionData{int......
  • C语言内存对齐
    概念在C语言中,内存对齐(MemoryAlignment)是一种编译器为了提高内存访问效率而采用的一种数据存储策略。它要求数据在内存中的存储地址是某个特定值(通常是数据类型大小或其倍数)的整数倍。为什么要进行内存对齐提高内存访问速度现代计算机的内存系统是以字节为单位进行组织......
  • 理解C语言之深入理解指针(四)
    目录1.回调函数是什么?2.qsort使⽤举例2.1使⽤qsort函数排序整型数据2.2使⽤qsort排序结构数据3.qsort函数的模拟实现1.回调函数是什么?        回调函数就是⼀个通过函数指针调⽤的函数。        如果你把函数的指针(地址)作为参数传递给另⼀个......
  • C语言开发windows程序主要程序结构
    一、两个函数1.WinMain,WindowsAPI主函数。本次示例中WinMain包含的三个内容: +.注册窗口 +.创建窗口 +.消息循环2.窗口过程(WndProc) 窗口过程,通过窗口过程(WndProc)与用户交互和管理窗口。二、Windows程序示例基于C语言开发的windows图形界面程序/*** title:Windows程......
  • 个人感悟##C语言中的得与失
    个人练习感悟1.三个任意整数从小到大排序#include<stdio.h>#include<stdlib.h>intmain(){inta,b,c;printf(“我可以为您进行从大到小排序,请任意输入三个的整数:”);scanf(“%d%d%d”,&a,&b,&c);if(a>b&&a>c)if(b>c)printf(“%d,%d,%d”,a,b,c);elseif(b<c)......