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