c中的宏数组-是不是可能
Posted
技术标签:
【中文标题】c中的宏数组-是不是可能【英文标题】:Array of macros in c -- is it possiblec中的宏数组-是否可能 【发布时间】:2016-04-08 06:36:43 【问题描述】:我想知道是否可以创建类似宏数组的东西。 我已经实现了以下有效的代码:
struct led_cmds_
ioport_pin_t *commands[LED_COUNT] ;
;
struct led_cmds_ the_led_cmd_ ;
void populate()
the_led_cmd_.commands[0] = SPECIFICPIN(0);
主要是:
int main(void)
//.....
populate();
LED_On(the_led_cmd_.commands[0]);
SPECIFICPIN(x)
是宏定义为:
#define SPECIFICPIN(X) (LED##X##_PIN)
我所希望的是一种方法来做这样的事情:
#define ioport_pin_t* ARR_LED[LED_COUNT] \
for (int j = 0; j < LED_COUNT; j++) ARR_LED[j] = SPECIFICPIN(j);
然后只需要在我想使用特定引脚时调用以下内容
LED_On(ARR_LED[some_number])
当我尝试这样做时,我得到一个 ARR_LED undeclared (first use in this function) 错误。
当我尝试调用 SPECIFICPIN(x)
时,例如,其中 x 是 for 循环中的一个 int 迭代器,我收到一条错误消息,例如“LEDx_PIN”未声明...
【问题讨论】:
不知道您是否使用 gcc 工具链,但无论如何您都需要将 C99 用于 avr-gcc(以及它的支持库)——通常与-Os
结合使用。为什么不坚持使用内联函数?
编译器对宏一无所知,因为在调用编译器之前它们已被 预处理器 替换。因此宏数组是不可能的
使用硬件寄存器时,为什么需要一个指针数组?那是可疑的代码。
此外,不存在具有可变 I/O 端口数量的硬件。任何集成电路都必须有固定数量的引脚,您不能即时添加和移除它们。只需声明一个对应于最坏情况的数组,然后根据需要使用尽可能多的数组项。
你是想给我做噩梦吗?
【参考方案1】:
您需要处理您的术语。 宏数组是不可能的。宏不是数据类型,而是在您的程序实际编译之前纯粹的文本替换。
我猜“使用宏填充数组”是您想要做的。但是不可能在编译时循环中做到这一点 - 您似乎想要通过您的 ioport_pin_t
宏尝试来实现。宏无法扩展到比您最初提供的更多的文本元素实例。没有像在编译时循环通过宏扩展和重复扩展宏这样的功能。
您的for
循环在运行时循环,而宏在编译时展开。一旦你让自己知道预处理器做了什么,编译器做了什么,以及完成的程序在运行时做了什么,你就会发现那是行不通的。
类似
#define P(X) (LED##X##_PIN)
ioport_pin_t *commands[LED_COUNT] =
P(0), P(1), P(2),......
#undefine P
可能是最接近您想要的东西。请注意,预处理器的主要用途不是为了节省您的打字工作量 - 您最好在编辑器中使用复制和粘贴,实现相同的效果并获得更清晰的代码。
【讨论】:
复制粘贴违反DRY规则,是very easy to make mistake 如果复制和粘贴澄清您的程序正在做什么(反复初始化数组成员)它不违反任何规则恕我直言。至少您可以立即看到正在发生的事情,您没有使用(最好)短#defines 污染预处理器名称空间。并且:一般在C语言中很容易出错..... 感谢您的帮助。我最终制作了一堆这样的预处理器指令:#if LED_COUNT == n 添加到位置 n -1 的数组,取消定义 LED_COUNT,然后再次将其定义为 n-1,然后调用 #elif LED_COUNT == n-1 并执行降至 0【参考方案2】:一个数组作为 tofro 的答案是要走的路。但是,如果无法简单地用数组解决,那么还有另一种方法可以使用 switch
#define SPECIFICPIN(X) (LED##X##_PIN)
void setpin(int pin, int value)
switch (pin)
case 1:
SPECIFICPIN(1) = value;
doSomething(); // if needed
break;
case x: ...
default: ...
【讨论】:
以上是关于c中的宏数组-是不是可能的主要内容,如果未能解决你的问题,请参考以下文章