本来我想说,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有没有大小端?别纠结,没有!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)