标题: 如何对C语言结构指针数组中成员的访问? [打印本页]

作者: nearsea    时间: 2024-6-8 15:26
标题: 如何对C语言结构指针数组中成员的访问?
本帖最后由 nearsea 于 2024-6-9 09:11 编辑

举个例子,一个项目中需要10个配方,同时需要触摸屏修改和显示,我一般都是定于一个保持寄存器数组,然后把配方结构指向保持寄存器数组。
我们需要访问结构数组中成员,一般来说用直接引用就可以了,但用指针引用的时候往往会出现意外情况,也就是说访问不到需要的内容。
U8 xdata vbhHoldReg[sizeof(RECIPE_TypeDef)*10U];
RECIPE_TypeDef xdata *vsRecipe[10] = &vbhHoldReg[0];



获取配方2中whTimeDry变量
下面两个表达中谁是正确的,谁是有问题的,为什么呢?

表达一:
vwhTimeDry = vsRecipe[2]->whTimeDry;
表达二:
vwhTimeDry = (*vsRecipe)[2].whTimeDry;



作者: xxxevery    时间: 2024-6-8 22:29
你只要搞清楚vsRecipe是数组不是指针,就应该明白表达二用法有问题
作者: littlespider    时间: 2024-6-9 08:32
“*vsRecipe[10] = &vbhHoldReg[0]; ”vsRecipe是个指针数组(元素类型是:RECIPE_TypeDef xdata*),不清楚你的 vbhHoldReg是不也是指针数组。总之:
vsRecipe[2] = vbhHoldReg[2],*(vsRecipe[2]) != vbhHoldReg[2]

如果 vbhHoldReg 的元素类型是 RECIPE_TypeDef xdata 的话,猜你可能需要的是
RECIPE_TypeDef xdata *vsRecipe = &vbhHoldReg[0]; 或者
RECIPE_TypeDef xdata *vsRecipe = vbhHoldReg;
作者: nearsea    时间: 2024-6-9 08:57
xxxevery 发表于 2024-6-8 22:29
你只要搞清楚vsRecipe是数组不是指针,就应该明白表达二用法有问题

恭喜你,答错了,正好相反,可以跟踪一下debug窗口。

Test1.zip

30.19 KB, 下载次数: 1

keilDEMO


作者: nearsea    时间: 2024-6-9 09:13
littlespider 发表于 2024-6-9 08:32
“*vsRecipe[10] = &vbhHoldReg[0]; ”vsRecipe是个指针数组(元素类型是:RECIPE_TypeDef xdata*),不清 ...

U8 xdata vbhHoldReg[sizeof(RECIPE_TypeDef)*10U];
数组类型是unsigned char.
作者: littlespider    时间: 2024-6-9 15:48
这就是了,vbhHoldReg存储的的是10个 RECIPE_TypeDef 大小的数据(某些场合也可看作是10个 RECIPE_TypeDef 的数组),vsRecipe是10个 RECIPE_TypeDef xdata * 的数组,两个数组元素类型都不同,出错是正常。还有“RECIPE_TypeDef xdata *vsRecipe[10] = &vbhHoldReg[0];”这句能编译通过?
作者: nearsea    时间: 2024-6-9 16:53
littlespider 发表于 2024-6-9 15:48
这就是了,vbhHoldReg存储的的是10个 RECIPE_TypeDef 大小的数据(某些场合也可看作是10个 RECIPE_TypeDef  ...

其实RECIPE_TypeDef xdata *vsRecipe[10] = &vbhHoldReg[0]定义虽然编译没有问题,意义也不多,就是给vsRecipe数组赋予一个首地址,很多编译器需要显式转换写成RECIPE_TypeDef xdata *vsRecipe[10] = (RECIPE_TypeDef xdata *)&vbhHoldReg[0]这个样子。
作者: hy47566398    时间: 2024-6-11 01:02
U8 xdata vbhHoldReg[sizeof(RECIPE_TypeDef)*10U];
改成:
RECIPE_TypeDef xdata vbhHoldReg[10];
RECIPE_TypeDef *vsRecipe = &vbhHoldReg;
访问:
第5个和第10个元素:
(vsRecipe + 4)->whTimeDry = 1;
(vsRecipe + 9)->whTimeDry = 2;
x = vsRecipe + 4;
y = vsRecipe + 9;
作者: nearsea    时间: 2024-6-11 18:15
hy47566398 发表于 2024-6-11 01:02
U8 xdata vbhHoldReg;
改成:
RECIPE_TypeDef xdata vbhHoldReg[10];

这么做意义就不大了,本意是“U8 xdata vbhHoldReg[]”定义一堆长数组用于支持MODBUS访问支持,RECIPE_TypeDef xdata *vsRecipe[10]只是一堆数据中的少部分,所以定义成不同类型还是很重要的。
作者: xxxevery    时间: 2024-6-12 17:21
如果RECIPE_TypeDef和U8的数据类型一样那你这么写还能接受,如果不一样你这么写就不规范了,虽然同一编译系统中地址的字节大小是一样的,但是包含的意义是不同的,对不同数据类型的地址进行一些操作得到结果是不同的。在c语言中还是强调在同种数据类型间进行数据操作,虽然现在也有很多能进行隐形数据转换,这也是减少隐藏bug的基本做法




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1