C语言Union详解:内存共享与类型转换应用

创始人
2024-12-18 03:02:42
0 次浏览
0 评论

c语言,union有什么用?

结构基本相同,但从封装角度来看有区别。

1联合体中可以定义多个成员,联合体的大小由最大成员的大小决定。

2个Union成员共享相同的内存大小,并且一次只能使用一个成员。

3给一个成员赋值会覆盖其他成员的值(这并不奇怪,因为它们共享一些内存。
但前提是成员占用的字节数相同。
当数量成员占用的字节数将被同时覆盖(int占用四个字节)

4保存联合体的顺序是保存所有成员。
从低地址开始。

看下面的简单代码:

#includetypedefunion{charcinta;演示intmain(intargc,char**argv){演示d.c='H';d.a=10d.b=12printf("大小:%d\n",sizeof("%c\t%);d\t%d\n",d.c,d.a,d.b);return0;}

具体使用示例:

1.为了方便查看理解代码。
比如要写一个3*3的矩阵,可以这样写:

structMatrix

{

union

{

结构

{

float_f11、_f12、_f13、_f21、_f22、_f23、_f31、_f32、_f33;

};

floatf[3][3];

}_matrix;

};

structMatrixm;

这两个东西使用相同的空间,所以不存在空间浪费,当需要使用整个矩阵时,可以使用m._matrix.f(例如传递参数,或者一般赋值等);m._matrix._f11以避免它使用m.f[0][0](这是不直观且容易出错)。
2、用在强制类型转换上(比强制类型转换更容易理解:(1)判断系统使用的是h3endian还是littleendian(其定义可以网上查相关资料。
这里)

#defineTRUE1

#defineFALSE0

#defineBOOLint

布尔值isBigEndian()

{

inti=1/*i=0x00000001*/

charc=*(;char*)&i;/*注意不能写成charc=(char)i*/

if如果是小字节序的话,i=1的内存会按照升序放置:0x010x000x000x00这样的话,会以char*(1字节)的方式访问i的起始地址,所以c=0;相反的x01可能看起来不是很明显,让我们看一下:

BOOLisBigEndian()

{

union

{

inti;

charc;

}测试;

test.c=2;

returntest.i!=2;

}

这里使用union来检查这个共享布局,有一个知识问题是union中的成员c和i是从低地址开始对齐的。
无需转换即可得到相同的结果,这一点更加明显。
什么,你不觉得这很明显吗??那么看下面的例子:(2)将littleendian下的longlong类型的值替换为h3endian类型的值。
我们已经知道系统提供了如下API:longhtonl(longlg)它的功能就是将所有字节的顺序改为大字节顺序。
因此,采用如下方法:

htonLLlonglong(lglong)

<{

union

{

struct

{

长低;

长高;

}val_1;

长长val_2;

}val_arg,val_ret;

if(isBigEndian())

returnlg;

val_arg.val_2=lg;

val_ret.val_1.low=htonl(val_arg.val_1.high);

val_ret.val_1.high=htonl(val_arg.val_1.low

returnval_ret.val_2;

}

只要你画出的结构(3)要理解C++类表示,有以下类:

classtest

public:

floatgetFVal(){returnf;}

私有于:

inti;

charc;

floatf;

};

测试;

否您可以向Test类添加代码,并将值7.0ff赋给该对象。

classTest_Cpy

{

public:

>

floatgetVal(){returnf;}

f=f;}

私有:

inti;

charc;

floatf;

};

....

intmain()

{

测试t;

union

{

测试t1,

Test_Cpyt2;

}测试;

test.t2.setVal(7.0f);

t=test.t1;

断言(t.getVal()==7.0f);当您使用成员函数时,该类的对象的布局基本上保持不变。
因此,可以编写一个与Test类结构相同的Test_Cpy类,但多了一个setVal成员函数,然后将其绑定到uinon结构体上,为私有变量赋值。
(当存在虚拟机类和虚函数机制时,此方法可能会失败,因此不可移植。
)至于详细讨论,本示例没有实际用途。
这种内存表示合并在操作系统底层代码中经常使用,因为它内存分配的表示方便直观。
因此,网络编程、协议分析以及一些使用union的内核代码更容易理解,简化了设计。

union用法c语言

在C语言中,union是一种特殊的复合数据类型,它允许不同的数据类型存储在同一内存位置。
“union”的主要特征是其所有成员共享相同的内存空间,因此它足够大,至少可以存储其最大的成员。
使用“union”可以节省内存,但使用它时需要小心,因为一次只能使用它的一个成员。
“Union”的定义与结构体(“struct”)类似,但具有不同的关键字。
例如:````cunionData{inti;floatf;charstr[20];};```这里定义了一个`unionData`,它是一个`int`、一个`float`或者一个`char`数组(最大可以存储最多20个字符)。
然而,无论存储什么类型的数据,它们都位于并集的同一内存位置。
因此,如果您首先存储“int”值,然后尝试读取“float”值,则结果将是未定义的,因为这两种类型在内存中的表示方式完全不同。
Union常用于需要节省内存但同时只使用一种数据类型的场景,例如硬件编程中模拟读写寄存器,或者实现简单状态机等。

c语言里的union和enum怎么用

1.Union

Union允许不同的数据类型访问同一块内存,实际上将数据存储在同一位置。
虽然它们的声明和用法与结构体非常相似,但它们的实际功能却有很大不同。

unionmodel_name{type1element1;pe2element2;type3element3.}object_name;

union中所有声明的元素都位于同一内存中占用空间,其大小为声明中最长元素的大小。
示例:

unionmytypes_t{charc;floatf;}mytypes;>

定义了三个元素:

mytypes.c;mytypes.i;mytypes.f;

每个都是不同的数据类型。
它们都指向相同的内存空间,因此更改一个元素的值会影响所有其他元素的值。

Union的一种用途是将较长的基本类型与由其他较小数据类型组成的结构或数组组合在一起,例如:

Unionmix_t{longl;{短hi;}s;charc[4];}mix;

上面的示例中,定义了三个名称:mix.l、mix.s和mix.c。
通过这三个名称来访问同一个4字节内存空间。
用于访问的名称取决于您使用的数据类型(长整型、短整型、字符型等)。
下图显示了内存中该联合的每个元素的可能结构以及如何使用不同的数据类型访问它。

2.枚举类型

1.枚举定义

枚举定义的一般格式为::

enum枚举名称{枚举值表};

值表必须列出所有可用的值。
这些值也称为枚举元素。

示例:

此枚举称为工作日,有7个枚举值,即一周中的7天。
声明为工作日类型的变量的值只能是7天中的一天。

2.解释枚举变量

与结构体和联合体一样,枚举变量可以用多种方式编写。
即先定义,后解释。
还定义指令或直接指令。

假设上面变量a、b、c写为星期几,可以使用以下方法之一:

枚举工作日{sun,already,Tuesday,Wednesday,Thursday,Friday,Saturday};枚举工作日a,b,c;

或者:

枚举工作日{sun,mou,tue,wed,thu,fri,sat}a,b,c;

或:

enum{sun,Tuesday,wed,thu,fri,sat}a,b,c;

3.枚举类型变量赋值和枚举的使用

以下规则适用于枚举类型的使用:

a.枚举值是常量,而不是变量。
你不能在程序中使用赋值语句来赋值。

例如,将以下值分配给星期几枚举的​​元素:

sun=5;mon;

他们都错了。

b.枚举元素本身被系统定义为表示从0开始并连续为0、1、2等的数字。
例如,在工作日,sun值为0,mon值为1,...,sat值为6。

#includeintmain(){enumWeekdays{周日、周一、周二、周三、周四、周五、周六}a、b、c;一个=sun;b=mon;c=tue;printf("%d,%d,%d",a,b,c);return0;}

说明:

只能将枚举值赋值给枚举变量;不能将元素值直接赋值给枚举变量。

a=sum;b=mon;

正确。

a=0;b=1;

是错误的。
如果需要给枚举变量赋值,则必须使用强制转换。

示例:

a=(enumWeekday)2;

表示依次改变enum类型就是做。
将数字2枚举元素分配给枚举变量a相当于:

a=tue;
热门文章
1
C语言字符串常量解析:区别、用途及存储方... 什么是字符串常量字符串常量是C语言中的一种数据类型,它是由一对双引号括起来的字符...

2
C语言printf函数:格式字符串与输出... printf函数中的格式与输出项有什么关系?在C语言中,printf函数中的格式...

3
Excel技巧:计算字符串起始位置与合并... 如何计算字符串在特定文本中的起始位置,怎么计算字符串在特定文本中的起始位置您可以...

4
Python发音全解:掌握正确的发音方法... python怎么读我的很多学习编程的朋友可能都知道Python这个词,但是他们中...

5
字符与字符串:编程中的基础文本类型解析 字符串什么意思字符串是由数字、字母和下划线组成的字符串,表示为s=“a1a2…a...

6
Python编程语言:多领域应用与开发优... Python的作用是什么?Python是一种跨平台计算机编程语言,是ABC语言的...

7
深度解析:C语言编程特点与应用领域 什么叫c语言C语言是一种编程语言。C编程语言应用广泛,具有以下特点和特点:1.语...

8
Java全解析:跨平台编程语言的魅力与多... java是什么Java是一种功能强大的编程语言,被称为“一次编写,随处运行”模型...

9
Excel字符提取技巧:轻松使用LEFT... 如何在Excel中提取文本字符串中的字符?在Excel中,要单独提取文本字符串中...

10
C语言字符串转数字:常用函数及转换技巧详... c语言所有类型转换函数C语言提供了多种类型转换函数,包括atoi()、atol(...