大小端问题

本来我想说,Windows平台一般是小端,Linux一般是大端;

但是,

实际上大小端CPU架构有关,当然和系统也可能有关,可以配置大小端;对于CPU框架,ARM是小端,目前移动端CPU也是小端,stm32这类的嵌入式CPU一般是大端;

我看网上的有些文章是这么描述的:

大端:高位存在低地址,低位存在高地址;
小端:高位存在高地址,低位存在低地址;

刚开始看的时候,还挺认可的,然而仔细想想,不太对劲,描述有问题,文章作者对 ‘位’ 和 ‘字节’ 已经混淆了,应该换成:

大端:高字节存在低地址,低字节存在高地址;
小端:高字节存在高地址,低字节存在低地址;

以下举个例子

// 为了方便看内存,我们定义的值使用十六进制
// 切记0xaabbccdd并非nValue的地址,而是nValue的值,转换成十进制是‭2864434397‬
// 自己用程序员计算器验证下

unsigned int nValue = 0xaabbccdd;

// 此处为了看内存,假定内存地址从右到左 为 低地址到高地址
// 基础知识:
//    int 目前的Windows系统下为 4 字节
//    1 个字节有 8 个位,每个字节最大可表示为 0xFF

                高地址 《《《《《《 低地址
字节编号          3     2     1     0
小端nValue      0xaa   0xbb  0xcc  0xdd
大端nValue      0xdd   0xcc  0xbb  0xaa

利用联合体判断大小端

//定义联合体
union
{
    unsigned int nValue;
    unsigned char aValue;
}Test;

//判断是否属于小端
//原理就是小端的存储方式为低字节存在低地址,联合体的特性是所有字段共用内存块
//即aValue可堪称nValue的低字节
bool IsLittle()
{
    Test t;//初始值为 0x00000000
    t.nValue = 1;//最后值为0x00000001
    return (t.aValue == 1);

    // 若为小端  则内存如下
    //      高地址 《《《《《《《《《《 低地址
    //字节编号     3      2      1      0
    //nValue      0x00   0x00   0x00   0x01
    //aValue                           0x01
    //若为大端  则内存如下
    //      高地址 《《《《《《《《《《 低地址
    //字节编号     3      2      1      0
    //nValue      0x01   0x00   0x00   0x00
    //aValue                           0x00
}

//或者
//直接取低字节进行判断
//不要感到迷糊,首地址是变量占用的内存中最低的地址
bool IsLittle()
{
    unsigned int nValue = 1;
    char* p = (char*)&nValue;
    return (*p) == 1;
}

是不是还有个疑惑,什么样的数据会有大小端问题?字符串会不会有大小端问题?

字符,字符串 都是以字符为单位的,所以读写数据时不会有大小端问题;

数值(short/int/float/double/......),有多个字符组成,在读写时会有大小端;

解释下,字符串可以理解为单字节的字符数组,字符之间没有直接关联,不存在字节序问题;

还有人要问,宽字符串utf-16有没有大小端?别纠结,没有!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值