关于联合的一道题
我对联合的概念不太清除,所以不知道结果怎么出来的,哪位高人给指点指点
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
[解决办法]
看计算机怎么存放数据的,一般高位在高地址的字节,低位在低地址的字节
有的机器正好反着的
所以是不一定的,和机器相关
