大小端与结构体释疑

  • 本人在做项目过程中需要在ARM对从FPGA读取到的数据进行处理,在实际过程中产生了一些问题,在思考了后记录在此。
1 大小端模式
  • 大小端指数据在内存中的存储方式。小端指数据的高字节保存在内存的高地址处,低字节保存在内存的低地址处。大端模式则正好相反。ARM和x86的CPU一般情况下都为小端模式。
  • 对于值unsigned int value = 0x12345678,在内存中的存储方式如下。
内存地址小端模式存放内容大端模式存放内容
0x000040000x780x12
0x000040010x560x34
0x000040020x340x56
0x000040030x120x78
2 栈上的数据存储
  • 局部变量在栈上存储,而栈由高地址向低地址方向增长。因此我们创建三个局部变量时,内存区如下图所示。我们由下图可以看到,在x86上,低字节存储在低地址,而栈由高地址向下增长。
	unsigned int a = 0x12345678;
	unsigned short b = 0x1234;
	unsigned char c  = 0x12;

在这里插入图片描述

  • 结构体在栈上的存储时,在结构体中靠前面的成员存储在低地址处。如下面这个结构体,inta成员存储在低地址处,charc成员存储在高地址处。
	#pragma pack(1)
	typedef struct _ppp
	{
	    unsigned int inta;
	    unsigned short shortb;
	    unsigned char charc;
	}structp;
	#pragma pack()
	
	struct structp ppppp;
	ppppp.inta = a;
	ppppp.shortb = b;
	ppppp.charc = c;
  • 我们可以看到,结构体变量ppppp存储在0x0065FE4A地址处,inta成员存储在低地址处,charc成员存储在高地址处。
    在这里插入图片描述
3 Qt中的QByteArray与结构体转换的问题
  • 在Qt中,我经常将变量或结构体转换成QByteArray类型,然后进行传递。
	QByteArray ba;
    unsigned int a = 0x12345678;
    unsigned short b = 0x1234;
    unsigned char c  = 0x12;
    ba.append(QByteArray((const char*)&b, sizeof(unsigned short)));
    ba.append(QByteArray((const char*)&c, sizeof(unsigned char)));
    ba.append(QByteArray((const char*)&a, sizeof(unsigned int)));
  • 变量ba在内存中的布局如下图所示,因此我可以用下面这种方式拆分QByteArray类型。
    在这里插入图片描述
	QByteArray bab = ba.mid(0, 2);
	QByteArray bac = ba.mid(2, 1);
	QByteArrat baa = ba.mid(3, 4);
	unsigned short* pbab = (unsigned short*)bab.data();		//0x1234
	unsigned char* pbac = (unsigned char*)bac.data();		//0x12
	unsigned int* pbaa = (unsigned int*)baa.data();			//0x12345678
  • 对于结构体看似这种方法也是正确的。变量structpp在内存中存储在0x0065FE39处,变量ba存储在0x00977280处。
	QByteArray ba;
    struct structp structpp;
    structpp.inta = 0x12345678;
    structpp.shortb = 0x1234;
    structpp.charc = 0x12;
    ba.append((const char*)&structpp, sizeof(structp));
    structp* pstructp = (structp*)ba.data();

在这里插入图片描述
在这里插入图片描述

  • 但如果
4 Qt中大小端转换函数问题
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值