大家好,欢迎来到IT知识分享网。
1. 端模式起源
端模式(Endian)起源于《格列佛游记》,书中根据鸡蛋敲开的方式不同将所有人分为2类,从圆头开始敲的人被归为Big Endian,从尖头开始敲的被归为 Little Endian。小人国的内战就是源于吃鸡蛋是是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开。
2. 大小端定义
大端:高地址存低字节,低地址存高字节
小端:低地址存低字节,高地址存高字节
人类读写数据习惯是大端字节序,大数据先读,小数据后读。所以小端是反人类的方式
3. 为什么有大小端
计算机业界的Endian表示数据在存储器中的存放顺序。
我们的编程语言定义了 char,short,int等各种类型,每一种类型占用的字节大小为1,2,4等。
而我们的处理器的寄存器的宽度大于一个字节,那么必然存在将多字节类型数据存入寄存器的顺序问题。
常见的处理器大小端架构:
| 处理器 | 端模式 |
|---|---|
| IntelX86 | Little-Endian |
| Power-PC | Big-Endian |
| IBM | Big-Endian |
| ARM | 默认 Little-Endian |
| STM32 | Little-Endian |
网络通讯协议采用的是Big-Endian
4. 谁更好?
小端模式:强制类型转换数据不需要调整字节内容。
大端模式:符号位判断固定为第一个字节,容易判断正负,便于人类阅读。
总结:大小端没有谁更优更劣,各种优点就是对方劣势。
5. 如何代码判断大小端
#include <QCoreApplication> #include <QDebug> bool isLittleEndian(){ unsigned short a = 0x1218; if( (*(char*)&a) == 0x18){ return true; }else{ return false; } } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); if(isLittleEndian()){ qDebug() << "LitteEndian"; }else{ qDebug() << "BigEndian"; } return a.exec(); }
6. 大小端转换代码
6.1. 使用宏转换
typedef unsigned short int uint16; typedef unsigned long int uint32; #define BigLittleSwap16(A) ((((uint16)(A) & 0xff00) >> 8) | \ (((uint16)(A) & 0x00ff) << 8)) #define BigLittleSwap32(A) ((((uint32)(A) & 0xff000000) >> 24) | \ (((uint32)(A) & 0x00ff0000) >> 8) | \ (((uint32)(A) & 0x0000ff00) << 8) | \ (((uint32)(A) & 0x000000ff) << 24))
6.2. 使用函数转换
大端转小端
template<class T> T ConvertBigEndToLittleEnd(T big_end_value) { T little_end_value(0); int num = sizeof(T); for (int i = 0; i < num; ++i) { little_end_value = little_end_value << 8; little_end_value |= (big_end_value & 0xFF); big_end_value = big_end_value >> 8; } return little_end_value; }
参考文献
一文彻底弄懂大端与小端_kingforyang的博客-CSDN博客_大端小端
C/C++ 大小端转换_HHT0506的博客-CSDN博客_c++ 大小端转换
大小端及转换(C++)_休息一下接着来的博客-CSDN博客_大小端转换
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/112366.html

