文章目录
前言
此前参与罗技G29方向盘远程遥控autolabor小车的小项目,树莓派操控小车为服务端,采集方向盘数据部分为客户端,二者间进行P2P通信,要将方向盘转向、油门、挡位数据发送给树莓派,需要使用到二进制流传递法,本文介绍通过二进制流传递整形数组的原理。
一、利用二进制流传递整形数组值
1.1 整形数组
如int num[3]={1,2,3};数组num中存放着三个数值1,2,3。由于在64位操作系统下int为4个字节,则每个数值的存放地址间隔为4个字节。
#include<iostream>
using namespace std;
int main(int argc,char* argv[])
{
int num[3] = {
1, 2, 3};
for (int i = 0; i < 3;++i)
cout<<"num["<<i<<"]的地址:"
<< &num[i] <<" "
<<"num["<<i<<"]的值:"
<<num[i]<< endl;
return 0;
}
/*---------------运行结果------------------
num[0]的地址:010FF878 num[0]的值:1
num[1]的地址:010FF87C num[1]的值:2
num[2]的地址:010FF880 num[2]的值:3
*/
我们可以查看内存空间地址中是如何存放整形十进制数字1,2,3的,仅看num[0]的地址内存放着01 00 00 00,因为num[0]属于int型,为4个字节,1 Byte=8 bit,其中01为一个字节,8位。所以在int型下,数组索引每移位一次,则地址移动4个字节输出。
0x010FF878 01 00 00 00
0x010FF87C 02 00 00 00
0x010FF880 03 00 00 00
1.2 二进制流
1.2.1 那如何将整形数值依次按一个字节存放入二进制流中呢?
引入
char *buff=(char *)&num[0]
,该语句与(char *)num
等价,因为数组名等价于数组首地址。num是int型数组,数组num中的每个值按4个字节存放在内存地址中,char是字符型,在64位操作系统下为一个字节,(char *)& 的意思便是将num从int型指针转变成字符型指针,地址依次移位一个字节存入,这样便能将整形数字1,按照01 00 00 00顺序存放到char *buff中。
此时buff中存放的二进制流如下所示:
buff[0]=01 buff[1]=00 buff[2]=00 buff[3]=00
buff[4]=02 buff[5]=00 buff[6]=00 buff[7]=00
buff[8]=03 buff[9]=00 buff[10]=00 buff[11]=00
1.2.2 如何重构回整形数值?
之后再依次按4个字节重构成整形数输出,利用(int *)buff
将字符型指针buff转换成整形指针,这样每次移位便是4个字节。
使用
(int*)buff
,将buff[0]到buff[3]合并
使用(int*)(buff+4)
,将buff[4]到buff[7]合并
使用(int*)(buff+8)
,将buff[8]到buff[11]合并
#include<iostream>
using namespace std;
int main(int argc, char* argv[])
{
int num[3] = {
1, 2, 3 };
char* buff;
buff = (char*)num;
for (int i = 0; i < 3;++i)
{
cout << "num[" << i << "]的地址:"
<< &num[i] << " "
<< "num[" << i << "]的值:"
<< num[i] << endl;
cout << "二进制流合并重构:"
<< (int*)(buff + 4 * i) << " 值为:"
<< *((int*)(buff + 4 * i)) << endl;
}
return 0;
}
/*---------------运行结果------------------
num[0]的地址:00F3FCB8 num[0]的值:1
二进制流合并重构:00F3FCB8 值为:1
num[1]的地址:00F3FCBC num[1]的值:2
二进制流合并重构:00F3FCBC 值为:2
num[2]的地址:00F3FCC0 num[2]的值:3
二进制流合并重构:00F3FCC0 值为:3
*/
二、结构体数组赋值
#include<iostream>
using namespace std;
typedef struct birthday
{
int year;
int month;
int day;
} birthday;
int main(int argc,char* argv[])
{
int person_num;
cout << "请输入人数:";
cin >> person_num;
int *num = new int[3*person_num];
cout << "请依次输入" << 3 * person_num << "个整数:" ;
for (int i = 0; i < 3 * person_num; ++i)
cin >> num[i];
char *array = (char *)num;
birthday *birth = new birthday[person_num];
int j=0;
for (int i=0; i < person_num ; ++i)
{
birth[i].year = *((int *)(array + 4*j));
birth[i].month= *((int *)(array + 4*(j+1)));
birth[i].day= *((int *)(array + 4*(j+2)));
j=j + 3;
switch(i)
{
case 0:
cout << "CJX的生日:";
break;
case 1:
cout << "WJ的生日:";
break;
}
cout << birth[i].year << "-"
<< birth[i].month << "-"
<< birth[i].day << endl;
}
delete[] birth;
birth = NULL;
delete[] num;
num = NULL;
return 0;
}
/*---------------运行结果------------------
请输入人数:2
请依次输入6个整数:1999 10 5 1996 8 31
CJX的生日:1999-10-5
WJ的生日:1996-8-31
*/