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;
}
时间: 2024-08-09 23:46:00

union 类型数据存储及计算的相关文章

PAT——A+B和C(考察类型数据存储)

A+B和C (15) 时间限制 1000 ms 内存限制 32768 KB 代码长度限制 100 KB 判断程序 Standard (来自 小小) 题目描述 给定区间[-2的31次方, 2的31次方]内的3个整数A.B和C,请判断A+B是否大于C. 输入描述: 输入第1行给出正整数T(<=10),是测试用例的个数.随后给出T组测试用例,每组占一行,顺序给出A.B和C.整数间以空格分隔. 输出描述: 对每组测试用例,在一行中输出“Case #X: true”如果A+B>C,否则输出“Case #

mysql那些事(2)时间类型数据如何存储

几乎每次数据库建模的时候,都会遇到时间类型数据存储的问题. mysql存储时间通常选择这四种类型:datetime.timestamp.int和bigint四种方式,到底使用什么类型,需要看具体的业务. 我们分别对这四种类型进行讨论. 1.datetime 这个类型可以存储8字节,表示从1000到9999年之间的数据.这个类型可以为空值,也可以自定义值,默认的初始值是"0000-00-00 00:00:00". 这种类型存储的存储的优点是数据可读性强,不需要函数做转换. 2.times

TableStore时序数据存储 - 架构篇

摘要: 背景 随着近几年物联网的发展,时序数据迎来了一个不小的爆发.从DB-Engines上近两年的数据库类型增长趋势来看,时序数据库的增长是非常迅猛的.在去年我花了比较长的时间去了解了一些开源时序数据库,写了一个系列的文章(综述.HBase系.Cassandra系.InfluxDB.Prometheus),感兴趣的可以浏览. 背景随着近几年物联网的发展,时序数据迎来了一个不小的爆发.从DB-Engines上近两年的数据库类型增长趋势来看,时序数据库的增长是非常迅猛的.在去年我花了比较长的时间去

大数据时代,计算模式从客户机/服务器到节点的转变

在数据库时代,计算机在分布体系中的角色有明确划分,不是客户机就是服务器,通常是一台服 务器连着多台客户机,服务器承担存储和计算的工作,客户机负责显示服务器的处理结果.高性能的计算机,比如小型机会被做为服务器,低端的计算机,如个人计 算机成为客户机.这就是以前经常说的Client/Server(客户机/服务器)结构. 到了大数据时代,这种角色已经悄然发生了变化.客户机/服务器的概念已经模糊化,被"节点"的概念取代.而这种变化的原因,归根结底,还是数据处 理需求发生了本质变化,迫使数据处理

Java String类型数据的字节长度

问题描述: 向Oracle数据库中一varchar2(64)类型字段中插入一条String类型数据,程序使用String.length()来进行数据的长度校验,如果数据是纯英文,没有问题,但是如果数据中包含中文,校验可以通过,但是在数据入库时经常会报数据超长. 问题分析: 既然问题是数据超长,那么问题应该就是出在数据长度校验上,也就是出在String.length()这个方法上,来看看JDK是如何描述这个方法的: [plain] view plain copy length public int

浅析数据存储的“那些事儿”

写在前面 对于运维来说,数据读取.安全与存储,也是至关重要的一点,数据存储的技术点也是相当的多,面比较广,今天,民工哥来给各位小伙伴聊一聊有关于数据存储的"那些事儿" 存储的概念介绍 数据存储对象包括数据流在加工过程中产生的临时文件或加工过程中需要查找的信息.数据以某种格式记录在计算机内部或外部存储介质上.数据存储要命名,这种命名要反映信息特征的组成含义.数据流反映了系统中流动的数据,表现出动态数据的特征:数据存储反映系统中静止的数据,表现出静态数据的特征,解释来源于百度百科.民工哥用

Cassandra存储time series类型数据时的内部数据结构?

因为我一直想用Cassandra来存储我们的数字电表中的数据,按照之前的文章(getting-started-time-series-data-modeling)的介绍,Cassandra真的和适合用于存储time series类型的数据,那么我就想要弄清楚,对于下面这张表 CREATE TABLE temperature ( weatherstation_id text, event_time timestamp, temperature text, PRIMARY KEY (weathers

Core Data存储自定义类型数据

目录: 一.使用CoreData存储基本数据 二.使用CoreData存储自定义类型数据 简单介绍CoreData CoreData是iOS编程中使用持久化数据存储的一种方式,我们知道CoreData并不是数据库本身,而是Apple提供的对象持久化技术--Object Persistent technology.CoreData框架为我们的数据变更.管理.对象存储.读取和恢复提供了支持.下面我们来尝试创建一个简单的CoreData Project. 操作 1. 打开x-code,为你的proje

iOS数据存储类型 及 堆(heap)和栈(stack)

iOS数据存储类型 及 堆(heap)和栈(stack) 一般认为在c中分为这几个存储区: 1栈 --  由编译器自动分配释放. 2堆 --  一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收. 3全局区(静态存储区)-- 全局变量和静态变量的存储是放在一块区域 ,程序退出后自动释放 .全局区又分为全局初始化区和全局未初始化区.初始化的全局变量和静态变量存放在全局初始化区,未初始化的全局变量和未初始化的静态变量存放在相邻的另一块区域. 4常量区-- 专门放数字/字符常量的地方, 程