As an addition to the excellent responses of Reynald0 and eferion I would like to comment on something that has been overlooked by both of you and that is relevant to your question.
Question.
Am I correct if I say that the code within the condition will be fulfilled if both conditions, the first and second are fulfilled or if the third one is fulfilled?
In Spanish, your code says the following:
if (distanciaCM<=50 && digitalRead(bombaPIN) == HIGH || f=="off"){
//mi código si se cumple la condición
}
If distanciaCM
is less than or equal to 50
AND the return of digitalRead(bombaPIN)
is HIGH
, O if f
is "off"
then execute the code .
Lazy logic.
But in C ++ the sentence in the previous section is not exactly true; C ++ uses short circuit evaluation 1 which means that after evaluating the first operating from a logical statement we can ignore the second operand, this second operand will not be executed.
In which cases does C ++ short-circuit the evaluation?
- When evaluating
A && B
if A
is false
, we know that the whole operation will be false
regardless of the value of B
so, B
is not evaluated.
- When evaluating
A || B
if A
is true
, we know that the whole operation will be true
regardless of the value of B
so, B
is not evaluated.
Consequences for the code.
If any of the short-circuited operands is a function call, that function will not be called. In your case you have a function call on the short side ( digitalRead(bombaPIN)
) and that call will not occur if distanciaCM
is less than or equal to 50
, on the other hand the comparison f=="off"
will never occur again if distanciaCM
is less than or equal to 50
and the return of digitalRead(bombaPIN)
is HIGH
, we can check it with this code:
enum e { HIGH, LOW };
bool digitalRead(bool b) {
std::cout << __FUNCTION__ << '\n';
return b ? HIGH : LOW;
}
struct F {
bool operator ==(const char *tag) const {
std::cout << __FUNCTION__ << '\n';
return false;
};
} f;
int main()
{
for (int distanciaCM = 45; distanciaCM != 55; ++distanciaCM)
{
const bool bombaPIN = (distanciaCM % 2) == 0;
std::cout << distanciaCM << '\n';
if (distanciaCM<=50 && digitalRead(bombaPIN) == HIGH || f=="off"){
std::cout << "mi código si se cumple la condición\n";
}
}
return 0;
}
In the previous example we see how the digitalRead
function has the secondary effect of showing its name in the console; we also see that the call to the equity operator of the object F
does the same, this produces the following output:
45
digitalRead
operator==
46
digitalRead
mi código si se cumple la condición
47
digitalRead
operator==
48
digitalRead
mi código si se cumple la condición
49
digitalRead
operator==
50
digitalRead
mi código si se cumple la condición
51
operator==
52
operator==
53
operator==
54
operator==
We can see that while distanciaCM
is less than or equal to 50
function digitalRead
has been executed (it has been short-circuited). We can also see that when the first part of the expression was true the second part has not been executed either:
| distanciaCM | distanciaCM<=50 | digitalRead(bombaPIN) == HIGH | f=="off" |
| 45 | verdadero | falso | falso |
| 46 | verdadero | verdadero | cortocircuito |
| 47 | verdadero | falso | falso |
| 48 | verdadero | verdadero | cortocircuito |
| 49 | verdadero | falso | falso |
| 50 | verdadero | verdadero | cortocircuito |
| 51 | falso | cortocircuito | falso |
| 52 | falso | cortocircuito | falso |
| 53 | falso | cortocircuito | falso |
| 54 | falso | cortocircuito | falso |
As you see, whenever distanciaCM<=50
was not fulfilled, the function digitalRead
was not executed, we can also see that if distanciaCM<=50 && digitalRead(bombaPIN) == HIGH
was true, it was not called the second part of the comparison.
Reorder conditions.
If you need the digitalRead
function to be called you should always flip the expression:
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvv <--- siempre se ejecuta
if (digitalRead(bombaPIN) == HIGH && distanciaCM<=50 || f=="off"){
// posible cortocircuito ---> ~~~~~~~~~~~~~~~
//mi código si se cumple la condición
}
Other things to consider.
Operators defined by the user (OdU) are not affected by the short circuit.
1 Also known as lazy logic.