Запутался в typedef, пример для FastLED

Sakolua
Offline
Зарегистрирован: 13.08.2019

Вот тут нашел пример создания списка функций и с доп параметрами. https://gist.github.com/kriegsman/841c8cd66ed40c6ecaae
Но он не компилируется.

'confetti' was not declared in this scope

и другие функции так же, функции там ниже есть.

Я никак не пойму, что он тут делает.

typedef void (*SimplePattern)();
typedef SimplePattern SimplePatternList[];
typedef struct { SimplePattern mPattern;  uint16_t mTime; } PatternAndTime;
typedef PatternAndTime PatternAndTimeList[];

// These times are in seconds, but could be changed to milliseconds if desired;
// there's some discussion further below.

const PatternAndTimeList gPlaylist = { 
  { confetti,                5 },
  { juggle,                 10 },
  { bpm,                    10 },
  { rainbowWithGlitter,      5 },
  { juggle,                  5 },
  { applause,               10 },
  { fadeToBlack,             3 }
};

Зачем столько typedef и почему все равно не работает?

 

b707
Offline
Зарегистрирован: 26.05.2017

Судя по ошибке, typedef-ы тут не причем.

функции где описаны? - ниже по программе?

переместите их описание выше вашего плейлиста и попробуйте скомпилировать еще раз

asam
asam аватар
Онлайн
Зарегистрирован: 12.12.2018

А можно поместить в начале только декларации

void rainbow();
void confetti();
void juggle();
void rainbowWithGlitter();
void applause();
void bpm();
void fadeToBlack();

 

Sakolua
Offline
Зарегистрирован: 13.08.2019

asam пишет:

А можно поместить в начале только декларации

Работает, но вместе в FastLed идет пример DemoReel100.ino

Я так понял это старая версия. И там список функций объявлен как:

typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = { rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm };

И он работает без объявления в начале. Почему?

 

asam
asam аватар
Онлайн
Зарегистрирован: 12.12.2018

Sakolua пишет:

typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = { rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm };

И он работает без объявления в начале. Почему?

Если в первом примере переместить SimplePatternList после setup() то тоже будет компилиться без предварительного объеявления.

Вообще, в С\С++ имена всегда должны быть декларированы до испозования. Ардуино IDE пытается сделать жизнь начинающих делая это за них у себя внутри, но, видимо, не всегда получается.  

Sakolua
Offline
Зарегистрирован: 13.08.2019

А может кто0нибудь описать по строчкам что происходит тут?
typedef void (*SimplePattern)();

ну тут объявляется новый тип для ссылки на функцию

typedef SimplePattern SimplePatternList[];

это еще один новый тип массив [] из ссылок? а разве массив это тоже тип данных? вроде же массив это не само по себе, а сначала тип внутри ячейки, а потом размер?

typedef struct { SimplePattern mPattern;  uint16_t mTime; } PatternAndTime;
 

typedef PatternAndTime PatternAndTimeList[];

rkit
Offline
Зарегистрирован: 23.11.2016

Sakolua пишет:

вроде же массив это не само по себе, а сначала тип внутри ячейки, а потом размер?

Массив в стиле C это просто непрерывный блок памяти кратный размеру элементов и ничего более. Размер учитывается отдельно.

asam
asam аватар
Онлайн
Зарегистрирован: 12.12.2018

rkit пишет:

Массив в стиле C это просто непрерывный блок памяти кратный размеру элементов и ничего более. Размер учитывается отдельно.

С умным видом изрек банальность rkit. Так ничего толком и не ответив по существу заданного вопроса.

Sakolua. Сейчас, доберусь до компа и объясню. С телефона неудобно.

asam
asam аватар
Онлайн
Зарегистрирован: 12.12.2018

Объясняю:

typedef void (*SimplePattern)();
 
Определяем указатель с именем SimplePattern который может указывать на любую функцию типа void foo()
 
typedef SimplePattern SimplePatternList[]; Тут вообще не при делах и эту строчку можно смело выкинуть.
 
typedef struct { SimplePattern mPattern;  uint16_t mTime; } PatternAndTime;
Определяем структуру которая состоит из указателя на функцию и uint16_t (aka unsigned int )
 
typedef PatternAndTime PatternAndTimeList[];
 
определяем тип массива из вышеуказанных структур. Поскольку это не сам по себе массив а только тип, то размер тут ни причем.
Размер определитсчя тут :
 
const PatternAndTimeList gPlaylist = { 
  { confetti,                5 },
  { juggle,                 10 },
  { bpm,                    10 }, 
...}
 
Cколько мы строчек тут напишем столько памяти и выделится (если ее хватит, конечно)
 
В С/С++ размер массива нигде не хранится просто при описании массива выделяется определенное количество памяти определяемое или цифрой в квадратных скобках или длинной списка элементов, как в вышеприведенном случае.
DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

21-й век на дворе, а про using тут так никто ничо и не знает. 

Sakolua
Offline
Зарегистрирован: 13.08.2019

А вот зачем вообще делать typedef для []

Если мы делаем обычный массив

string students[10] = {
    "Иванов", "Петров", "Сидоров",
    "Ахмедов", "Ерошкин", "Выхин",
    "Андеев", "Вин Дизель", "Картошкин", "Чубайс"
};

Мы же не пишем typedef string stringlist[];
Sakolua
Offline
Зарегистрирован: 13.08.2019

typedef PatternAndTime PatternAndTimeList[];

Имею ввиду зачем это? И почему просто не PatternAndTime[]

asam
asam аватар
Онлайн
Зарегистрирован: 12.12.2018

Sakolua пишет:

typedef PatternAndTime PatternAndTimeList[];

Имею ввиду зачем это? И почему просто не PatternAndTime[]

Я же писал, эта строчка здесь вообще от балды и ее можно удалить.

Sakolua
Offline
Зарегистрирован: 13.08.2019

typedef SimplePattern SimplePatternList[]; Тут вообще не при делах и эту строчку можно смело выкинуть.

не, то другая строка была

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Sakolua, ну, почитайте Вы уже книжку по языку, ну что ж Вы тычетесь, как слепой котёнок, аж жалко Вас. Если Вы надеетесь освоить язык методом тыка и догадок, что написано в чужих кодах - не надейтесь - не освоите. Читаю Ваш первый пост ... ужас, у Вас не хватает знаний даже, чтобы задать вопрос, не то, чтобы найти ответ на него.