标签:union-数据计算 大端 小端
今天在做一个C语言题目的时候,碰上了这样一题:
#include <iostream>
using namespace std;
union
{
int i;
char x[2];
}a;
int main()
{
a.x[0] = 10;
a.x[1] = 1;
cout<<a.i;
system("pause");
return 0;
}
结果是这样的:
开始我的思路是 int 占四个字节,x[0],x[1]分别一个字节,由于惯性地认为x[0]是排在x[1]前面的,int第一个字节与之对应前面的一个字节x[0],第二节字节对应x[1],这样结果就是00001010 00000001也就是2561,但事实上却是 00000001 00001010,也就是256 + 10 = 266,我也是百思不得其解,后面找各种资料,终于发现了其中奥秘。
众所周知,c语言分为很多版本,其中用的比较多的就是c80和c99两种版本,现在我们用的基本上都是c99,这里以c99为标准。(c80中int占两个字节,而c99中占4个字节)
通过查阅资料,得知计算机分为大端和小端两种方式存储,主要跟cpu的内部指令有关,那么下面具体说一下这两种存储方式的区别。
大端模式和小端模式。
大端模式(Big_endian):字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。
小端模式(Little_endian):字数据的高字节存储在高地址中,而字数据的低字节则存放在低地址中。
union 型数据所占的空间等于其最大的成员所占的空间,当然这句话是在c80上适用,但是在c99上是不适用的,c99中不管是struct 还 union类型都要考虑内存对齐的情况,这里不细说。对union 型的成员的存取都是相对于该联合体基地址的偏移量为0 处开始,也就是联合体的访问不论对哪个变量的存取都是从union 的首地址位置开始。
先分析一下,按照上面关于大小端模式的定义,假设int 类型变量i 被初始化为1。
以大端模式存储,其内存布局如下图:
以小端模式存储,其内存布局如下图:
那么我们可以根据大端和小端的特性来判断
数组元素的排列永远是从地地址到高地址,这个和cpu采用的大端或者是小端没有影响,所以,对于大端模式,字符数组对应的int 数据内存:
小端模式:
而一般现在所用的cpu基本上是采用的小端模式,也就是第二种对应方式,所以计算方式有所改变。
其次,我们可以通过int类型的低位与字符型数组的第一个元素是否相等来判断一台机器的cpu采用的是大端模式还是小端模式:
这里用开始的union程序也就是:i == a.x[0]来进行判断.
#include <iostream>
using namespace std;
union
{
int i;
char x[2];
}a;
int main()
{
a.x[0] = 1;
a.x[1] = 0;
if (a.i == a.x[0])
cout << "little"<<endl;
else
cout << "big"<<endl;
return 0;
}
标签:union-数据计算 大端 小端
原文地址:http://blog.csdn.net/fantasydreams/article/details/44782817