找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1746|回复: 9
收起左侧

如何对C语言结构指针数组中成员的访问?

[复制链接]
ID:1101997 发表于 2024-6-8 15:26 | 显示全部楼层 |阅读模式
本帖最后由 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;


回复

使用道具 举报

ID:59202 发表于 2024-6-8 22:29 | 显示全部楼层
你只要搞清楚vsRecipe是数组不是指针,就应该明白表达二用法有问题
回复

使用道具 举报

ID:1041851 发表于 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;
回复

使用道具 举报

ID:1101997 发表于 2024-6-9 08:57 | 显示全部楼层
xxxevery 发表于 2024-6-8 22:29
你只要搞清楚vsRecipe是数组不是指针,就应该明白表达二用法有问题

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

Test1.zip

30.19 KB, 下载次数: 1

keilDEMO

回复

使用道具 举报

ID:1101997 发表于 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.
回复

使用道具 举报

ID:1041851 发表于 2024-6-9 15:48 | 显示全部楼层
这就是了,vbhHoldReg存储的的是10个 RECIPE_TypeDef 大小的数据(某些场合也可看作是10个 RECIPE_TypeDef 的数组),vsRecipe是10个 RECIPE_TypeDef xdata * 的数组,两个数组元素类型都不同,出错是正常。还有“RECIPE_TypeDef xdata *vsRecipe[10] = &vbhHoldReg[0];”这句能编译通过?
回复

使用道具 举报

ID:1101997 发表于 2024-6-9 16:53 | 显示全部楼层
littlespider 发表于 2024-6-9 15:48
这就是了,vbhHoldReg存储的的是10个 RECIPE_TypeDef 大小的数据(某些场合也可看作是10个 RECIPE_TypeDef  ...

捕获.JPG 其实RECIPE_TypeDef xdata *vsRecipe[10] = &vbhHoldReg[0]定义虽然编译没有问题,意义也不多,就是给vsRecipe数组赋予一个首地址,很多编译器需要显式转换写成RECIPE_TypeDef xdata *vsRecipe[10] = (RECIPE_TypeDef xdata *)&vbhHoldReg[0]这个样子。
回复

使用道具 举报

ID:1012735 发表于 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;
回复

使用道具 举报

ID:1101997 发表于 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]只是一堆数据中的少部分,所以定义成不同类型还是很重要的。
回复

使用道具 举报

ID:59202 发表于 2024-6-12 17:21 | 显示全部楼层
如果RECIPE_TypeDef和U8的数据类型一样那你这么写还能接受,如果不一样你这么写就不规范了,虽然同一编译系统中地址的字节大小是一样的,但是包含的意义是不同的,对不同数据类型的地址进行一些操作得到结果是不同的。在c语言中还是强调在同种数据类型间进行数据操作,虽然现在也有很多能进行隐形数据转换,这也是减少隐藏bug的基本做法
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表