dubbio su else if

Ragazzi solo una conferma. Scrivere questo:

if (a==1) {
        eseguo un comando;
      }
      if (a==2) {
        eseguo un comando;
      }
      else {                                     
      if (a<3) {
        eseguo un comando;
      }
       if (a>4) {
        eseguo un comando;
      }
     }

o questo:

if (a==1) {
        eseguo un comando;
      }
      if (a==2) {
        eseguo un comando;
      }
      else if (a<3) {
        eseguo un comando;
      }
      else if (a>4) {
        eseguo un comando;
      }

è la stessa cosa vero? Grazie

NO, stai indentando male e mettendo male gli else ...

if (condizione) {
  // da fare se condizione vera
}
else {
  // da fare se condizione falsa
}

In caso di più if in cascata:

if (condizione) {
  // da fare se condizione vera
}
else if (condizione) {
  // da fase se la prima condizione è falsa, ma la seconda è vera
}
else if (condizione) {
  // da fare se la prima condizione è falsa, la seconda pure e la terza e vera
}
else {
  // da fare se tutte le condizioni sono false
}

Guglielmo

O meglio, il codice ha senso, viene compilato e fa le sue, non ci sono errori.
Il problema è cosa gli dici di fare. Il C controlla le condizioni degli if solo quando si presentano. Nulla vieta, quindi, che il corpo di un if (tra le graffe) renda non più valida la condizione (tra le tonde), o la renda valida per un if successivo.
Se la variabile non la tocchi mai nel corpo degli if allora si, possono essere intercambiabili, ma se anche accidentalmente la tocchi... Apriti Cielo.
Infatti ecco un esempio

byte a=0;
//Codice
if (a==0)
{
a=1;
Serial.print (F("Ciao "));
}
if (a==1)
{
a=2;
Serial.println (F("Mondo"));
}
if (a==3)
{
a=0;
//...
}
//...

viene eseguito tutto, perché il programma trova che una variabile a vale zero.
Poi trova che se una variabile a vale zero (ed è vero) devo fare un insieme di cose, tra cui far valere a come 1. E quindi lo faccio, ormai sono entrato...
Uscito dall'if numero zero ho una variabile a che vale uno.
Oh, che bello, ho un altro if in cui se a vale uno (ed è vero) faccio altro, tra cui rendere a pari a 2.
...
Se, invece, anziché essere tutti if() fossero tutti else if() tranne il primo la cosa cambierebbe di molto.
Il programma trova che a vale zero
Il programma trova un if o un else. L'if dice che se a vale zero...
Essendo vera la condizione eseguo la if()
Non ho scelto la esle, che quindi ignoro, per ora.
...
Secondo giro, a adesso, facciamo, vale uno
La if a==0 non la prendo, ma scelgo la esle.
La quale else contiene un'altra scelta. Se a==1 entro nella SECONDA if, se no entro nella else
a vale uno, entro nella seconda if.
La faccio e salto la esle
Terzo giro
...

Ci tengo a chiarire una cosa: il fatto che siano messi male gli else o meno dipende tutto da cosa vuoi fare, non è assoluto.

Inoltre se devi fare tanti test di uguaglianza su una stessa variabile ti consiglio la switch case. È una forma di if su una sola variabile, molto più semplice da scrivere

Piu che altro a me sembra (ma magari sbaglio), che nel primo caso, l'ultimo if puo venire eseguito anche se una delle condizioni del penultimo e' vera, se nel frattempo a cambia, mentre il secondo caso dovrebbe venire gestito diversamente ...

Cerco di spiegarmi ... siccome l'else e' un "altrimenti", in pratica, credo che introduca un controllo condizionale sulla catena ... nel primo caso, se "a" e' 2, viene eseguito quel comando, ma se intanto, prima che l'ultimo controllo venga effettuato, "a" diventa maggiore di 4 (ad esempio perche' quel comando pone "a" a 5), viene eseguito ANCHE quel comando ... mentre nel secondo caso, visto che tutti i successivi controlli sono sotto "else", se "a" e' due, viene eseguito quel comando, ma gli altri controlli vengono saltati, per cui anche se nel fratempo "a" e' diventato maggiore di 4, NON viene eseguito l'ultimo comando ... o almeno, e' questa l'impressione che mi da quella sequenza ...

... l'ho azzeccata, stavolta ? ... :smiley:

Silente:
...
Inoltre se devi fare tanti test di uguaglianza su una stessa variabile ti consiglio la switch case. È una forma di if su una sola variabile, molto più semplice da scrivere

pero', se non mi sbaglio, la switch case puo gestire solo sequenze numeriche unitarie regolari, giusto ?

Voglio dire, posso usare una switch case se le condizioni sono tipo 0, 1, 2, 3, 4 ... ma NON credo si possa usare se le condizioni da controllare sono, ad esempio, 0, 1, 3, 7, maggiore di 9 ... corretto ?

Etemenanki:
pero', se non mi sbaglio, la switch case puo gestire solo sequenze numeriche unitarie regolari, giusto ?

No, il solo limite è che lo switch vuole una variabile intera e nei case dei valori di tale int (costanti).

Guglielmo

E poi switch non permette "maggiore di" "minore di". Devi prevedere tutti i casi

Silente:
E poi switch non permette "maggiore di" "minore di". Devi prevedere tutti i casi

... infatti ho scritto :

gpb01:
... e nei case dei valori di tale int (costanti).

:smiley: :smiley: :smiley:

Guglielmo

Grazie a tutti....! :slight_smile:

Quello che sto cercando di fare è un codice che a partire dal valore di pressione barometrica al suolo più quello dell'umidità, possa generare una sorta di previsione meteo locale. Tutti questi if, poi andranno a gestire uno switch case per la stampa dell'iconcina sull'app. Vi mostro il codice.

Queste condizioni si basano su alcune letture che ho fatto su svariat siti dedicati. Ovviamente ciò non ha valore scientifico ma può aiutare, a patto che funzioni :grin: .

Ditemi se fa quello che vorrei ottenere, il codice lo fa. Grazie 1000!

void previsione()
{
  if (contatore == 0) {  // forza il confronto di p_rif e p_slm solo al primo avvio
    p_rif = p_slm;
    contatore++;
  }

  if ((millis() - tempo_prev) > 10800000) {     // intervallo tempo per i vari confronti

    if (p_slm < p_rif) {          // condizioni tempo in peggioramento
      if ((p_rif - p_slm >= 1) && (p_rif - p_slm <= 2)) {
        prev = 1; // partly cloudy/rain's cloudy
        p_rif = p_slm;
      }
      if ((p_rif - p_slm > 2) && (p_rif - p_slm <= 3)) {
        prev = 2; //rain light
        p_rif = p_slm;
      }
      if ((p_rif - p_slm >= 5) && (h > 70)) {
        prev = 3;   // thunderstorms
        p_rif = p_slm;
      }
      else if ((p_slm <1000) && (h > 70)) {             // blocco da eseguire se nessuna delle precedenti condizione è verificata
        prev = 1;   // partly cloudy/rain's cloudy
        p_rif = p_slm;
        }
    }
    if (p_slm > p_rif) {        // condizioni tempo in miglioramento
      if ((p_slm - p_rif >= 1) && (p_slm - p_rif <= 2)) {
        prev = 4;  //partly cloudy
        p_rif = p_slm;
      }
      if ((p_slm - p_rif > 2) && (p_slm - p_rif <= 3) && (h < 60)) {
        prev = 5; // sunny
        p_rif = p_slm;
      }
      else {                                            // blocco da eseguire se nessuna delle precedenti condizione è verificata
      if ((p_slm > 1001) && (p_slm <= 1015)) {             
        prev = 4; // partly cloudy
        p_rif = p_slm;
      }
      if ((p_slm > 1016) && (h < 60)) {
        prev = 5; // sunny
        p_rif = p_slm;
       }
     }
    }
    tempo_prev = millis();
  }
}

Sembra quasi che a molti le parentesi graffe aperte diano noia.
Per me ha molto più senso scrivere
if( test)
{
}

e non
if(test) {
}
SOPRATTUTTO per i nuovi.

nid69ita:
Sembra quasi che a molti le parentesi graffe aperte diano noia ...

... non l'ho capita ... le parntesi graffe ci sono in entrambi gli stili, e solo questione di abitudine, ma non vedo che differenza faccia mettere la graffa sulla stessa linea del IF o subito sotto ... ripeto, e solo questione di scelta dello stile usato.

Guglielmo

Per chi inizia è molto meglio lo stile con graffa sotto l'if (naturalmente con indentazione corretta)
Anche l'IDE di Arduino alla graffa chiusa ti evidenzia la graffa aperta.
E' solo questione di stile, ma secondo me è anche una questione di imparare a "contare" tot graffe aperte, tot graffe chiuse. Se sono su stessa colonna (quindi indentato per bene) è molto più difficile per i neofiti sbagliare.
Quindi viva Horstmann style !! (sarà che ho iniziato con il Pascal)

@Guglielmo, prendi il codice di @droid al post#8, fagli mettere le graffe aperte su riga successiva, CTRL+T e secondo me avrà un codice più leggibile (per lui)
Ovviamente è una mia opinione. Ma ho insegnato per un pò di anni e mi pare che lo stile Horstmann aiuta ai nuovi a fare meno errori.

Concordo

nid69ita:
Per chi inizia è molto meglio lo stile con graffa sotto l'if

... de gustibus non est disputandum ... preferisco lo stile K&R :smiley:

Guglielmo

Ragazzi a parte la forma che deriva anche dal fatto che stavo editando su un foglio note, ciò non toglie che mi avete fatto notare una cosa buona e giusta, per il resto ciò che ho scritto è più o meno giusto?

Grazie

droidprova:
per il resto ciò che ho scritto è più o meno giusto?

Come detto, a compilare può anche compilare, dipende da cosa tu voglia che il programma faccia in base alle condizioni.. E qui con nomi di variabili che possiamo solo immaginare a cosa servano, e con le varie combinazioni delle condizioni noi (quantomeno io) non è che riusciamo a dirti con certezza se funzioni o meno.

Ma, a parte il discorso giusto delle graffe, quando ci sono pezzi di codice con una logica non proprio semplice, consiglio sempre di iniziare scrivendo in linguaggio naturale dei commenti, che poi si traducono man mano nelle istruzioni.

Quindi per il tuo caso direi che se mettessi prima di ogni "if" un commento per spiegare cosa stai verificando (ossia qual è la condizione ricercata) già sarebbe un aiuto per tutti.

gpb01:
... de gustibus non est disputandum ... preferisco lo stile K&R :smiley:

Guglielmo

dove mi sono perso?
lo stile K&R è esattamente la graffa SOTTO
mi manca di leggere qualcosa?

Standardoil:
lo stile K&R è esattamente la graffa SOTTO

... e questa dove l'hai letta ? ? ? ... Prendi il K&R e guarda come scrive gli IF..ELSE .. pag 53:

If that isn't what you want, braces must be used to force the proper association:
if (n > 0) {
if (a > b)
z = a;
}
else
z = b;

Poi leggi anche QUI ...

The K&R style is commonly used in C, C++, and other curly brace programming languages. Used in Kernighan and Ritchie's book The C Programming Language, it had its origins in Kernighan and Plauger's The Elements of Programming Style.

When following K&R, each function has its opening brace at the next line on the same indentation level as its header, the statements within the braces are indented, and the closing brace at the end is on the same indentation level as the header of the function at a line of its own. The blocks inside a function, however, have their opening braces at the same line as their respective control statements; closing braces remain in a line of their own, unless followed by a keyword else or while.
...
The C Programming Language does not explicitly specify this style, though it is followed consistently throughout the book.

Direi che è il caso che riprendi in mano il K&R ... :smiling_imp:

Guglielmo

io non so che edizione del K& R hai, io comunque la prima e la seconda in inglese e la seconda in italiano, e sono tutte con la graffa SOTTO...
solitamente controllo prima di scrivere, come ho fatto un'ora fa
la pagine 53 della seconda edizione in inglese (ISBN 0-13-110370-9 PRENTICE HALL, Englewood Cliffs, New Jersey 07632) ha la tabella delle precedenze ed associatività.... di graffe mi sembra non ne parli
vedi tu, se vuoi ti mando la scansione....

Sì, però domani, che stasera viene la inganneressa nuova, quella dei raccordi rapidi...