我遇到了一个奇怪的代码
static ROMCONST struct testcase * ROMCONST *patterns[] = {
patternbmk,
NULL
};
可以找到此代码 here .
这是什么类型的结构定义/声明?
谁能用简单的英语解释一下这是什么意思?
最佳答案
关于ROMCONST
:
就我们理解这些声明而言,ROMCONST
只是一些用来代替 const
的噪声宏。
此类定义在嵌入式系统中很常见,您有时需要非标准的东西才能在闪存中分配数据。哈佛架构尤其因此而臭名昭著,而且 8/16 位 MCU 也可能需要非标准 *far
指针。最后,如果该表分配在 EEPROM/数据闪存中,尽管它是只读的,但它可以在运行时更新,因此我们需要添加 volatile
。所有这些东西都可以隐藏在 ROMCONST 中。所以理论上我们可以有一些凌乱且部分不标准的东西,比如
#define ROMCONST volatile const far PROGMEM
(其中 volatile
来自eeprom/数据闪存,const
用于任何类型的闪存,far
用于存储内存和PROGMEM
用于在哈佛 MCU 上的 ROM 中声明数据的东西。)
现在,我将忽略它并将其替换为 const
。
要了解代码其余部分的 const
限定符,请从指向数组开始,例如 patternbmk
。
const struct testcase * const patternbmk[] = {
把这个分开:
struct testcase * patternbmk[]
声明一个指向结构的指针数组。const struct testcase * patternbmk[]
为这些指针提供只读访问权限。所指向的数据是const
并且不能通过这些指针进行修改。const struct testcase * const patternbmk[]
使指针本身变为只读,这主要是为了确保表分配在闪存而不是 RAM 中。
调整编码风格(例如 *const
),将指针声明及其限定符写在一起可能会有所帮助。
接下来,程序员希望声明一个指向这些指针数组的指针数组。 (正如您所知,这开始变得困惑......)有两种方法可以用来指向指针数组,或者通过使用数组指针指向数组,或者通过指向位于带有指针的数组的第一项。程序员选择了后者。
数组项的类型为 const struct testcase * const
,为了指向这样的项,我们在右侧添加一个额外的 *
,最后为const struct testcase * const *
。从右到左阅读这样的困惑声明是有帮助的:指向 const 的指针-指向 const struct testcase 的指针。
然后他们希望创建一个这样的指针到指针的数组,只需在末尾添加一个 []
即可: const struct testcase * const *patterns[]
.
并非该数组中的每个初始值设定项都隐式“衰减”为指向第一项的指针,因此初始值设定项 patternbmk
衰减为 &patternmk[0]
,这恰好是指向 const 的指针,指向 const struct testcase,与我上面讨论的类型相同。
最后,static
限定符只是将变量范围限制在声明它的文件中。 patterns
初始值设定项列表末尾的 NULL 是一个哨兵值,标记数组的末尾。
关于c - 结构体定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58970009/