.NET人字拖
万丈高楼平地起,我正在努力筑地基...
随笔- 134  文章- 0  评论- 606 
博客园  社区  首页  新随笔  联系  管理  订阅 订阅

c++中union的使用,看高手们如何解释的

union主要是共享内存,分配内存以其最大的结构或对象为大小,即sizeof最大的。在C/C++程序的编写中,当多个基本数据类型或复合数据结构要占用同一片内存时,我们要使用联合体;当多种类型,多个对象,多个事物只取其一时(我们姑且通俗地称其为“n 选1”),我们也可以使用联合体来发挥其长处。一下转载自网站:

在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 源代码的精妙之处!(如果ENDIANNESS=’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;

 

关于作者:网魂小兵

文章出处:http://xdotnet.cnblogs.com

本文可以随意转载,摘抄等非商业用途。

为了尊重作者成果,在转载和摘抄的时候请留下作者名称和出处。

标签: union, Little endian, Big endian
绿色通道:好文要顶关注我收藏该文与我联系
posted @ 2011-04-20 17:27 网魂小兵 阅读(322) 评论(0) 编辑 收藏
注册用户登录后才能发表评论,请 登录 或 注册,返回博客园首页。
首页博问闪存新闻园子招聘知识库
最新IT新闻:
· Twitter联合创始人:长时间用Twitter不利健康
· 盛大文学重启赴美IPO计划拟融资2亿美元
· 谷歌招聘揭秘:入职就像进入美军海豹突击队
· 诺基亚超HTC成第一大Windows Phone手机商
· Google Voice支持圈子功能:可用于过滤来电
» 更多新闻...
最新知识库文章:
· 领域模型管理与AOP
· 编程的艺术:漂亮的代码和漂亮的软件
· GIT分支管理是一门艺术
· 编程:是一门艺术
· 编程是一门艺术吗?
» 更多知识库文章...

China-pub 2011秋季教材巡展
China-Pub 计算机绝版图书按需印刷服务
Copyright ©2012 网魂小兵
Name:
网魂小兵
Addr:
福建厦门
MSN:
myxbing#hotmail.com
昵称:网魂小兵
园龄:6年
粉丝:24
关注:0

搜索

 
 

常用链接

  • 我的随笔
  • 我的评论
  • 我的参与
  • 最新评论
  • 我的标签
  • 更多链接

我的标签

  • directx11(6)
  • direct3d 11(6)
  • 游戏编程(6)
  • c/c++(6)
  • vs2010(5)
  • wpf(4)
  • openssl(2)
  • direct3d坐标系(2)
  • vs2008(2)
  • xaml(2)
  • 更多

随笔分类(170)

  • AJAX(doc)(8)
  • ASP.NET(46)
  • C#3.0+(13)
  • C/C++(27)
  • CommunityServer(7)
  • Database(11)
  • Enterprise Library (7)
  • JavaScript(10)
  • ServerContols(7)
  • UML(1)
  • VC++/MFC(8)
  • WPF/SilverLight(6)
  • XNA Game(2)
  • 翻译(4)
  • 今天我当家(11)
  • 设计模式(2)

随笔档案(134)

  • 2012年2月 (4)
  • 2011年8月 (3)
  • 2011年7月 (7)
  • 2011年5月 (1)
  • 2011年4月 (2)
  • 2011年2月 (1)
  • 2010年1月 (1)
  • 2009年3月 (3)
  • 2009年1月 (8)
  • 2008年3月 (1)
  • 2008年2月 (3)
  • 2008年1月 (1)
  • 2007年11月 (4)
  • 2007年10月 (3)
  • 2007年9月 (9)
  • 2007年8月 (3)
  • 2007年7月 (2)
  • 2007年6月 (9)
  • 2007年5月 (9)
  • 2007年4月 (14)
  • 2007年3月 (6)
  • 2007年2月 (3)
  • 2007年1月 (15)
  • 2006年12月 (9)
  • 2006年11月 (2)
  • 2006年10月 (4)
  • 2006年9月 (7)

文章分类

  • Asp.Net(.NET)

I Like Links

  • ASP.NET
  • Codeplex
  • XNADevelopment

My Friend's Blog

  • 陆巍杰
  • 孙小雨
  • 探丫头
  • 网络安全&Linux

积分与排名

  • 积分 - 284251
  • 排名 - 247

最新评论

阅读排行榜

评论排行榜