Чи вони зла? Може бути. Проблема з globals полягає в тому, що вони можуть бути доступні та модифіковані в будь-який момент часу, виконуючи будь-яку функцію чи фрагмент коду без обмежень. Це може призвести до ситуацій, які, скажімо, важко відстежити та пояснити. Тому бажано звести до мінімуму кількість глобалів, якщо це можливо, повернути суму до нуля.
Чи їх можна уникнути? Майже завжди так. Проблема з 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. Якщо ви не знайомі (ще) з OOP (об'єктно-орієнтоване програмування) або C ++, може знадобитися трохи звикання та читання.
Моя пропозиція полягає в тому, щоб створити клас програми та створити єдиний глобальний екземпляр цього класу. Клас повинен розглядатися як план об'єктів.
Розглянемо наступну програму:
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()
функції не мають доступу, оскільки ці змінні були позначені класу private. Це поняття називається інкапсуляція даних або приховування даних.
Навчання OOP та/або C ++ трохи виходить за рамки відповіді на це питання, тому я зупинюся тут.
Підсумовуючи: необхідно уникнути глобалів і майже завжди можна різко зменшити кількість глобалів. Також, коли ви програмуєте для Arduino.
Найголовніше, сподіваюся, що моя відповідь є дещо корисною для вас :)