码迷,mamicode.com
首页 > 其他好文 > 详细

union 类型数据存储及计算

时间:2015-03-31 22:19:51      阅读:182      评论:0      收藏:0      [点我收藏+]

标签: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 类型数据存储及计算

标签:union-数据计算   大端   小端   

原文地址:http://blog.csdn.net/fantasydreams/article/details/44782817

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!