您的位置:首页 > 其它

union 类型数据存储及计算

2015-03-31 21:12 295 查看
今天在做一个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 << "litter"<<endl;
    else
        cout << "big"<<endl;
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: