Vi chiedo cortesemente se potreste darmi chiarimenti in merito a questa struttura di selezione di uno sketch che ho trovato in rete.
Quello che non capisco è a che cosa serve quel if (digitalRead(SignalPin)) se non c'è nessuna condizione da verificare?
Sembrano solo delle istruzioni di assegnamento.
Eppure lo sketch funziona solo in questo modo.
Ma vorrei capire la logica !
Si tratta della forma abbreviata usata tantissimo, qui la forma esplicita:
if (digitalRead(SIGNAL_PIN) == true) {
Funziona anche come segue:
if (true) {
Questo lascia intuire che se la condizione è il valore restituito dalla chiamata a funzione digitalRead(SIGNAL_PIN) si può omettere == true. Se digitalRead(SIGNAL_PIN) restituisce true viene eseguito il ramo {... }. Diversamente viene eseguito il ramo else {... }
Quando si ritiene sia il caso (per maggiore chiarezza) di esplicitare la condizione lo si fa.
Nota che se provi questo:
if (!false) {
Serial.println("la negazione di false è true");
}
Stamperà quel messaggio.
PS: Ricorda di premere CTRL+T per identare il codice prima di copiare e postare. Fallo spesso anche se non devi postare.
A quanto correttamente ti hanno già indicato, manca forse solo una cosa da chiarirti bene.
Parlando genericamente, la if() considera la condizione tra parentesi come verificata, ossia "true", se il valore del suo argomento è diverso da zero, e non verificata, ossia "false", se uguale a zero.
Questo significa che "if(1)" e "if(34)", ad esempio, sono tutte equivalenti a "if(true)" e solo "if(0)" è "false".
Parlando della digitalRead(), quindi, saprai che questa restituisce LOW o HIGH che sono a loro volta simboli definiti in "Wiring.h":
#define HIGH 0x1
#define LOW 0x0
Quindi LOW vale 0 e per la if() equivale a FALSE, mentre HIGH, che vale 1, essendo diverso da zero equivale a TRUE.
Il che significa che con "if(digitalRead(SIGNAL_PIN))" si intende "se lo stato del pin SIGNAL_PIN è diverso da zero" ovvero equivale implicitamente a "if(digitalRead(SIGNAL_PIN) == HIGH)".
In realtà, almeno in teoria l'unica forma universalmente certa è if (digitalRead (SIGNAL_PIN)) if (!digitalRead (SIGNAL_PIN))
perché il confronto viene fatto con zero (LOW), mentre "HIGH" potrebbe assumere qualunque valore diverso da zero secondo il contesto...
Cioè... Uhmm... docdoc, vuoi dire qualcosa in proposito?...
Allora, c'è da fare una distinzione ...
... intanto sono "true" e "false" in minuscolo, poi ... dipende da dove li usi:
in 'C', if e while, considerano "false" il valore zero e "true" tutto ciò che è diverso da zero.
le due parole "true" e "false" sono invece definite come macro in "stdbool.h" e valgono 1 e 0
Quindi, quando fai un if() o un while() viene vautato il contenuto e, se zero, considerato come condizione logica falsa mentre, se diverso da zero, come condizione logica vera, mentre, se usi le due macro "true" e "false" stai usando i valori 1 e 0.
*===---- stdbool.h - Standard header for booleans -------------------------===
*
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
* See https://llvm.org/LICENSE.txt for license information.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
*===-----------------------------------------------------------------------===
*/
#ifndef __STDBOOL_H
#define __STDBOOL_H
/* Don't define bool, true, and false in C++, except as a GNU extension. */
#ifndef __cplusplus
#define bool _Bool
#define true 1
#define false 0
#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
/* Define _Bool as a GNU extension. */
#define _Bool bool
#if __cplusplus < 201103L
/* For C++98, define bool, false, true as a GNU extension. */
#define bool bool
#define false false
#define true true
#endif
#endif
#define __bool_true_false_are_defined 1
#endif /* __STDBOOL_H */
Però credo che sia in realtà un problema della define...
Perche mi sembra di ricordare che se si facesse
''' #define true (bool)1
'''
Le regole di casting implicito obbligatorio delle ultime versioni dello standard dovrebbero castare 255 a 1
Ma non sto qui a provare
Io ho sempre omesso test inutili come ==1 o ==0
E secondo me si tratta di una delle prime cose da imparare in C: liberarsi delle inutilità...
Vi ringrazio di essere stati cosi dettagliati
Ora la cosa è sicuramente più chiara.
Vorrei solo capire come fate a ricordarvi tutte queste regole "sintattiche"
Mi piacere trovare un memorandum sul C dove poter accorrere quando incappo in queste lacune!
Ma devo dire che sono anche un po confuso perchè quei due tre testi che ho letto sul C si perdono in tanti preamboli poco diretti e pratici, da sfogliare all'occorrenza , e non trattano molto la programmazione ad oggetti molto utile nelle librerie.
Anzi se avete qualche consiglio è ben accetto!
Come ti comprendo e ancora adesso non ho un manuale di riferimento sulla programmazione ad oggetti. Il libri sul C++ spiegano tutto sulle classi, ma come usare la parola chiave class per creare una gerarchia di classi questo non lo spiegano nel dettaglio. Ho scoperto ad un certo punto che serviva studiare l'ingegneria del software, poi ho scoperto i design pattern, ma non è bastato. I libri costano (ma ci sono risorse online gratuite meglio di niente) e non bastano, scrivendo codice C++ impiegando le librerie Qt (meglio noto come framework) mi sono detto visto che ho il codice sorgente perché non provare a studiare il codice e così feci e scopri tante belle cose come pimpl (ops link che non avevo mai visitato sembra interessante), ma tutto questo serviva sul PC e con arduino avevo poco a che fare e quindi la ricerca continuò fino a quando acquistai un libro e scoprì che anche in C si poteva programmare ad oggetti. Ma non basto e non basta ancora adesso e di libri ne ho letti. Penso che l'argomento sia davvero complesso e molto ampio che non si può ridurre a come creare una classe che è solo il punto di partenza.
Ci sono altri libri che descrivono l'uso del C++ in embedded ma serve il tempo per leggerli e applicarli e poi credo che una buona predisposizione all'astrazione (ciò che mi manca) agevoli molto. Tutto questo so ma so anche che con arduino ed in genere con MCU (anche anche ARM) con ridotte risorse il C++ va usato in modo specifico e ciò vuole dire che per alcune architetture ad es AVR non puoi allocare dinamicamente la memoria con new a cuor leggero come si fa sul PC.
Ora ti do il consiglio di prendere dimestichezza con il C++ con la parola chiave class e poi andare a studiare il codice del core di arduino.
PS: ma quanto siete precisi, avete dedicato un capitolo intero a if (cond)
il "testo sacro" del 'C' ... è il "riferimento" del linguaggio e come tale è scritto (ovvero NON si perde in chiacchiere, ma descrive tutti gli elementi del 'C') ... QUESTO
un testo scritto da un ex. admin di questo forum, nonché caro amico, che è tra i migliori libri in Italiano che puoi trovare, dedicato specificatamente ad Arduino ... QUESTO