如何在C中使用##粘贴术语和计数器

How to paste a term and counter in C using ##?

本文关键字:术语 计数器      更新时间:2023-10-16

在嵌入式系统中定义:

#define Row1_PORT   GPIOD
#define Row1_PIN    GPIO_PIN_4
#define Row2_PORT   GPIOD
#define Row2_PIN    GPIO_PIN_7
#define Row3_PORT   GPIOD
#define Row3_PIN    GPIO_PIN_1
#define Row4_PORT   GPIOD
#define Row4_PIN    GPIO_PIN_3
//------------
#define Paste2(a,b)   a ## b
#define Paste(a,b)    Paste2(a,b)
#define NRows   4

我想在这样的循环中使用上面定义的宏:

for(i=1;i<=NRows;i++)
{
    GPIO_Init(Paste(Paste(Row,i),_PORT),Paste(Paste(Row,i),_PIN),GPIO_MODE_IN_PU_NO_IT);
}
不是

GPIO_Init(Row1_PORT,Row1_PIN);
GPIO_Init(Row2_PORT,Row2_PIN);
GPIO_Init(Row3_PORT,Row3_PIN);
GPIO_Init(Row4_PORT,Row4_PIN);

有可能吗?我需要一些东西,如__COUNTER__在ANSI C或c++。我的编译器是IAR

预处理器在编译时运行,以文本方式修改呈现给编译器的源代码。你想做的事是不可能的;编译器会在宏展开中嵌入字母i,而不是在运行时嵌入变量i的值。

我可能会这样写:

static const int ports[] = { 0, Row1_PORT, Row2_PORT, Row3_PORT, Row4_PORT };
static const int pins[]  = { 0, Row1_PIN,  Row2_PIN,  Row3_PIN,  Row4_PIN  };
for (int i = 1; i <= NRows; i++)
    GPIO_Init(ports[i], pins[i]);

或者我会手写(正如你在"instead of"选项中所显示的那样)——这几乎没有惩罚,而且可能只节省了4个条目。如果你有100个端口要初始化,循环当然会更好。

此外,如果您打算在将来再次使用端口和引脚编号(在代码的其他部分,而不仅仅是初始化代码),使用数组将允许更大的灵活性。

正如chris所说,在预处理期间,您无法获得此信息,因此您最终将获得

GPIO_Init(Rowi_PORT,Rowi_PIN);

如预期的那样出错。

我不认为宏是正确的工具。为什么不将端口和引脚保存在数组中呢?比如:

int ports[] = {Row1_PORT, Row2_PORT, ...};
int pins[] = {Row1_PIN, Row2_PIN, ...};
for (int i = 0; i < NRows; i++) {
    GPIO_Init(ports[i], pins[i];
}

同样简洁,但没有宏技巧