计算机在存储数据的时候,是以字节(byte)为基本单位来存储的,因此存储单字节类型的数据(比如char)不存在字节序的问题。但存储多字节的数据的时候(比方说4字节的int变量),就涉及到了以一个什么样的顺序来存储。下面举例来说明大端和小端的存储方式。
定义变量 unsigned long long a=0x1122334455667788
变量a是一个64位的无符号整数,共需要8个字节来存储,那么在两种模式下是如何存储的呢?
||--1--||--2--||--3--||--4--||--5--||--6--||--7--||--8--|| 地址
|| 11 || 22 || 33 || 44 || 55 || 66 || 77 || 88 || 大端模式
|| 88 || 77 || 66 || 55 || 44 || 33 || 22 || 11 || 小端模式
从中很容易可以看出各自的存储特点。
大端:高地址存低字节,低地址存高字节
小端:低地址存低字节,高地址存高字节
小端模式:强制类型转换数据不需要调整字节内容。
大端模式:符号位判断固定为第一个字节,容易判断正负,便于人类阅读。
判断大小端
#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();
}
大小端转换
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))
Qt中大端小端的转换
Qt中<QtEndian>包含了大端小端转换的几个函数
T qFromBigEndian(const uchar * src)
T qFromBigEndian(T src)
T qFromLittleEndian(const uchar * src)
T qFromLittleEndian(T src)
void qToBigEndian(T src, uchar * dest)
T qToBigEndian(T src)
void qToLittleEndian(T src, uchar * dest)
T qToLittleEndian(T src)
下面对这个几个函数进行简单的说明。
union{
int a;
char b[4];
}test1,test2;
test1.a=0x61626364;
test2.a=qFromBigEndian(test1.a);
qDebug()<<test1.b[0]<<test1.b[1]<<test1.b[2]<<test1.b[3];
qDebug()<<test2.b[0]<<test2.b[1]<<test2.b[2]<<test2.b[3];
对于qFromBigEndian()函数,它会判断执行程序的主机的字节序,如果是大端模式的计算机,那么只是读取数据,不进行转换,如果是小端模式的计算机,那么则进行转换。
因此我在本机(小端模式)上的的执行结果是:
d c b a
a b c d
可以看出,它将数据进行了转换。
对于qFromLittleEndian()函数,和前者类似。对于大端模式的计算机进行转换,对于小端模式的计算机只是读取数据。
union{
int a;
char b[4];
}test1,test2;
test1.a=0x61626364;
test2.a=qFromLittleEndian(test1.a);
qToBigEndian(test1.a,(uchar*)test2.b);
qDebug()<<test1.b[0]<<test1.b[1]<<test1.b[2]<<test1.b[3];
qDebug()<<test2.b[0]<<test2.b[1]<<test2.b[2]<<test2.b[3];
对于qToBigEndian()函数,也有着上面的规则,对于小端模式的计算机进行转换,对于大端模式的计算机只进行读取。
因此,本机(小端模式)的执行结果是:
d c b a
a b c d
对于qToLittleEndian()函数,只对大端模式的计算机进行转换。文章来源:https://www.toymoban.com/news/detail-425077.html
需要注意的是,Qt中的模板T只针对有符号和无符号的整型,对于浮点型(一般也不会用到),需要进行强制类型转换。
文章来源地址https://www.toymoban.com/news/detail-425077.html
到了这里,关于大端小端及其转换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!