高雅兰冷锋小说:从两道经典试题谈C/C 中联合体(union)的使用 - Inside SW,FW and HW R
来源:百度文库 编辑:九乡新闻网 时间:2024/05/17 00:44:12
从两道经典试题谈C/C++中联合体(union)的使用宋宝华 21cnbao sweek@21cn.com试题一:编写一段程序判断系统中的CPU是Little endian还是Big endian模式?分析:作为一个计算机相关专业的人,我们应该在计算机组成中都学习过什么叫Little endian和Big endian。Littleendian和Big endian是CPU存放数据的两种不同顺序。对于整型、长整型等数据类型,Bigendian认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节);而Littleendian则相反,它认为第一个字节是最低位字节(按照从低地址到高地址的顺序存放数据的低位字节到高位字节)。例如,假设从内存地址0x0000开始有以下数据: 0x0000 0x0001 0x0002 0x0003 0x12 0x34 0xab 0xcd 如果我们去读取一个地址为0x0000的四个字节变量,若字节序为big-endian,则读出结果为0x1234abcd;若字节序位little-endian,则读出结果为0xcdab3412。如果我们将0x1234abcd写入到以0x0000开始的内存中,则Littleendian和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 l; } endian_test = { { ‘l‘, ‘?‘, ‘?‘, ‘b‘ } };#define ENDIANNESS ((char)endian_test.l)Linux的内核作者们仅仅用一个union变量和一个简单的宏定义就实现了一大段代码同样的功能!由以上一段代码我们可以深刻领会到Linux源代码的精妙之处!试题二:假设网络节点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/C++程序的编写中,当多个基本数据类型或复合数据结构要占用同一片内存时,我们要使用联合体(试题一是这样的例证);当多种类型,多个对象,多个事物只取其一时(我们姑且通俗地称其为“n选1”),我们也可以使用联合体来发挥其长处(试题二是这样的例证)。
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=1054811
从两道经典试题谈C/C 中联合体(union)的使用 - Inside SW,FW and HW R
从两道经典试题谈C/C 中联合体(union)的使用 - Inside SW,FW and HW R
几道经典C语言面试题
C语言中地址操作符&的使用
C:\Documents and Settings
学习MISRA C之三:指针结构体联合体的安全规范
C 中Reference与指针(Pointer)的使用对比 - wu928320442的专栏 - CSDN博客
市场营销中“4P”“4C”“4R”“4S”的专业知识
营销中“4P”“4C”“4R”“4S”
营销中“4P”“4C”“4R”“4S”
营销中“4P”“4C”“4R”“4S”!
营销中“4P”“4C”“4R”“4S”
营销中“4P”“4C”“4R”“4S”
转帖:C罗同学阳光明媚的少女心~“me and kaka”萌翻了~~产生梅西悲催帝~(从一个很神秘的地方转来的) - 开心网
C面试题
C语言面试题
C面试题
马克思试题C
C 面试题
只言片语中c的人生哲理
如何混合使用C和C (上)
RS-232c接口的两机通信的问题 - C/C++ / C语言
C:Documents and Settings里的文件能删吗
C盘突然被装满,C:\Documents and Settings下面的文件夹Admini...