Найти тему
VktrSansara

Arduino, "Короткое замыкание" логических операторов && и ||

Понятие "Короткое замыкание" (в анг.яз. Short-Circuiting) связано с операторами && и ||. Это метод оптимизации компилятора, позволяющий избежать вычисления ненужного выражения.

Например, во время вычисления оператора &&, выражение в левой части оператора дает результат false, то независимо от значений правой части логическое выражение всегда будет давать значение false в качестве конечного результата. Тем самым компилятор избегает вычисления правой части.

Аналогично для оператора || , когда левая часть принимает значение true, результат выражения всегда будет true независимо от значения правой части.

Звучит сложно, но на примерах все проще чем на словах, так что перейдем к ним:

Глядя на эти пример стоит вспомнить о приоритетах выполнения операций...

"Короткое замыкание" на примере оператора &&.

Поскольку первый операнд равен false, вычисление прекращается и возвращается false.

if ( false && true && true ) {

// True! Не будет выполнено

} else {

// False! Будет выполнено

}

Для наглядности рассмотрим пример с || но без "Короткого замыкания":

В примере ниже будет вычисляться всё выражение целиком, так как перед последним условием нет значения true.

if ( false || false || true ) {

// True! Будет выполнено

} else {

// False! Не будет выполнено

}

В учебниках по языку C++ обычно приводят пример короткого замыкания не с булевыми значениями, а с целыми числами для большей наглядности. Этот пример я тоже приведу:

int a = 1, b = 1, c = 1;

void setup() {

Serial.begin(9600);

}

void loop() {

if ( a == b || c++ ) {

Serial.println("True!");

} else {

Serial.println("False!");

}

Serial.println(c);

delay(1000);

}

В примере выше значение "c" не будет увеличиваться из-за короткого замыкания.

Ниже противоположный пример, где "c" будет увеличиваться из за отсутствия короткого замыкания:

int a = 1, b = 1, c = 1;

void setup() {

Serial.begin(9600);

}

void loop() {

if ( a == b && c++ ) {

Serial.println("True!");

} else {

Serial.println("False!");

}

Serial.println(c);

delay(1000);

}