关于联合的一道题解决办法

关于联合的一道题我对联合的概念不太清除,所以不知道结果怎么出来的,哪位高人给指点指点a)#includestdio.

关于联合的一道题
我对联合的概念不太清除,所以不知道结果怎么出来的,哪位高人给指点指点

a)
#i   nclude   <stdio.h>
union
{
int   i;
char   x[2];
}a;

void   main()
{
a.x[0]   =   10;  
a.x[1]   =   1;
printf( "%d ",a.i);
}
答案:266   (低位低地址,高位高地址,内存占用情况是Ox010A)
b)
          main()  
          {  
                    union{                                       /*定义一个联合*/  
                              int   i;  
                              struct{                           /*在联合中定义一个结构*/  
                                        char   first;  
                                        char   second;  
                              }half;  
                    }number;  
                    number.i=0x4241;                   /*联合成员赋值*/  
                    printf( "%c%c\n ",   number.half.first,   mumber.half.second);  
                    number.half.first= 'a ';       /*联合中结构成员赋值*/  
                    number.half.second= 'b ';  
                    printf( "%x\n ",   number.i);  
                    getch();  
          }  
答案:   AB       (0x41对应 'A ',是低位;Ox42对应 'B ',是高位)
              6261   (number.i和number.half共用一块地址空间)


[解决办法]
还和CPU的大小头有关系呢。你的答案算完全正确。
[解决办法]
这个和运行环境 大小端序 相关
[解决办法]
LZ加一下打印信息就很清楚了,a.x和a.i是共用地址的
a.x[0] = 10;
a.x[1] = 1;
printf( "%p,%p, %p %d ",&a.x[0],&a.x[1], &a.i,a.i);

联合体采用成员最大尺寸的空间
int i //4字节
char x[2]; //2*1字节
故a的大小是4字节
a.x[0] = 10;
a.x[1] = 1;
a的第一个字节的值是10
a的第二个字节的值是1

我们目前的系统大多是小模式序,低地址存高位数据,故a.i就为0x010A了,(10的16进制为0A)
数据存储的大小模式参考
http://blog.csdn.net/TrueLie/archive/2006/02/10/596356.aspx

第二题类似
[解决办法]
Endianism

Endianism 是指用来存储数据的方法,它定义了整数和浮点数据类型中是如何对字节进行寻址的。

Little-endian 是将低位字节存储在内存的低地址中,将高位字节存储在内存的高地址中。



Big-endian 是将高位字节存储在内存的低地址中,将低位字节存储在内存的高地址中。

表 3 给出了一个 64 位长整数的布局示例。


表 3. 64 位 long int 类型的布局

低地址 高地址
Little endian Byte 0 Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6 Byte 7
Big endian Byte 7 Byte 6 Byte 5 Byte 4 Byte 3 Byte 2 Byte 1 Byte 0


例如,32 位的字 0x12345678 在 big endian 机器上的布局如下:


表 4. 0x12345678 在 big-endian 系统上的布局
内存偏移量 0 1 2 3
内存内容 0x12 0x34 0x56 0x78


如果将 0x12345678 当作两个半字来看待,分别是 0x1234 和 0x5678,那么就会看到在 big endian 机器上是下面的情况:


表 5. 0x12345678 在 big-endian 系统上当作两个半字来看待的情况
内存偏移量 0 2
内存内容 0x1234 0x5678


然而,在 little endian 机器上,字 0x12345678 的布局如下所示:


表 6. 0x12345678 在 little-endian 系统上的布局
内存偏移量 0 1 2 3
内存内容 0x78 0x56 0x34 0x12


类似地,两个半字 0x1234 和 0x5678 如下所示:


表 7. 0x12345678 在 little-endian 系统上作为两个半字看到的情况
内存偏移量 0 2
内存内容 0x3412 0x7856


下面这个例子解释了 big endian 和 little endian 机器上字节顺序之间的区别。

下面的 C 程序在一台 big endian 机器上进行编译和运行时会打印 “Big endian”,在一台 little endian 机器上进行编译和运行时会打印 “Little endian”。


清单 2. big endian 与 little endian
#include <stdio.h>
main () {
int i = 0x12345678;
if (*(char *)&i == 0x12)
printf ( "Big endian\n ");
else if (*(char *)&i == 0x78)
printf ( "Little endian\n ");
}



Endianism 在以下情况中非常重要:

使用位掩码时
对象的间接指针地址部分

在 C 和 C++ 中有位域来帮助处理 endian 的问题。我建议使用位域,而不要使用掩码域或 16 进制的常量。有几个函数可以用来将 16 位和 32 位数据从 “主机字节顺序” 转换成 “网络字节顺序”。例如,htonl (3)、ntohl (3) 用来转换 32 位整数。类似地,htons (3)、ntohs (3) 用来转换 16 位整数。然而,对于 64 位整数来说,并没有标准的函数集。但是在 big endian 和 little endian 系统上,Linux 都提供了下面的几个宏:

bswap_16
bswap_32
bswap_64

[解决办法]
看计算机怎么存放数据的,一般高位在高地址的字节,低位在低地址的字节
有的机器正好反着的
所以是不一定的,和机器相关