FOR_MACRO подскажите можно ли передать масив в качестве аргумента

Николай Ск

✩✩✩✩✩✩✩
28 Мар 2023
12
2
Задался вопросом можноли написать шапку для компилятора типа:
#
for (int i = 0; i <9; i++) {
Serial.print(i) ;
}#
А он сам бы при компиляции написал эти сточки указанное количество раз

В интернете нашёл только одну статью "Циклы" на препроцессоре, в другой теме мне подсказали что это макрос и надо писать

Начал просматривать библиотеки со слова макрос и boost и смотрю есть FOR_MACRO от AlexGyver читаю описание, а там почти так и написано это то, что ты ищешь и даже больше, что способен понять.

Так вот подскажите кто разбирается в библиотеке:
- если аргументы не нужны можно ли указать число повторений, числом (переменной), а не вписывать пустые аргументы вручную
-и можно ли указать массив или структуру с аргументами, а не вписывать аргументы вручную

C++:
#include <FOR_MACRO.h>

byte masiv [] = {5, 25, 35, 45};

void setup() {
  Serial.begin (115200);

  #define MF1(N, i, p, val)\
  Serial.print(N);
  #define FOR_1( ...) FOR_MACRO(MF1, 0, __VA_ARGS__)

  FOR_1(,,,,,,,,);      //развернется как  Serial.print(9);Serial.print(9);Serial.print(9);(9раз по числу аргументов в ())
  Serial.println();
}

void loop() {
  delay (1000);
  Serial.println();
  ///*
  #define MF2(N, i, p, val) Serial.print(i);
  #define FOR_2( ...) FOR_MACRO(MF2, 0, __VA_ARGS__)
  FOR_2(,,,,,,,,);      //развернется как  Serial.print(8);Serial.print(7);Serial.print(6);...
  //*/
   
  //если аргументы не нужны можно ли указать число повторений, числом (переменной), а не вписывать пустые аргументы вручную
  //можно ли указать массив или структуру с аргументами, а не вписывать аргументы вручную
  /*
  #define MF3(N, i, p, val) Serial.print(val);
  #define FOR_3( ...) FOR_MACRO(MF3, 0, __VA_ARGS__)
  FOR_3(*masiv);      //так вписывает один первый аргумент масива
  */

}
 

poty

★★★★★★✩
19 Фев 2020
3,448
981
@Николай Ск, если FOR_MACRO.h управляет препроцессором, то "обычный" массив в него не загнать. Препроцессор работает перед компиляцией, когда никакие переменные, включая массивы, ещё неизвестны. По сути препроцессор аналогичен функции замены текста в текстовом редакторе с незначительными автоматизациями. То есть непосредственно текст программы не анализируется.
 

bort707

★★★★★★✩
21 Сен 2020
3,168
934
@Николай Ск, вы уже третью тему создаете по этому вопросу. Вас в другой теме спросили - почему вы не хотите использовать циклы в коде, зачем это делать в препроцессоре?
 

Николай Ск

✩✩✩✩✩✩✩
28 Мар 2023
12
2
@poty, я не пытаюсь что-то доказать по тому, что мои знания это метод тыка но обрати пожалуйста внимание на часть скетча там в качестве аргумента массив. а результат - это первый элемент массива, поэтому я и посчитал что массив определен, и можно передать, просто я делаю что-то не так.

#define MF3(N, i, p, val) Serial.print(val);
#define FOR_3( ...) FOR_MACRO(MF3, 0, VA_ARGS)
FOR_3(*masiv); //так вписывает один первый аргумент масива
 

Николай Ск

✩✩✩✩✩✩✩
28 Мар 2023
12
2
@poty, я не пытаюсь что-то доказать по тому, что мои знания это метод тыка но обрати пожалуйста внимание на часть скетча там в качестве аргумента массив. а результат - это первый элемент массива, поэтому я и посчитал что массив определен, и можно передать, просто я делаю что-то не так.

#define MF3(N, i, p, val) Serial.print(val);
#define FOR_3( ...) FOR_MACRO(MF3, 0, VA_ARGS)
FOR_3(*masiv); //так вписывает один первый аргумент масива
Подскажи можно ли изменить библиотеку так чтобы она работал не по количеству аргументов, а по заданному числу
 

poty

★★★★★★✩
19 Фев 2020
3,448
981
@Николай Ск, аргументы вставляются в текст программы в виде текста, за исключением ранее определенных define, которые заменяются на их значения. Если есть действия с константами, то все они, по возможности, выполняются препроцессором.
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
584
176
@Николай Ск,
Я уже писал раньше, что на макросах можно много что сделать, но для тех кто ими не пользуется, выглядит это малопонятно.
Я в макросах не разбираюсь.
Т.к. стандартно макросы не поддерживают циклы, то необходимо расписать ВСЕ варианты руками.
Если вы посмотрите FOR_MACRO.h , то увидите что там расписаны все варианты для максимально допустимого числа аргументов. С рекурсивным вызовом.
Если вам в качестве головоломки интересно изучать макросы, то смысл в этом может быть.
Если нет, то лучше обойтись без них.

Простейший вариант макроса для массива сделать легко (без рекурсии и авто подсчета количества).
Надо просто расписать все варианты.
Как пример. (Все, что между //начало и //конец , можно оформить в отдельный макрос, и вызывать его одной строчкой.)
Но повторюсь, я не спец в макросах, могу ошибаться.
Помогать написать макрос под ваши нужды не берусь.

C++:
#define N 10
String arrStr[N] = {"_0_", "_1_", "_2_", "_3_", "_4_", "_5_", "_6_", "_7_", "_8_", "_9_"};

void setup() {
  Serial.begin(9600);
  Serial.println("===START===");

// начало
#if N >= 1
  Serial.println(arrStr[0]);
#endif
#if N >= 2
  Serial.println(arrStr[1]);
#endif
#if N >= 3
  Serial.println(arrStr[2]);
#endif
// И так далее до максимально возможного значения
// Если когда то N может быть 100, то надо записать 100 вариантов
//конец
}

void loop() {
}