Ricerca…


if () Dichiarazioni

Uno dei modi più semplici per controllare il flusso del programma è quello di utilizzare if istruzioni di selezione. Questa affermazione può decidere se un blocco di codice deve essere eseguito o non eseguito.

La sintassi per if dichiarazione selezione in C potrebbe essere la seguente:

if(cond) 
{
  statement(s);  /*to be executed, on condition being true*/
}

Per esempio,

if (a > 1) {
    puts("a is larger than 1");
}

Dove a > 1 è una condizione che deve essere valutata a true per eseguire le istruzioni all'interno del blocco if . In questo esempio "a è maggiore di 1" viene stampato solo se a > 1 è vero.

if istruzioni di selezione possono tralasciare le parentesi graffe { e } se c'è una sola affermazione all'interno del blocco. L'esempio sopra può essere riscritto a

if (a > 1)
    puts("a is larger than 1");

Tuttavia, per eseguire più istruzioni all'interno di un blocco, le parentesi devono essere utilizzate.

La condizione per if può includere più espressioni. if eseguirà l'azione solo se il risultato finale dell'espressione è vero.

Per esempio

if ((a > 1) && (b > 1)) {
    puts("a is larger than 1");
    a++;
}

eseguirà solo printf e a++ se sia a che b sono maggiori di 1 .

if () ... else istruzioni e sintassi

Mentre if esegue un'azione solo quando la sua condizione viene valutata su true , if / else consente di specificare le diverse azioni quando la condizione è true e quando la condizione è false .

Esempio:

if (a > 1)
    puts("a is larger than 1");
else 
    puts("a is not larger than 1");

Proprio come il if dichiarazione, quando il blocco all'interno di if o else è composto da una sola istruzione, quindi le parentesi graffe può essere omessa (ma così facendo non è raccomandato in quanto può facilmente introdurre problemi involontariamente). Tuttavia, se c'è più di un'istruzione nel blocco if o else , le parentesi devono essere utilizzate su quel particolare blocco.

if (a > 1) 
{
    puts("a is larger than 1");
    a--;
}
else 
{
    puts("a is not larger than 1");
    a++;
}

switch () Dichiarazioni

switch istruzioni switch sono utili quando si desidera che il programma esegua molte cose diverse in base al valore di una particolare variabile di test.

Un esempio di utilizzo dell'istruzione switch è simile a questo:

int a = 1;

switch (a) {
case 1:
    puts("a is 1");
    break;
case 2:
    puts("a is 2");
    break;
default:
    puts("a is neither 1 nor 2");
    break;
}

Questo esempio è equivalente a

int a = 1;

if (a == 1) {
    puts("a is 1");
} else if (a == 2) {
    puts("a is 2");
} else {
    puts("a is neither 1 nor 2");
}

Se il valore di a è 1 quando viene utilizzata l'istruzione switch , verrà stampato a is 1 . Se il valore di a è 2 allora, a is 2 verrà stampato. Altrimenti, a is neither 1 nor 2 verrà stampato a is neither 1 nor 2 .

case n: è usato per descrivere dove salterà il flusso di esecuzione quando il valore passato all'istruzione switch è n . n deve essere una costante in fase di compilazione e lo stesso n può esistere al massimo una volta in un'unica istruzione switch .

default: è usato per descrivere che quando il valore non corrisponde a nessuna delle scelte per il case n: È buona norma includere un caso default in ogni istruzione switch per rilevare comportamenti imprevisti.

Una break; è richiesta una dichiarazione per saltare fuori dal blocco switch .

Nota: se dimentichi accidentalmente di aggiungere break dopo la fine di un case , il compilatore presupporrà che intendi "fallire" e tutte le successive istruzioni caso, se presenti, verranno eseguite (a meno che non venga trovata un'istruzione break) uno qualsiasi dei casi successivi), indipendentemente dal fatto che le dichiarazioni dei casi susseguenti corrispondano o meno. Questa particolare proprietà viene utilizzata per implementare il dispositivo di Duff . Questo comportamento è spesso considerato un difetto nelle specifiche del linguaggio C.

Di seguito è riportato un esempio che mostra gli effetti dell'assenza di break; :

int a = 1;

switch (a) {
case 1:
case 2:
    puts("a is 1 or 2");
case 3:
    puts("a is 1, 2 or 3");
    break;
default:
    puts("a is neither 1, 2 nor 3");
    break;
}

Quando il valore di a è 1 o 2, a is 1 or 2 e a is 1, 2 or 3 saranno entrambi stampati. Quando a è 3, verrà stampato solo a is 1, 2 or 3 . Altrimenti, a is neither 1, 2 nor 3 stampato a is neither 1, 2 nor 3 .

Notare che il caso default non è necessario, specialmente quando il set di valori che si ottiene nello switch è finito e noto al momento della compilazione.

Il miglior esempio è usare un switch su un enum .

enum msg_type { ACK, PING, ERROR };
void f(enum msg_type t)
{
  switch (t) {
  case ACK:
    // do nothing
    break;
  case PING:
    // do something
    break;
  case ERROR:
    // do something else
    break;
  }
}

Ci sono molti vantaggi nel fare questo:

  • la maggior parte dei compilatori segnalerà un avviso se non si gestisce un valore (questo non verrebbe segnalato se fosse presente un caso default )
  • per lo stesso motivo, se aggiungi un nuovo valore enum , riceverai una notifica di tutti i luoghi in cui hai dimenticato di gestire il nuovo valore (con un caso default , avresti bisogno di esplorare manualmente il tuo codice alla ricerca di tali casi)
  • Il lettore non ha bisogno di capire "cosa è nascosto dal default: ", se esistono altri valori enum o se è una protezione per "just in case". E se ci sono altri valori di enum , il programmatore ha intenzionalmente usato il caso default o c'è un bug che è stato introdotto quando ha aggiunto il valore?
  • la gestione di ogni valore enum rende il codice auto esplicativo in quanto non è possibile nascondersi dietro una wild card, è necessario gestirne esplicitamente ciascuno.

Tuttavia, non puoi impedire a qualcuno di scrivere codice malvagio come:

enum msg_type t = (enum msg_type)666; // I'm evil

Quindi puoi aggiungere un controllo extra prima del tuo passaggio per rilevarlo, se davvero ne hai bisogno.

void f(enum msg_type t)
{
   if (!is_msg_type_valid(t)) {
      // Handle this unlikely error
   }

   switch(t) { 
    // Same code than before
   }
}

if () ... else Ladder Concatenare due o più if () ... else statements

Mentre l'istruzione if ()... else consente di definire solo un comportamento (predefinito) che si verifica quando la condizione all'interno di if () non viene soddisfatta, concatenando due o più if () ... else istruzioni consentono di definire una coppia più comportamenti prima di andare all'ultimo else ramo che funge da "default", se presenti.

Esempio:

int a = ... /* initialise to some value. */

if (a >= 1) 
{
    printf("a is greater than or equals 1.\n");
} 
else if (a == 0) //we already know that a is smaller than 1
{
    printf("a equals 0.\n");
}
else /* a is smaller than 1 and not equals 0, hence: */
{ 
    printf("a is negative.\n");
}

Nested if () ... else VS if () .. else Ladder

Nested if()...else istruzioni richiedono più tempo di esecuzione (sono più lente) rispetto a if()...else ladder perché le istruzioni nidificate if()...else controllano tutte le istruzioni condizionali interne una volta che l'esterno l'istruzione condizionale if() è soddisfatta, mentre if()..else ladder interrompe il test di condizione una volta che una delle istruzioni condizionali if() o else if() sono vere.

An if()...else ladder:

#include <stdio.h>

int main(int argc, char *argv[])
{
  int a, b, c;
  printf("\nEnter Three numbers = ");
  scanf("%d%d%d", &a, &b, &c);
  if ((a < b) && (a < c))
  {
    printf("\na = %d is the smallest.", a);
  }
  else if ((b < a) && (b < c))
  {
    printf("\nb = %d is the smallest.", b);
  }
  else if ((c < a) && (c < b))
  {
    printf("\nc = %d is the smallest.", c);
  }
  else
  {
    printf("\nImprove your coding logic");
  }
  return 0;
}

È, nel caso generale, considerato migliore del nidificato equivalente if()...else :

#include <stdio.h>

int main(int argc, char *argv[])
{
  int a, b, c;
  printf("\nEnter Three numbers = ");
  scanf("%d%d%d", &a, &b, &c);
  if (a < b)
  {
    if (a < c)
      {
        printf("\na = %d is the smallest.", a);
      }
    else
      {
        printf("\nc = %d is the smallest.", c);
      }
  }
  else
  {
    if(b < c)
    {
      printf("\nb = %d is the smallest.", b);
    }
    else
    {
      printf("\nc = %d is the smallest.", c);
    }
  }
  return 0;  
}


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow