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