Они злые? Может быть. Проблема с глобальными переменными состоит в том, что они могут быть доступны и изменены в любой момент времени любой выполняемой функцией или частью кода без ограничений. Это может привести к ситуациям, которые, скажем, трудно отследить и объяснить. Поэтому желательно свести к минимуму количество глобалов, если возможно, вернуть их к нулю.
Можно ли их избежать? Почти всегда да. Проблема с Arduino заключается в том, что они заставляют вас использовать этот двухфункциональный подход, при котором они предполагают вас setup()
и вас loop()
. В этом конкретном случае у вас нет доступа к области действия функции вызова этих двух функций (вероятно main()
). Если бы вы имели, вы могли бы избавить себя от всех глобальных и использовать вместо этого местных жителей.
Изобразите следующее:
int main() {
setup();
while (true) {
loop();
}
return 0;
}
Это, вероятно, более или менее так выглядит основная функция программы Arduino. Переменные, которые вам нужны как в функции, так setup()
и в loop()
функции, будут предпочтительно объявляться внутри области действия main()
функции, а не в глобальной области действия. Затем их можно сделать доступными для двух других функций путем передачи их в качестве аргументов (при необходимости используя указатели).
Например:
int main() {
int myVariable = 0;
setup(&myVariable);
while (true) {
loop(&myVariable);
}
return 0;
}
Обратите внимание, что в этом случае вам также необходимо изменить сигнатуру обеих функций.
Поскольку это может быть неосуществимо и не желательно, я вижу в действительности только один способ удалить большинство глобалов из программы Arduino без изменения принудительной структуры программы.
Если я правильно помню, вы вполне можете использовать C ++ при программировании для Arduino, а не C. Если вы еще не знакомы (пока) с ООП (объектно-ориентированным программированием) или C ++, может потребоваться некоторое привыкание и некоторые чтение.
Моим предложением было бы создать класс Program и создать единый глобальный экземпляр этого класса. Класс должен рассматриваться как проект для объектов.
Рассмотрим следующий пример программы:
class Program {
public:
Program();
void setup();
void loop();
private:
int myFirstSampleVariable;
int mySecondSampleVariable;
};
Program::Program() :
myFirstSampleVariable(0),
mySecondSampleVariable(0)
{
}
void Program::setup() {
// your setup code goes here
}
void Program::loop() {
// your loop code goes here
}
Program program; // your single global
void setup() {
program.setup();
}
void loop() {
program.loop();
}
Вуаля, мы избавились от почти всех глобалов. Функции , в которых вы бы начать добавлять логику приложения будет правильным Program::setup()
и Program::loop()
функции. Эти функции имеют доступ к переменным - членам экземпляра конкретных myFirstSampleVariable
и в mySecondSampleVariable
то время как традиционные setup()
иloop()
функции не имеют доступа , поскольку эти переменные были отмечены класса приватным. Эта концепция называется инкапсуляцией или сокрытием данных.
Обучение ООП и / или C ++ немного выходит за рамки ответа на этот вопрос, поэтому я на этом остановлюсь.
Подводя итог: глобалы следует избегать, и почти всегда можно резко сократить количество глобалов. Также, когда вы программируете для Arduino.
Самое главное, я надеюсь, что мой ответ несколько полезен для вас :)