二进制流:C++中使用 (char *)& 传递int型值

2023-11-04

前言

此前参与罗技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

*/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

二进制流:C++中使用 (char *)& 传递int型值 的相关文章

随机推荐

  • 股票获取最大利润

    1 题目背景 给定一个数组 prices 它的第i个元素prices i 表示一支给定股票第i天的价格 你只能选择某一天买入这只股票 并选择在未来的某一个不同的日子卖出该股票 设计一个算法来计算你所能获取的最大利润 返回你可以从这笔交易中获
  • 操作中 "Chinese_PRC_CI_AS" 和 "Chinese_PRC_CI_AI" 之间的排序规则冲突 的解决办法

    最主要就一句话 在条件中不同排序规则的列后面加上 collate Chinese PRC CI AS 即可解决 有个需求 要求数据库系统自动同步两个不同数据库中的人员信息 首先想到写一个存储过程然后由系统任务来自动处理 尝试性的写了下面的查
  • H5实现高德地图的uni.chooseLocation

    在uniapp中获取当前定位和选择当前位置都是做了兼容 在各个平台都可以使用 这篇文章讲解如何定位当前位置 搜索位置 点击进行定位在H5中实现uni chooseLocation 如下图所示 左侧微信小程序的选择位置 右侧为高德地图在H5中
  • 微信小程序 修改三方组件中的自带样式

    众所周知 微信小程序会引用诸如vant weiui等三方组件 当我们想要对组件自带样式进行修改的时候该怎么做呢 1 在调试器中找到想要修改样式的组件的class类名 在对应的wxss中添加样式 此时样式未生效 2 官方文档中提到可以在ext
  • python写的串口助手并连接腾讯云服务器数据库

    结合上一期的基于pyqt5开发的图书管理系统UI 带登录页面 文章做一个此章节的补充 因为老师说需要结合数据库实现登录系统 于是我就想起了自己在腾讯云上买的一个服务器 因此经过百度查询大量的资料 功夫不负有心人 在这个Pyqt5实现的可视化
  • three.js展示obj模型

    利用three js展示obj模型 环境 必须是在web服务器中 下载objShow js
  • 【UART】Verilog实现UART接收和发送模块

    目录 写在前面 UART 工作原理 UART 接收部分 UART RX 模块图 UART RX 时序图 Verilog 实现 UART RX 模块 UART 发送部分 UART TX 模块图 UART TX 时序图 Verilog 实现 U
  • linux如何同时执行两个命令,如何同时运行两个或者多个终端命令

    选项一 分号 运算符 分号 运算符允许你连续执行多个命令 而不管前面的每个命令是否成功 例如 打开终端窗口 在Ubuntu和Linux Mint中 Ctrl Alt T 然后 在一行中键入以下三个命令 用分号分隔 然后按Enter 这会列出
  • 09、用户、组(一):基本分类

    1 用户类别 管理员 普通用户 系统用户 登录用户 2 用户标识 UserID UID 16bits二进制数字 0 65535 管理员 0 普通用户 1 65635 系统用户 1 499 CentOS6 1 999 CentOS7 登录用户
  • springboot2.0 redis使用lettuce连接包实现分布式锁关键词setnx

    springboot升级到2 0之后 关联的spring data redis默认使用的连接包也从原本的jedis改为了性能更好 且线程安全的使用netty实现的lettuce连接包 鉴于spring data默认只提供了setnx不带过期
  • Unable to negotiate with XXXX port 22: no matching host key type found. Their offer: ssh-rsa,ssh-dss

    问题描述 代码仓库已经添加了ssh公钥之后 克隆代码到本地时就报了这个问题 执行命令 git clone git xxxxxxxxxxxxx git 不能正常clone代码 报错信息如下 Unable to negotiate with x
  • JVM 面试深入理解内存模型和垃圾回收(二)

    JVM 面试深入理解内存模型和垃圾回收 二 文章目录 JVM 面试深入理解内存模型和垃圾回收 二 1 运行时数据区域 1 1 The PC Register 1 2 Java Virtual Machine Stacks 1 2 1 Fra
  • MongoDB Replica Sets + Sharding 实战

    一 Replica Sets 复制集 MongoDB 支持在多个机器中通过异步复制达到故障转移和实现冗余 多机器中同一时刻只有一台是用于写操作 正是由于这个情况 为 MongoDB 提供了数据一致性的保障 担当Primary 角色的机器能把
  • image点击事件

    self headImage userInteractionEnabled YES UITapGestureRecognizer singleTap1 UITapGestureRecognizer alloc initWithTarget
  • 实验八 模板

    一 实验目的和要求 1 能够使用C 模板机制定义重载函数 2 能够实例化及使用模板函数 3 能够实例化和使用模板类 4 应用标准C 模板库 STL 通用算法和函数对象实现查找和排序 二 实验内容 1 分析并调试下列程序 了解函数模板的使用
  • GJM : 【技术干货】给The Lab Renderer for Unity中地形添加阴影

    感谢您的阅读 喜欢的 有用的就请大哥大嫂们高抬贵手 推荐一下 吧 你的精神支持是博主强大的写作动力以及转载收藏动力 欢迎转载 版权声明 本文原创发表于 请点击连接前往 未经作者同意必须保留此段声明 如有问题请联系我 侵立删 谢谢 我的博客
  • R4 STM32高级定时器笔记之PWM互补输出

    STM32高级定时器笔记之PWM互补输出 程序功能 通过两个GPIO 输出相反的PWM信号 带死区时间和刹车控制 PWM为50 要配置几个寄存器 CNT计数器 CCR输出比较寄存器器 输入捕获寄存器 ARR自动重装载寄存器 最大65535
  • 数据结构之Trie树

    目录 前言 什么是Trie树 如何实现一棵Trie树 Trie 树与散列表 红黑树的比较 问题 总结 参考资料 前言 搜索引擎的搜索关键词提示功能 我想你应该不陌生吧 为了方便快速输入 当你在搜索引擎的搜索框中 输入要搜索的文字的某一部分的
  • C语言共用体-union的用法

    定义格式 union 共用体名 成员列表 共用体特点 1 占用的内存等于最长的成员占用的内存 2 共用体使用了内存覆盖技术 同一时刻只能保存一个成员的值 如果对新的成员赋值 就会把原来成员的值覆盖掉 会影响其余所有成员 实例说明 typed
  • 二进制流:C++中使用 (char *)& 传递int型值

    文章目录 前言 一 利用二进制流传递整形数组值 1 1 整形数组 1 2 二进制流 1 2 1 那如何将整形数值依次按一个字节存放入二进制流中呢 1 2 2 如何重构回整形数值 二 结构体数组赋值 前言 此前参与罗技G29方向盘远程遥控au