scope
Область видимости (scope) определяет, каким частям программы доступна переменная; глобальные видны во всём скетче, локальные — только внутри своего блока {}.
Полная статья
Описание
Область видимости (scope) — это правило, которое определяет, в каком месте программы переменная «видна» и может быть использована. В Arduino-скетчах, как и в C++, переменные делятся на глобальные и локальные.
Глобальная переменная объявляется вне любых функций — обычно в самом начале файла. Её видят setup(), loop() и все остальные функции в этом файле.
Локальная переменная объявляется внутри функции или блока кода (между фигурными скобками {}). Она существует только пока выполняется этот блок, а после выхода из него — исчезает. Обратиться к ней снаружи невозможно.
Пример кода
int gPWMval; // эта переменная видна из любой функции
void setup() {
// ...
}
void loop() {
int i; // "i" видна только внутри "loop"
float f; // "f" видна только внутри "loop"
// ...
for (int j = 0; j < 100; j++) {
// переменная j доступна только внутри скобок цикла for
}
}
Где применяется
- Счётчик в цикле — классический пример локальной переменной:
int iв заголовкеforнужна только внутри этого цикла и нигде больше. - Флаг состояния устройства — если несколько функций должны знать, включён ли мотор или в каком режиме работает устройство, удобнее хранить это в глобальной переменной.
- Последние показания датчика — если
setup()читает датчик и передаёт значение вloop()для отображения, глобальная переменная служит «мостом» между ними. - Обработчики прерываний — переменная, которую устанавливает ISR и проверяет
loop(), должна быть глобальной (и объявленной какvolatile).
Практические замечания
- Не делайте переменную глобальной «на всякий случай». Чем уже область видимости, тем проще читать и отлаживать код: сразу понятно, кто и откуда может изменить значение.
- Переменная в заголовке
forдоступна только внутри тела этого цикла. Попытка обратиться к ней после закрывающей скобки вызовет ошибку компиляции. - Одинаковые имена в разных областях не конфликтуют, но могут запутать. Если локальная переменная называется так же, как глобальная, внутри блока будет использоваться локальная — глобальная при этом не изменится. Такое «затенение» лучше избегать.
- Если локальная переменная должна помнить своё значение между вызовами функции, используйте квалификатор
static. Переменная останется локальной по видимости, но не будет уничтожаться при выходе из функции. - При отладке через Serial Monitor полезно помнить: если вы распечатываете переменную и получаете неожиданное значение, проверьте, не объявлена ли одноимённая переменная в локальной области — возможно, вы читаете не ту.