打印
[C语言]

请教前辈,关于指针,,结构体指针内的指针怎么实现?

[复制链接]
637|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Light_David|  楼主 | 2021-1-5 12:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
搞CH438(8串口芯片),我定义了一个用于存放数据的结构体数组CH438Buf[],和一个用于访问结构体数组的指针*Pbuf,成员是[数据字节数]和[数据缓冲区]
struct
{unsigned char length;
unsigned char Payload[128];
}CH438Buf[8],*Pbuf;

现在使用指针访问结构体数组内的Payload数据,只能用pBuf->Payload[]的形式,这等同数组方式,会导致访问效率问题吧(计算数组下标),如何在结构体指针内使用指针能和普通指针一样可以用++或者--操作呢.,

我试过定义一个这样的结构指针
typedef struct //Message
{unsigned char cu;
unsigned char *Payload;
}*Data_Buff;

static Data_Buff pBuf; //声明指针

pBuf=(void)&CH438Buf[1]//指针初始化,结构数组(第二组)地址赋值给指针

按如上定义后,用*pBuf->Payload++可以编译通过,这会是什么鬼效果。

使用特权

评论回复

相关帖子

沙发
ayb_ice| | 2021-1-5 13:35 | 只看该作者
直接用普通指针
u8* pDst = &pBuf->Payload[0];

使用特权

评论回复
板凳
Light_David|  楼主 | 2021-1-5 14:17 | 只看该作者
ayb_ice 发表于 2021-1-5 13:35
直接用普通指针
u8* pDst = &pBuf->Payload[0];

嗯,用一个普通指针,这样OK,目前就是这样。
我试过我的第二种方法,得不到预期结果,乱七八糟的。没详细研究了
我测试了用数组与指针发方式搬运128字节,在同样环境下,指针用时544uS,数组索引的方式用时822uS

使用特权

评论回复
地板
ayb_ice| | 2021-1-5 14:34 | 只看该作者
Light_David 发表于 2021-1-5 14:17
嗯,用一个普通指针,这样OK,目前就是这样。
我试过我的第二种方法,得不到预期结果,乱七八糟的。没详 ...

这点时间一般无所谓的,多注重可读,可维护性,在需要性能时有方法优化就可以了

使用特权

评论回复
5
Light_David|  楼主 | 2021-1-5 14:37 | 只看该作者
ayb_ice 发表于 2021-1-5 13:35
直接用普通指针
u8* pDst = &pBuf->Payload[0];

结构指针内的指针成员我理解不了。
我理解的,指针本质上也就是一个数据,只是它存储的内容是地址,不同数据类型的指针本质没有差异,仅仅是告诉编译器它做运算的偏移量。
结构指针应该也好理解,结构内的成员就告诉了它固有偏移(就如STM32库大量使用结构指针)
但是结构指针内的指针,有点懵,感觉嵌套了,不知道为什么可以定义并使用。
把一个结构体指针赋值以后,那么结构体指针内的指针会被赋到什么值呢,它会指向哪呢

使用特权

评论回复
评论
linguanghua 2021-1-5 15:48 回复TA
因为指针本身是固定大小的,可以嵌套使用。可以是自己指向自己的指针,只是开辟一个固定的内存而已。 
6
diweo| | 2021-1-5 16:13 | 只看该作者
第一个结构体1在内存中就是先1个字节的length,然后128字节的Payload。
现在让另外一个结构体2的指针指向这块内存区域,其实就是按照结构体2的定义来解析这些数据。
现在结构体2的第一个元素类型是unsigned char,它占中一个字节,那么它其实就对应到结构体1的length。
结构体2的第二个元素类型是unsigned char *,它占用4个字节(假设是32位机器),那么它对应的就是结构体1中Payload的前4个字节。假设初始状态下,这4个字节都是0x00,那么第一次执行*pBuf->Payload++,就表示从0x00000000里读出数据,然后Payload[0]会变成1,第二次执行*pBuf->Payload++,就表示从0x00000001里读数据,然后Payload[0]变成2,以此类推。

使用特权

评论回复
7
diweo| | 2021-1-5 16:15 | 只看该作者
第二个结构体可能还要考虑对齐的问题,会稍微更复杂一点。

使用特权

评论回复
8
雪山飞狐D| | 2021-1-5 16:31 | 只看该作者
本帖最后由 雪山飞狐D 于 2021-1-5 16:40 编辑
Light_David 发表于 2021-1-5 14:37
结构指针内的指针成员我理解不了。
我理解的,指针本质上也就是一个数据,只是它存储的内容是地址,不同 ...

你每定义一个指针变量,就会分配一个内存块A,这个内存块里面存的是地址,其实还是一组数而已,由编译器负责识别转译汇编,结构体B是一组内存块组的打包,里面的其中一个内存块A存了地址,也就是结构体内有一个指针A,而结构体的指针,又另一外分配一个内存块C,这个内存块里面存了结构体B第一个内存块的地址
    C->A 操作就会把CPU内部的硬件PC跳转到C存的地址,这时候编译器根据偏移就能找到A储存的数据,也就是一个地址  C - >A  相当于(*C).A 的简化符号,你没有*A,就是告诉编译器,直接提取A储存的数值,而A之前定义为指针,编译器就会知道A的数值是地址,*A还可以跳转到另外一个地方,也就是你说嵌套

使用特权

评论回复
9
Light_David|  楼主 | 2021-1-5 17:01 | 只看该作者
diweo 发表于 2021-1-5 16:13
第一个结构体1在内存中就是先1个字节的length,然后128字节的Payload。
现在让另外一个结构体2的指针指向这 ...

您这么一说,的确跟我测试看到的“莫名其妙”现象对上了。 结构体指针内的指针成员在这里仅有一个‘占位’功能了,我通过 *pBuf->Payload++ 赋值, 我直接用ch438.Payload[]输出的确是0,2,4,6,这样的值,看样子是把指向的成员空间当数据块用来存储指针值了。 这和我的原本想要的完全不一致,看样子我就定义一个普通指针来处理好了。
非常感谢解惑。

使用特权

评论回复
10
Light_David|  楼主 | 2021-1-5 17:08 | 只看该作者
雪山飞狐D 发表于 2021-1-5 16:31
你每定义一个指针变量,就会分配一个内存块A,这个内存块里面存的是地址,其实还是一组数而已,由编译器负 ...

大概已经明白,我回复diweo的内容描述了我的理解,对这个指针赋值时,内存块被赋予地址值了。那么对于这样的定义,用(*C).*A (我不确定能不能这样写)也提取不到意愿的值了,因为我赋值结构体指针时,这个指针所用的地址与我的数据重叠了(类似于联合类型)数据已经被破坏掉了,没有意义了。

使用特权

评论回复
11
雪山飞狐D| | 2021-1-5 17:21 | 只看该作者
Light_David 发表于 2021-1-5 17:08
大概已经明白,我回复diweo的内容描述了我的理解,对这个指针赋值时,内存块被赋予地址值了。那么对于这 ...

   * (C->A) , 这样就行了,*A本身就是告诉编译器要PC要跳走,你在结构体里面找*A ,那是找不到的, *A本身就不在结构体里面,只有A在结构体里面

使用特权

评论回复
12
Light_David|  楼主 | 2021-1-5 17:31 | 只看该作者
雪山飞狐D 发表于 2021-1-5 17:21
* (C->A) , 这样就行了,*A本身就是告诉编译器要PC要跳走,你在结构体里面找*A ,那是找不到的, *A本 ...

还是我理解的还不够深刻,结构体指针的成员仅是一个类型声明了,就是告诉编译器把接下来被赋值给结构体指针的那片RAM当什么来看,就如我那样声明,其实指针功能已经没有了,* (C->A)这样操作,其实A是不是指针不重要了,只要A和指针类型占用一样的内存宽度和存储格式,就能这样操作

使用特权

评论回复
13
wfw69| | 2021-1-6 10:46 | 只看该作者
学习了,谢谢!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

273

帖子

2

粉丝