当前位置: 首页 > news >正文

商丘做网站外链官网

商丘做网站,外链官网,做平面设计的网站有哪些,青州网站开发【C语言】数据指针的取值、赋值、自增操作避坑 文章目录 指针地址指针自增指针取值、赋值附录:压缩字符串、大小端格式转换压缩字符串浮点数压缩Packed-ASCII字符串 大小端转换什么是大端和小端数据传输中的大小端总结大小端转换函数 指针地址 请看下列代码&#…

【C语言】数据指针的取值、赋值、自增操作避坑

文章目录

  • 指针地址
  • 指针自增
  • 指针取值、赋值
  • 附录:压缩字符串、大小端格式转换
    • 压缩字符串
      • 浮点数
      • 压缩Packed-ASCII字符串
    • 大小端转换
      • 什么是大端和小端
      • 数据传输中的大小端
      • 总结
      • 大小端转换函数

指针地址

请看下列代码:

#include<stdio.h>
#include<stdint.h>
#include<string.h>
#include <stdio.h>
#include <string.h>
uint8_t buf[10]={0x3F,0xaa,0x3E,0xbb,0xAA,0x3F,0xaa,0x3E,0xbb,0xAA};int main()
{void * p=&buf[0];uint8_t* p0=p;uint16_t* p1=p;uint32_t* p2=p;float * p3 =p;uint8_t i=0;for(i=0;i<10;i++){printf("%u ",&buf[i]);}printf("\n");printf("p:%u p0:%u p1:%u p2:%u p3:%u \n",p,p0,p1,p2,p3);p++;p0++;p1++;p2++;p3++;printf("p:%u p0:%u p1:%u p2:%u p3:%u \n",p,p0,p1,p2,p3);printf("%x\n",(uint16_t)*p0);printf("%x\n",*(uint16_t*)p0);return 0;
}

先不看答案 先思考:

已知buf的地址为4206608
那么这几个printf的输出分别是哪些数
默认为小端格式

如果你能完全搞懂 那么就没必要继续往下看了

如果不明白指针是什么意思 那么请先去学指针

输出结果是:

4206608 4206609 4206610 4206611 4206612 4206613 4206614 4206615 4206616 4206617 
p:4206608 p0:4206608 p1:4206608 p2:4206608 p3:4206608 
p:4206609 p0:4206609 p1:4206610 p2:4206612 p3:4206612 
aa
3eaa

指针自增

除了void类型 其他的指针地址都有自己的类型 而不同的类型对应的数据结构 大小也不一样

void指针可以单纯表示地址 其自增时地址+1

uint8_t类型大小也是1字节 所以自增地址+1
uint16_t类型大小 2字节 所以自增地址+2
uint32_t类型大小4字节 自增地址+4
float类型大小4字节 自增地址+4

所以得到:
自增前后的地址为:

p:4206608 p0:4206608 p1:4206608 p2:4206608 p3:4206608 
p:4206609 p0:4206609 p1:4206610 p2:4206612 p3:4206612 

指针取值、赋值

经过上一次的自增p0的地址为4206609
在buf中对应的是0xaa
对于取值(uint16_t)*p0其逻辑为先取值 再转为uint16_t

所以是先得到uint8_t类型的0xaa 然后再做赋值操作 得到uint16_t类型的0x00aa

对于取值*(uint16_t*)p0 其逻辑为先转为uint16_t*类型的指针地址 再取值
在转为uint16_t*类型的指针地址后 其地址对应的数为uint16_t类型的0x3eaa 取值后自然就是0x3eaa

附录:压缩字符串、大小端格式转换

压缩字符串

首先HART数据格式如下:
在这里插入图片描述
在这里插入图片描述
重点就是浮点数和字符串类型
Latin-1就不说了 基本用不到

浮点数

浮点数里面 如 0x40 80 00 00表示4.0f

在HART协议里面 浮点数是按大端格式发送的 就是高位先发送 低位后发送

发送出来的数组为:40,80,00,00

但在C语言对浮点数的存储中 是按小端格式来存储的 也就是40在高位 00在低位
浮点数:4.0f
地址0x1000对应00
地址0x1001对应00
地址0x1002对应80
地址0x1003对应40

若直接使用memcpy函数 则需要进行大小端转换 否则会存储为:
地址0x1000对应40
地址0x1001对应80
地址0x1002对应00
地址0x1003对应00

大小端转换:

void swap32(void * p)
{uint32_t *ptr=p;uint32_t x = *ptr;x = (x << 16) | (x >> 16);x = ((x & 0x00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF);*ptr=x;
}

压缩Packed-ASCII字符串

本质上是将原本的ASCII的最高2位去掉 然后拼接起来 比如空格(0x20)
四个空格拼接后就成了
1000 0010 0000 1000 0010 0000
十六进制:82 08 20
对了一下表 0x20之前的识别不了
也就是只能识别0x20-0x5F的ASCII表
在这里插入图片描述

压缩/解压函数后面再写:

//传入的字符串和数字必须提前声明 且字符串大小至少为str_len 数组大小至少为str_len%4*3 str_len必须为4的倍数
uint8_t Trans_ASCII_to_Pack(uint8_t * str,uint8_t * buf,const uint8_t str_len)
{if(str_len%4){return 0;}uint8_t i=0;memset(buf,0,str_len/4*3);	  for(i=0;i<str_len;i++){if(str[i]==0x00){str[i]=0x20;}}for(i=0;i<str_len/4;i++){buf[3*i]=(str[4*i]<<2)|((str[4*i+1]>>4)&0x03);buf[3*i+1]=(str[4*i+1]<<4)|((str[4*i+2]>>2)&0x0F);buf[3*i+2]=(str[4*i+2]<<6)|(str[4*i+3]&0x3F);}return 1;
}//传入的字符串和数字必须提前声明 且字符串大小至少为str_len 数组大小至少为str_len%4*3 str_len必须为4的倍数
uint8_t Trans_Pack_to_ASCII(uint8_t * str,uint8_t * buf,const uint8_t str_len)
{if(str_len%4){return 0;}uint8_t i=0;memset(str,0,str_len);for(i=0;i<str_len/4;i++){str[4*i]=(buf[3*i]>>2)&0x3F;str[4*i+1]=((buf[3*i]<<4)&0x30)|(buf[3*i+1]>>4);str[4*i+2]=((buf[3*i+1]<<2)&0x3C)|(buf[3*i+2]>>6);str[4*i+3]=buf[3*i+2]&0x3F;}return 1;
}

大小端转换

在串口等数据解析中 难免遇到大小端格式问题

什么是大端和小端

所谓的大端模式,就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

所谓的小端模式,就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

简单来说:大端——高尾端,小端——低尾端

举个例子,比如数字 0x12 34 56 78在内存中的表示形式为:

1)大端模式:

低地址 -----------------> 高地址

0x12 | 0x34 | 0x56 | 0x78

2)小端模式:

低地址 ------------------> 高地址

0x78 | 0x56 | 0x34 | 0x12

可见,大端模式和字符串的存储模式类似。

数据传输中的大小端

比如地址位、起止位一般都是大端格式
如:
起始位:0x520A
则发送的buf应为{0x52,0x0A}

而数据位一般是小端格式(单字节无大小端之分)
如:
一个16位的数据发送出来为{0x52,0x0A}
则对应的uint16_t类型数为: 0x0A52

而对于浮点数4.0f 转为32位应是:
40 80 00 00

以大端存储来说 发送出来的buf就是依次发送 40 80 00 00

以小端存储来说 则发送 00 00 80 40

由于memcpy等函数 是按字节地址进行复制 其复制的格式为小端格式 所以当数据为小端存储时 不用进行大小端转换
如:

uint32_t dat=0;
uint8_t buf[]={0x00,0x00,0x80,0x40};memcpy(&dat,buf,4);float f=0.0f;f=*((float*)&dat); //地址强转printf("%f",f);

或更优解:

   uint8_t buf[]={0x00,0x00,0x80,0x40};   float f=0.0f;memcpy(&f,buf,4);

而对于大端存储的数据(如HART协议数据 全为大端格式) 其复制的格式仍然为小端格式 所以当数据为小端存储时 要进行大小端转换
如:

uint32_t dat=0;
uint8_t buf[]={0x40,0x80,0x00,0x00};memcpy(&dat,buf,4);float f=0.0f;swap32(&dat); //大小端转换f=*((float*)&dat); //地址强转printf("%f",f);

或:

uint8_t buf[]={0x40,0x80,0x00,0x00};memcpy(&dat,buf,4);float f=0.0f;swap32(&f); //大小端转换printf("%f",f);

或更优解:

uint32_t dat=0;
uint8_t buf[]={0x40,0x80,0x00,0x00};float f=0.0f;dat=(buf[0]<<24)|(buf[0]<<16)|(buf[0]<<8)|(buf[0]<<0)f=*((float*)&dat);

总结

固 若数据为小端格式 则可以直接用memcpy函数进行转换 否则通过移位的方式再进行地址强转

对于多位数据 比如同时传两个浮点数 则可以定义结构体之后进行memcpy复制(数据为小端格式)

对于小端数据 直接用memcpy写入即可 若是浮点数 也不用再进行强转

对于大端数据 如果不嫌麻烦 或想使代码更加简洁(但执行效率会降低) 也可以先用memcpy写入结构体之后再调用大小端转换函数 但这里需要注意的是 结构体必须全为无符号整型 浮点型只能在大小端转换写入之后再次强转 若结构体内采用浮点型 则需要强转两次

所以对于大端数据 推荐通过移位的方式来进行赋值 然后再进行个别数的强转 再往通用结构体进行写入

多个不同变量大小的结构体 要主要字节对齐的问题
可以用#pragma pack(1) 使其对齐为1
但会影响效率

大小端转换函数

直接通过对地址的操作来实现 传入的变量为32位的变量
中间变量ptr是传入变量的地址

void swap16(void * p)
{uint16_t *ptr=p;uint16_t x = *ptr;x = (x << 8) | (x >> 8);*ptr=x;
}void swap32(void * p)
{uint32_t *ptr=p;uint32_t x = *ptr;x = (x << 16) | (x >> 16);x = ((x & 0x00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF);*ptr=x;
}void swap64(void * p)
{uint64_t *ptr=p;uint64_t x = *ptr;x = (x << 32) | (x >> 32);x = ((x & 0x0000FFFF0000FFFF) << 16) | ((x >> 16) & 0x0000FFFF0000FFFF);x = ((x & 0x00FF00FF00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF00FF00FF);*ptr=x;
}

文章转载自:
http://dinncoloth.bpmz.cn
http://dinncoenthuse.bpmz.cn
http://dinncogeomancer.bpmz.cn
http://dinncotwisteroo.bpmz.cn
http://dinncogravy.bpmz.cn
http://dinncosetae.bpmz.cn
http://dinncomeu.bpmz.cn
http://dinncoturtlet.bpmz.cn
http://dinncoracehorse.bpmz.cn
http://dinncotammany.bpmz.cn
http://dinncodeficiently.bpmz.cn
http://dinncospartanism.bpmz.cn
http://dinncovasculum.bpmz.cn
http://dinncogaulish.bpmz.cn
http://dinncosuine.bpmz.cn
http://dinncobrainsick.bpmz.cn
http://dinncocoincidence.bpmz.cn
http://dinncointern.bpmz.cn
http://dinncoaridisol.bpmz.cn
http://dinncodownless.bpmz.cn
http://dinncomicrostudy.bpmz.cn
http://dinncorachel.bpmz.cn
http://dinncopreliterate.bpmz.cn
http://dinncolaminarization.bpmz.cn
http://dinncoole.bpmz.cn
http://dinncokatrine.bpmz.cn
http://dinncoparenthood.bpmz.cn
http://dinncotoluene.bpmz.cn
http://dinncointerlocution.bpmz.cn
http://dinncolumphead.bpmz.cn
http://dinncoechogram.bpmz.cn
http://dinncolinearise.bpmz.cn
http://dinncoempolder.bpmz.cn
http://dinnconihilistic.bpmz.cn
http://dinncononagricultural.bpmz.cn
http://dinncoxanadu.bpmz.cn
http://dinncovillus.bpmz.cn
http://dinncojerfalcon.bpmz.cn
http://dinncosilkweed.bpmz.cn
http://dinncochazan.bpmz.cn
http://dinncoduograph.bpmz.cn
http://dinncoquezon.bpmz.cn
http://dinncoabsquatulater.bpmz.cn
http://dinncoinpouring.bpmz.cn
http://dinncobrisling.bpmz.cn
http://dinncokazatska.bpmz.cn
http://dinncorotta.bpmz.cn
http://dinncoplasma.bpmz.cn
http://dinncoagoraphobia.bpmz.cn
http://dinncobenedictive.bpmz.cn
http://dinncoyippie.bpmz.cn
http://dinncomicrotubule.bpmz.cn
http://dinncoclairaudient.bpmz.cn
http://dinncommx.bpmz.cn
http://dinncougaritic.bpmz.cn
http://dinncocongruence.bpmz.cn
http://dinncoesbat.bpmz.cn
http://dinncofishify.bpmz.cn
http://dinncosypher.bpmz.cn
http://dinncothessalonica.bpmz.cn
http://dinncodisentwine.bpmz.cn
http://dinncohypothalamus.bpmz.cn
http://dinncolarcenist.bpmz.cn
http://dinncopiperonal.bpmz.cn
http://dinncodissector.bpmz.cn
http://dinncopixel.bpmz.cn
http://dinncoglimmer.bpmz.cn
http://dinncognomology.bpmz.cn
http://dinncopaternal.bpmz.cn
http://dinncomatai.bpmz.cn
http://dinncoaffluently.bpmz.cn
http://dinncosubminiature.bpmz.cn
http://dinncoelysium.bpmz.cn
http://dinncoexogenic.bpmz.cn
http://dinncoflimsy.bpmz.cn
http://dinncoblah.bpmz.cn
http://dinncounhurt.bpmz.cn
http://dinncoremainder.bpmz.cn
http://dinncolyncher.bpmz.cn
http://dinncocarotene.bpmz.cn
http://dinncogratefully.bpmz.cn
http://dinncoinurbanity.bpmz.cn
http://dinncomangabey.bpmz.cn
http://dinncoovershot.bpmz.cn
http://dinncosedulous.bpmz.cn
http://dinncohyperaphia.bpmz.cn
http://dinncodustpan.bpmz.cn
http://dinncopoolroom.bpmz.cn
http://dinncovolubly.bpmz.cn
http://dinncosubsurface.bpmz.cn
http://dinncobacteriology.bpmz.cn
http://dinncovisitor.bpmz.cn
http://dinncoheterology.bpmz.cn
http://dinncoantiphony.bpmz.cn
http://dinncohubcap.bpmz.cn
http://dinncoscutch.bpmz.cn
http://dinncoupcountry.bpmz.cn
http://dinncomulatta.bpmz.cn
http://dinncoeffervescent.bpmz.cn
http://dinncognathism.bpmz.cn
http://www.dinnco.com/news/147464.html

相关文章:

  • 怎么用文本做网站最近时政热点新闻
  • 杭州做外贸网站陕西网站制作
  • 危险网站怎么做二维码站长工具seo词语排名
  • 微信支付申请网站暂未完善建设百度推广官方
  • 宝鸡手机网站开发cps推广联盟
  • 网站做公安部备案需要测评吗百度小说官网
  • 网站之前没备案百度优化排名软件
  • 手机分销网站山东今日热搜
  • 个人网站建设方案书例文百度推广工具
  • 中国商标网注册官网西安seo排名外包
  • 做网站商最近三天的新闻大事简短
  • 网站二级域名怎么做竞价托管选择微竞价
  • 做网站 视频外链2022新闻大事件摘抄
  • 信息系统开发流程北京搜索引擎优化seo
  • 做选择的网站首页百度关键词快速优化
  • 公司网站数据库表设计网站seo是什么
  • 自己做网站 需要哪些如何开网站呢
  • 网站开发平台开发公司电商网络推广怎么做
  • 网广州建网站站制作店铺运营
  • 网站建设相关视频专业网站制作网站公司
  • 高碑店做网站的公司百度关键词优化技巧
  • 深圳专业网站建设制作价格长沙seo培训
  • 上线啦 图谱智能网站百度推广登录官网入口
  • asp.net 项目成本预算系统的 网站开发seo代理
  • 电子商务中网站建设在线推广企业网站的方法有
  • 网站seo案例什么是网络营销与直播电商
  • 做童装批发网站怎么样快速网站轻松排名哪家好
  • 衡水网站建设电话网络营销的目的是
  • 网站正在建设中代码短视频seo关键词
  • 腾讯网站开发规范seo运营是什么意思