`
CB-13
  • 浏览: 22428 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

C语言中的联合体union

阅读更多
在C/C++程序的编写中,当多个基本数据类型或复合数据结构要占用同一片内存时,我们要使用联合体;当多种类型,多个对象,多个事物只取其一时(我们姑且通俗地称其为“n 选1”),我们也可以使用联合体来发挥其长处。首先看一段代码:
union myun 
{
 struct { int x; int y; int z; }u; 
 int k; 
}a; 
int main() 
{ 
 a.u.x =4;
 a.u.y =5; 
 a.u.z =6; 
 a.k = 0; 
 printf("%d %d %d\n",a.u.x,a.u.y,a.u.z);
 return 0;
}

union类型是共享内存的,以size最大的结构作为自己的大小,这样的话,myun这个结构就包含u这个结构体,而大小也等于u这个结构体的大小,在内存中的排列为声明的顺序x,y,z从低到高,然后赋值的时候,在内存中,就是x的位置放置4,y的位置放置5,z的位置放置6,现在对k赋值,对k的赋值因为是union,要共享内存,所以从union的首地址开始放置,首地址开始的位置其实是x的位置,这样原来内存中x的位置就被k所赋的值代替了,就变为0了,这个时候要进行打印,就直接看内存里就行了,x的位置也就是k的位置是0,而y,z的位置的值没有改变,所以应该是0,5,6

再看两个试题:

试题一:
编写一段程序判断系统中的CPU 是Little endian 还是Big endian 模式?

分析:
作为一个计算机相关专业的人,我们应该在计算机组成中都学习过什么叫Little endian 和Big endian。Little endian 和Big endian 是CPU 存放数据的两种不同顺序。对于整型、长整型等数据类型,Big endian 认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节);而Little endian 则相反,它认为第一个字节是最低位字节(按照从低地址到高地址的顺序存放数据的低位字节到高位字节)。

例如,假设从内存地址0x0000 开始有以下数据:

0x12 0x34 0xab 0xcd

如果我们去读取一个地址为0x0000 的四个字节变量,若字节序为big-endian,则读出结果为0x1234abcd;若字节序位little-endian,则读出结果为0xcdab3412。如果我们将0x1234abcd 写入到以0x0000 开始的内存中,则Little endian 和Big endian 模式的存放结果如下:

地址               0x0000 0x0001 0x0002 0x0003
big-endian         0x12   0x34   0xab   0xcd
little-endian      0xcd   0xab   0x34   0x12

一般来说,x86 系列CPU 都是little-endian 的字节序,PowerPC 通常是Big endian,还有的CPU 能通过跳线来设置CPU 工作于Little endian 还是Big endian 模式。

解答:
显然,解答这个问题的方法只能是将一个字节(CHAR/BYTE 类型)的数据和一个整型数据存放于同样的内存开始地址,通过读取整型数据,分析CHAR/BYTE 数据在整型数据的高位还是低位来判断CPU 工作于Little endian 还是Big endian 模式。得出如下的答案:
typedef unsigned char BYTE;
int main(int argc, char* argv[])
{
unsigned int num,*p;
p = #
num = 0;
*(BYTE *)p = 0xff;
if(num == 0xff)
{
printf("The endian of cpu is little\n");
}
else //num == 0xff000000
{
printf("The endian of cpu is big\n");
}
return 0;
}

除了上述方法(通过指针类型强制转换并对整型数据首字节赋值,判断该赋值赋给了高位还是低位)外,还有没有更好的办法呢?我们知道,union 的成员本身就被存放在相同的内存空间(共享内存,正是union 发挥作用、做贡献的去处),因此,我们可以将一个CHAR/BYTE 数据和一个整型数据同时作为一个union 的成员,得出如下答案:
int checkCPU()
{
 {
  union w
 {
  int a;
  char b;
 } c;
 c.a = 1;
 return (c.b == 1);
 }
}

实现同样的功能,我们来看看Linux 操作系统中相关的源代码是怎么做的:
static union { char c[4]; unsigned long mylong; } endian_test = {{ 'l', '?', '?', 'b' } };

#define ENDIANNESS ((char)endian_test.mylong)

Linux 的内核作者们仅仅用一个union 变量和一个简单的宏定义就实现了一大段代码同样的功能!由以上一段代码我们可以深刻领会到Linux 源代码的精妙之处!(如果NDIANNESS=’l’表示系统为little endian,为’b’表示big endian )

试题二:
假设网络节点A 和网络节点B 中的通信协议涉及四类报文,报文格式为“报文类型字段+报文内容的结构体”,四个报文内容的结构体类型分别为STRUCTTYPE1~ STRUCTTYPE4,请编写程序以最简单的方式组织一个统一的报文数据结构。

分析:
报文的格式为“报文类型+报文内容的结构体”,在真实的通信中,每次只能发四类报文中的一种,我们可以将四类报文的结构体组织为一个union(共享一段内存,但每次有效的只是一种),然后和报文类型字段统一组织成一个报文数据结构。

解答:
根据上述分析,我们很自然地得出如下答案:
typedef unsigned char BYTE;
//报文内容联合体
typedef union tagPacketContent
{
STRUCTTYPE1 pkt1;
STRUCTTYPE2 pkt2;
STRUCTTYPE3 pkt1;
STRUCTTYPE4 pkt2;
}PacketContent;
//统一的报文数据结构
typedef struct tagPacket
{
BYTE pktType;
PacketContent pktContent;
}Packet;
分享到:
评论

相关推荐

    C语言中联合体union的实例详解

    C语言中联合体union的实例详解 1.定义: union(int i, short s, char c) un; un.i = 3; printf(“i=%d”,un.i); printf(“length = %d\n”,sizeof(un);//==4,有最大的变量来决定 2.相当与java里的List T类型 3....

    C语言中的联合体(Union):高级用法与应用实例

    联合体是C语言中一种非常有用的数据类型,它允许在相同的内存位置存储不同类型的数据,节省内存空间并提高程序的灵活性。通过本文的介绍,读者可以更好地理解联合体的概念和特性,并在实际编程中灵活应用。联合体的...

    C#下利用类的方式封装了位操作类,仿照C语言的联合体配合结构体的方式

    C#本身并不像C语言那样内置了联合体(union)和结构体(struct)的位级操作支持,但我们可以利用类(class)来实现类似的功能。本项目即为在C#中封装了一个位操作类,模拟C语言中的联合体和结构体的位操作方式。 ...

    联合体的多面性:C语言中union的妙用

    C语言是一种广泛使用的计算机编程语言,具有以下特点: 1. **高级语言**:C语言是一种高级编程语言,设计用于编写系统软件和应用程序。 2. **结构化语言**:C语言支持结构化编程,允许使用条件语句、循环、函数等...

    C语言编程中的联合体union入门学习教程

    在C语言中,联合体(union)是一种特殊的复合数据类型,它允许在一个内存位置存储不同类型的值。这种特性使得联合体成为节省内存和实现特定数据操作的有效工具。本文将深入探讨C语言编程中联合体的基本概念、定义...

    STM8S单片机中union联合体的应用

    这意味着union中的所有成员共享同一块内存空间,这与结构体(struct)中每个成员各自占用独立空间的情况不同。使用union可以有效地节省内存,并在特定场景下实现数据的灵活转换。 **STM8S单片机中的联合体应用** 在...

    struct和union结构体和联合体的区别.pdf

    - **Struct(结构体)**:在C语言中,`struct`是一种用户自定义的数据类型,它允许将不同类型的变量组合在一起,形成一个新的复合数据类型。结构体中的各个成员可以拥有不同的数据类型,并且每个成员都有其独立的...

    C语言结构体、联合体、指针等

    以上内容涵盖了C语言中结构体、联合体、枚举类型以及指针的一些基本概念和高级应用,这些知识点对于理解和掌握C语言至关重要。通过这些概念的学习,开发者可以更好地设计和实现复杂的数据结构,提高程序的效率和...

    C语言结构体和联合体PPT课件.pptx

    在C语言中,结构体(Struct)和联合体(Union)是两种重要的复合数据类型,它们允许我们将多种不同类型的数据组合到一个单一的实体中。在本PPT课件中,我们将深入探讨这两种数据类型的定义、使用以及它们的区别。 ...

    C语言结构体和联合体PPT学习教案.pptx

    在C语言中,结构体(Struct)是一种复合数据...联合体(Union)是另一个类似的概念,但它在一个固定大小的内存空间中存储不同类型的成员,但这里并未详细展开。理解和熟练运用结构体是成为C语言编程高手的重要步骤。

    C语言、C++中的union用法总结

    `union`在C和C++中被称为共用体或联合体。它是一种数据结构,允许你在一个内存区域存储不同类型的数据。与结构体`struct`不同,结构体中每个成员都有独立的内存空间,而`union`的成员共享同一块内存。这意味着当你...

    C中Union的巧妙用法

    C语言中的联合体(Union)是一种特殊的数据类型,它允许在相同的内存位置存储不同的数据类型。在内存中,联合体所占的内存大小为最大成员的大小,使得联合体的所有成员都共享这一块内存区域。通过巧妙地使用联合体,...

    c语言课件(完整版)

    C语言提供了多种基本数据类型,如整型(int)、浮点型(float、double)、字符型(char)等,以及构造类型如枚举(enum)、结构体(struct)、联合体(union)。了解这些数据类型及其用法,能帮助我们创建各种变量并...

    谈谈C语言中构造类型数据.pdf

    本文将深入探讨C语言中的构造类型数据,包括结构体(struct)、联合体(union)以及枚举(enum),并阐述它们在实际编程中的应用和重要性。 首先,结构体是C语言中的一种复合数据类型,它允许我们将多个不同类型的...

    27、【C语言高级数据类型】联合体和枚举.rar

    在C语言中,高级数据类型包括结构体(struct)、共用体(union)以及枚举(enum)。这些数据类型使得我们可以更加灵活地处理复杂的数据结构,以满足各种编程需求。让我们详细探讨一下联合体和枚举这两个主题。 一、...

    C语言文法文档

    struct-or-union-specifier是C语言中的结构体或联合体说明符,包括struct和union。struct是C语言中的结构体,用于定义一个复杂的数据类型。union是C语言中的联合体,用于定义一个可以存储不同类型数据的变量。struct...

    C语言 C语言C语言C语言C语言C语言C

    2. **数据类型**(第3章):C语言有基本的数据类型,如整型(int)、字符型(char)、浮点型(float和double)等,还有自定义数据类型,如枚举(enum)、结构体(struct)和联合体(union)。数据类型的使用直接影响...

    cHelp C语言中文帮助文档

    8. **C语言特性**:如函数指针、位运算、结构体和联合体的解引用等,这些都是C语言特有的高级特性,cHelp文档会给出详细解释和实例。 9. **编程规范和最佳实践**:遵循良好的编程习惯可以提高代码的可读性和维护性...

Global site tag (gtag.js) - Google Analytics