Как вставить термин и счетчик в C, используя ##?

Во встроенной системе определите:

#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.

1

Решение

Препроцессор запускается во время компиляции и текстовым образом изменяет исходный код, представленный компилятору. То, что вы стремитесь сделать, невозможно; компилятор вставит письмо 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]);

Или я бы выписал это от руки (как вы показываете в своем варианте «вместо») — нет небольшого штрафа и, возможно, небольшая экономия только для 4 записей. Если у вас есть 100 портов для инициализации, цикл, конечно, будет лучше.

Кроме того, если вы собираетесь снова использовать номера портов и выводов в будущем (в других частях кода, а не только в коде инициализации), наличие доступных массивов даст большую гибкость.

2

Другие решения

Как сказал Крис — эта информация недоступна вам во время предварительной обработки, так что вы в конечном итоге

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];
}

Не менее лаконично, но без макросов.

2

По вопросам рекламы [email protected]