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中的宏数组-是不是可能的主要内容,如果未能解决你的问题,请参考以下文章

C语言中的宏定义如何使用?

C ++中的宏指令和预处理器指令有啥区别[重复]

C语言中的宏定义怎么用?

学习 C 中的宏的建议

MISRA C 2012 - 规则 21.1 - 以下划线开头的宏

C语言问题,宏定义中的参数为啥要定义,不是主函数中的参数直接替换吗?