Lezione 02 – corso di programmazione in C

In questa lezione:

  • soluzione ai problemi assegnati
  • operatori di uguaglianza e confronto
  • operatori logici
  • uso del costrutto condizionale if
  • uso del costrutto condizionale if…then
  • uso del costrutto condizionale switch
  • esercizi


Soluzione ai problemi assegnati nella lezione precedente

Per poter risolvere gli esercizi era necessario utilizzare le nozioni spiegate nella precedente lezione più alcune informazioni aggiuntive che avreste potuto ottenere consultando i manuali consigliati.

Esercizio 1

/* Nome: calcolatrice
   Scopo: compiere le 4 operazioni tra due numeri reali inseriti da tastiera

          X+Y
          X-Y
          X*Y
          X/Y (ipotizzando che Y sia diverso da 0)

   Autore: Michele Maffucci
   Data creazione: 06.10.2012
*/

#include <stdio.h>
#include <stdlib.h>

/* la funzione main è il punto di inizio */

int main (void) {

	float x, y ; /* numeri inserito */
	float somma, differenza, prodotto, quoziente; /* variabili in cui inserire il risultato dell'operazione */

	printf("-- Calcolatrice\n\n ---") ; /* stampa cosa eseguira' il programma */

    /* --- leggiamo i due numeri --- */

    printf("Inserisci il primo numero: ") ; /* legge il primo numero */
	scanf("%f", &x);

	printf("Inserisci il secondo numero: ") ; /* legge il secondo numero */
	scanf("%f", &y);

	/* --- calcola la SOMMA --- */

	somma = x + y ;

	/* --- calcola la DIFFERENZA --- */

	differenza = x - y ;

	/* --- calcola il PRODOTTO --- */

	prodotto = x * y ;

	/* --- calcola il QUOZIENTE --- */

	quoziente = x / y ;

	/* --- stampa il risultato delle operazioni --- */

	printf("----------------------------------------------------\n\n") ;
	printf("I numeri inseriti sono %f e %f:\n", x, y);
	printf("La somma e'%f\n", somma);
	printf("La differenza e'%f\n", differenza);
	printf("Il prodotto e'%f\n", prodotto);
	printf("Il quoziente e'%f\n", quoziente);

    return 0; /* indica che l'esecuzione è terminata con successo */
}
/* fine della funzione main */

Esercizio 2

/* Nome: calcolo area
   Scopo: scrivere un programma che dato un numero reale X inserito da tastiera calcoli e stampi:

          l’area del quadrato di lato X
          l’area del triangolo equilatero di lato X
          l’area del cerchio di diametro X

   Autore: Michele Maffucci
   Data creazione: 06.10.2012
*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/* la funzione main è il punto di inizio */

int main (void) {

	float x ;                                 /* numero inserito */
	float a_quadrato, a_cerchio, a_triangolo; /* area quadrato, cerchio, triangolo */
	float raggio ;                            /* raggio del cerchio */
	float costante ;                          /* costante pari a radice(3)/4 */

	costante = sqrt(3) / 4 ;

    printf("CALCOLO DELLE AREE\n");        /* stampa cosa eseguira' il programma */
    printf("Inserisci il valore di X: ") ; /* legge il numero */
    scanf("%f", &x);

	/* --- calcola l'area del quadrato di lato X --- */

	a_quadrato = x * x ;

	/* poiche' includiamo la libreria math.h possiamo utilizzare anche la funzione
	pow(base, esponente) e quindi scrivere anche:

	a_quadrato = pow(x,2);

	*/

	/* --- calcola l'area del cerchio di diametro X --- */

	raggio = x/2; /* calcola il raggio del cerchio */

	a_cerchio = M_PI*(raggio*raggio); /* calcola l'area del cerchio */
	/* il valore di PI greco e’ definito nella libreria math.h come M_PI */

	/* soluzione alternativa per il calcolo dell'area del cerchio:

	a_cerchio = M_PI * pow(raggio, 2) ;

	*/

	/* --- calcola l'area del triangolo equilatero avente lato X --- */

	a_triangolo = costante * ( x * x );

	/* soluzione alternativa per il calcolo dell'area del triangolo:

	a_triangolo = costante * pow( x, 2 );

	*/

	/* --- stampa i risultati ---*/
	printf("\n") ;
	printf("Le aree calcolate sono:\n") ;
	printf("Area del quadrato di lato %f = %f\n", x, a_quadrato);
	printf("Area del cerchio di diametro %f = %f\n",x, a_cerchio);
	printf("Area del triangolo equilatero di lato %f = %f\n", x, a_triangolo);

    return 0; /* indica che l'esecuzione è terminata con successo */
}
/* fine della funzione main */

Nota di carattere geometrico: ma da dove si deriva la costante per il calcolo dell’area del triangolo equilatero?

...
float costante ;  /* costante pari a radice(3)/4 */

costante = sqrt(3) / 4 ;
...

supposta nota la lunghezza del lato del triangolo equilatero e applicando il teorema di Pitagora si ottiene:

Operatori di uguaglianza e confronto

Le istruzioni eseguite in C possono compiere delle azioni (ad esempio fare dei calcoli od effettuare la stampa di qualcosa a monitor) oppure prendere delle decisioni.

Detto in altro modo, i programmi che realizziamo hanno la necessità di  scegliere una strada invece che un’altra  in funzione di una condizione e quindi per prendere delle decisione abbiamo bisogno di utilizzare degli operatori di confronto.

Gli operatori di confronto sono operatori a due argomenti e si dice che hanno sempre posizione infissa, cioè sono inseriti tra due argomenti.

Simbolo di relazione Significato di condizione Esempio di condizione
== uguale a x == y
!= diverso da x != y
< minore x < y
> maggiore x > y
<= minore o uguale x <= y
>= maggiore o uguale x >= y

Gli operatori:

  • ==
  • !=

sono detti operatori di uguaglianza.

Gli operatori:

  • <
  • >
  • <=
  • >=

sono detti operatori di confronto.

Priorità e associazione degli operatori di uguaglianza e confronto

  • Gli operatori di relazione hanno tutti lo stesso livello di priorità e associano da sinistra a destra.
  • Gli operatori di uguaglianza hanno livello più basso degli operatori di relazione e associano da sinistra a destra.

Operatori logici

Anche gli operatori logici sono utilizzati con istruzioni condizionali ed iterative, consentono di effettuare l’AND e l’OR tra due operandi. Le operazioni logiche restituiscono 1 quando sono vere e 0 quando sono false:

Simbolo logico Significato logico Esempio relazione logica
&& AND logico x && y
|| OR logico x || y

Per quanto riguarda l’AND e l’OR le tavole di verità sono le seguenti:

AND logico:

X Y X AND Y
0 0 0
0 1 0
1 0 0
1 1 1

OR logico

X Y X OR Y
0 0 0
0 1 1
1 0 1
1 1 1

Strutture di controllo

if

Supponiamo di voler realizzare un semplicissimo programma che decide in base alla media dei voti di uno studente, se l’allievo risulta promosso, questo tipo di decisione può essere presa con un costrutto condizionale.

Utilizziamo uno pseudo-codice per descrivere questo tipo di operazione:

/* porzione di pseudo-codice per decidere se promuovere un allievo */

SE media e' maggiore o uguale a 6
ALLORA
   promosso

nello pseudo-codice abbiamo un controllo su “media” quindi possiamo pensare “media” come ad una variabile. andando avanti nella lettura troviamo “e’ maggiore o uguale a“, ma per quanto detto precedentemente  “e’ maggiore o uguale a” è tradotto in “>=” che come detto è un operatore di confronto. Traducendo abbiamo:

SE media >= 6 ALLORA
   promosso

Inseriamo un po’ di parentesi per mettere in evidenza le parti del codice, useremo le parentesi graffe per racchiudere blocchi di codice, in qiuesto caso metteremo tra parentesi graffe la parola “promosso”. Utilizziamo le parentesi tonde per evidenziare la condizione di controllo:

SE (media >= 6) ALLORA
   {
     promosso
   }

Per avvicinarci al linguaggio C, sostituiamo alle parole in italiane le corrispondenti parole in inglesi:

if (media >= 6) then
   {
     promosso
   }

Ma per essere aderenti all’ANSI C bisogna fare un passo successivo molto semplice: eliminare la parola then, ottenendo:

if (media >= 6)
   {
     promosso
   }

a questo punto se vogliamo stampare la parola “promosso” sappiamo che dobbiamo utilizzare la funzione printf():

if (media >= 6)
   {
     printf("promosso\n");
   }

e questo che avete ottenuto è il costrutto if

Breve trattazione teorica

Riprendo quanto già spiegato negli: Appunti di programmazione su Arduino: controllo di flusso (ripeto ricopiando in parte):

L’istruzione if è composta da un blocco “condizione” che verifica se una deterniata condizione logica si verifica. Se la “condizione” risulta “Vera“, viene eseguita un blocco “istruzioni“, se la “condizione” risulta “Falsa“, non viene eseguito il blocco “istruzioni” e l’esecuzione del programma prosegue oltre l’istruzione if.

In altro modo, se la condizione di controllo, costituita ad esempio dal confronto di due valori, risulta vera, verrà eseguito il codice incluso tra le parentesi graffe che seguono il controllo, altrimenti se la condizione di controllo risulta falsa, non vengono eseguite le istruzioni dell’if  e l’esecuzione del programma continua con la porzione di codice che segue.

if (someVariable ?? value)
{
   doSomething;
}

(con ?? indichiamo l’operatore di uguaglianza o relazione usato dalla condizione di controllo)

L’esempio sopra confronta la variabile someVariable con il valore contenuto in value che può essere una variabile o una costante. Se il confronto o la condizione all’interno delle parentesi tonde risulta vera, verrà eseguita la porzione di codice inclusa tra le parentesi graffe, doSomething, altrimenti se la condizione risulta falsa viene saltata la porzione tra parentesi graffe e l’esecuzione prosegue dopo l’ultima parentesi graffa.

Nota: fate attenzione che se accidentalmente usate ‘=’, ad esempio if(x=10), tecnicamente è un’operazione valida, l’operazione assegna alla variabile x il valore 10 che è un’operazione sempre vera, quindi il programma si comporterà diversamente da come avevamo progettato. Invece se usiamo “==” (doppio uguale) in if(x==10) viene verificato se la variabile x è uguale al numero 10.

Pensate a “=” come ad un’operazione di assegnamento e “==” come ad una operazione di confronto (“è uguale a”).

Esempio pratico

Per comprendere l’uso degli operatori logici e del comando di selezione if realizziamo un programma che confronta due numeri interi:

/* Nome: confronto tra due numeri interi
   Scopo: comprendere l'uso degli operatori di uguaglianza e confronto
   Autore: Michele Maffucci
   Data creazione: 09.10.2013
*/

#include <stdio.h> 

int main( void )
{
   int nunero1; /* primo numero da inserire  */
   int numero2; /* secondo numero da inserire */

   printf( "Inserisci due numeri interi ed io ti\n" );
   printf( "diro' che relazione intercorre: " );

   scanf( "%d%d", &numero1, &numero2 ); /* legge i due numeri interi */

   if ( numero1 == numero2 ) { 
      printf( "%d e' uguale a %d\n", numero1, numero2 );
   } /* fine dell'if */

   if ( numero1 != numero2 ) {
      printf( "%d e' diverso da %d\n", numero1, numero2 );
   } /* fine dell'if */

   if ( numero1 < numero2 ) {        printf( "%d e' minore di %d\n", numero1, numero2 );    } /* fine dell'if */    if ( numero1 > numero2 ) { 
      printf( "%d e' maggiore di %d\n", numero1, numero2 );
   } /* fine dell'if */

   if ( numero1 = numero2 ) {
      printf( "%d e' maggiore o uguale a %d\n", numero1, numero2 );
   } /* fine dell'if */

   return 0;
}

Riprendiamo l’analisi del programma precedente:

   ...
   if ( numero1 == numero2 ) { 
      printf( "%d e' uguale a %d\n", numero1, numero2 );
   } /* fine dell'if */
   ...

l’if verifica se i due numeri sono uguali, se la condizione tra parentesi tonde risulta vera allora viene eseguita l’operazione tra parentesi graffe ovvero viene stampato (assumendo che i due numeri siano uguali a 7)

7 e' uguale a 7

In caso contrario se la condizione non risulta vera non viene eseguita l’operazine tra parentesi graffe ed il controllo passa all’istruzione successiva.

In modo del tutto analogo vengono eseguiti i successivi if.

 Esempio pratico

Realizziamo un programma che stampa il maggiore dei due numeri inseriti.

/* Nome: maggiore tra due numeri
   Scopo: dati due numeri ne stampa il maggiore
   Autore: Michele Maffucci
   Data creazione: 09.10.2013
*/

#include <stdio.h> 

int main( void )
{
   int nunero1; /* primo numero da inserire  */
   int numero2; /* secondo numero da inserire */
   int temporaneo; /* variabile temporanea */

   scanf( "%d", &numero1 ); /* legge il primo numero */
   scanf( "%d", &numero2 ); /* legge il secondo numero */

   if ( numero1 > numero2 ) { 
      temporaneo = numero1;
      numero1 = numero2;
      numero2 = temporaneo;
   } /* fine dell'if */

   printf( "%d\n", numero2 );

   } /* fine dell'if */

   return 0;
}

Analizziamo il programma.
Se numero1 è >= a  numero2. Altrimenti se numero1 è > di numero2 scambia i valori di numero1 e numero2 (passando il valore attraverso la variabile “temporaneo“) e poi stampa numero2, ossia quello che prima era numero1.

if…else

Vogliamo realizzare un programma che stampa “promosso” se la media dei voti di uno studente è maggiore o uguale a  6 e  stampa “bocciato” se la media dei voti è minore di 6.

Anche in questo caso utilizziamo lo pseudo-codice:

/* porzione di pseudo-codice per decidere se promuovere un allievo */

SE media e' maggiore o uguale a 6
ALLORA
   visualizza "promosso"
ALTRIMENTI
   visualizza "bocciato"

Agiamo passo passo come fatto in precedenza per l’if.

sostituiamo la grase “e’ maggiore o uguale a” con “>=” ed evidenziamo con parentesi tonde le condizioni e con le graffe le porzioni di codice:

/* porzione di pseudo-codice per decidere se promuovere un allievo */

SE (media >= 6)
ALLORA {
   visualizza "promosso"
}
ALTRIMENTI {
   visualizza "bocciato"
}

traduciamo in inglese:

/* porzione di pseudo-codice per decidere se promuovere un allievo */

if (media >= 6)
then {
   visualizza "promosso"
}
else {
   visualizza "bocciato"
}

Come detto in ANSI C la parola then si omette e quindi, sostituendo all’azione “visualizza” con la rispettiva funzione C printf(), otteniamo:

if (media >= 6) {
   printf("promosso\n");
} /* fine del corpo dell'if */
else {
   printf("bocciato"\n");
} /* fine del corpo dell'else */

il diagramma che segue illustra il flusso di controllo per l’istruzione “if…else“:

Breve trattazione teorica

Come rappresentato dal diagramma di flusso che segue, la struttura if…else è composta da tre sezioni, la prima è costituita da un blocco “condizione” che controlla il verificarsi di una determinata condizione logica, se la condizione risulta “Vera” viene eseguito il blocco “istruzioni” altrimenti, se “Falso” viene eseguito il blocco “altre istruzioni

La condizione logica da verificare è inclusa tra parentesi tonde. Il ramo che viene eseguito nel caso di risultato “Vero” è racchiuso tra il primo gruppo di parentesi graffe, mentre il secondo gruppo di codice, incluso tra le parentesi graffe dopo l’istruzione “else“, viene eseguito se “condizione” risulta “Falso“:

if (inputPin == HIGH)
{
   doThingA;
}
else
{
   doThingB;
}

Nota: una istruzione if verifica semplicemente se la condizione all’interno delle parentesi tonde è vera o falsa. Nell’esempio, se if (inputPin == HIGH) risulta vera, viene eseguita la porzione di codice doTingA, in caso contrario viene eseguita la porzione di codice che segue l’elsedoThingB

L’else può anche precedere altre istruzioni if e test mutualmente esclusivi possono essere eseguiti nello stesso momento. Quindi potrete avere molte istruzioni if annidate.
Potete avere un numero illimitato di rami else. Ricordate che in funzione del valore logico del blocco di controllo, solo un insieme di istruzioni verrà eseguito.

if (inputPin < 500)
{
   doThingA;
}
else if (inputPin >= 1000)
{
   doThingB;
}
else
{
   doThingC;
}

Esempio pratico

Realizzare nuovamente il programma che stampa il maggiore dei due numeri inseriti uisando il costrutto if…else:

/* Nome: maggiore tra due numeri
   Scopo: dati due numeri ne stampa il maggiore
   Autore: Michele Maffucci
   Data creazione: 09.10.2013
*/

#include <stdio.h>
int main( void )
{
   int nunero1; /* primo numero da inserire  */
   int numero2; /* secondo numero da inserire */

   scanf( "%d", &numero1 ); /* legge il primo numero */
   scanf( "%d", &numero2 ); /* legge il secondo numero */

   if ( numero1 > numero2 ) { 
      printf("%d\n", numero1);
   }
   else
   {
      printf("%d\n", numero2 );
   } /* fine dell'if */

   return 0;
}

Esempio pratico

Realizzare un programma che acquisisce un numero da tastiera e stampa un messaggio che indica se il numero è positivo o negativo:

/* Nome: segno del numero
   Scopo: verificare se il numero e' negativo
   Autore: Michele Maffucci
   Data creazione: 09.10.2013
*/

#include <stdio.h>
#include <stdlib.h>

int main( void )
{
   int nunero; /* numero inserito  */

   printf( "Inserisci il numero: ");
   scanf( "%d", &numero ); /* legge il numero */

   if ( numero >= 0 ) {
   /* il numero e' positivo o nullo */
      printf("il numero %d e' positivo o nullo\n", numero);
   }
   else
   {
   /* il numero e' negativo */
      printf("il numero %d e' negativo\n", numero );
   }
   return 0;
}

Esercizio 1

Realizzare un programma che legga un numero inserito da tastiera e ne stampi il valore assoluto.

Esercizio 2

Realizzare un programma che legga due numeri inseriti da tastiera, detti X e Y, restituisca a monitor le seguenti informazioni:

  • determinare se Y è un numero positivo o negativo
  • determinare se X è un numero pari o dispari
  • calcoli il valore di X + Y
  • determinare quale scelta dei segni (±X) + (±Y) porta al risultato massimo e quale è il valore massimo.

Esercizio 3

Scrivere un programma che legga da tastiera i valori delle lunghezze dei tre lati di un triangolo (detti X, Y, Z) e determini:

  • se il triangolo è equilatero
  • se il triangolo è isoscele
  • se il triangolo è scaleno
  • se il triangolo è rettangolo

switch

Abbiamo visto che in C possiamo utilizzare il comando di selezione singola if e quello di selezione multipla if…else.
Potrebbe però esserci la necessità che una variabile o una espressione debba essere confrontata con una serie di valori che la variabile o l’espressione potrebbe assumere e che, a seconda del risultato del confronto, vengano intraprese delle azioni diverse. Questo tipo di selezione è chiamato switch (interruttore) e serve per gestire una serie di decisioni.

switch (variabile)
{
       case 1:
              istruzione1;
              break;
       case 2:
              istruzione2;
              break;
       .
       .
       .
       case 12:
              istruzione12;
              break;
       default:
              istruzioneDefault;
              break;
}

La prima operazione che viene eseguita è quella di verificare il valore della variabile, in funzione del valore assunto da “variabile” si entra nel ramo “case” corretto, se per esempio il valore di “variabile” è 2, viene eseguita “istruzione2“, che può anche essere una lista di istruzioni, al termine viene eseguito il “break”, cioè termina l’esecuzione dello switch e l’esecuzione del programma prosegue dopo la graffa di chiusura dello switch.

Se il valore non è nessuno di quelli elencati viene eseguito il ramo “default”.

Esempio pratico

Dato un numero intero tra 1 e 12, che rappresenta il mese, stampare il nome per esteso del mese (“gennaio”, “febbraio”… “dicembre”).

/* Nome: mese
   Scopo: dato un numero da 1 a 12 stampare il mese corrispondente 
   Autore: Michele Maffucci
   Data creazione: 09.10.2013
*/

#include <stdio.h>
#include <stdlib.h>

int main( void )
{
   int mese; /* mese inserito  */
   /* legge il numero del mese */
   printf( "Inserire il numero del mese: ");
   scanf( "%d", &mese ); /* legge il mese */

   /* visualizza il nome del mese corrispondente al numero */
   case (mese)
   {
      case 1:
         printf("gennaio\n");
         break;
      case 2:
         printf("febbraio\n");
         break;
      case 3:
         printf("marzo\n");
         break;
      case 4:
         printf("aprile\n");
         break;
      case 5:
         printf("maggio\n");
         break;
      case 6:
         printf("giugno\n");
         break;
      case 7:
         printf("luglio\n");
         break;
      case 8:
         printf("agosto\n");
         break;
      case 9:
         printf("settembre\n");
         break;
      case 10:
         printf("ottombre\n");
         break;
      case 11:
         printf("novembre\n");
         break;
      case 12:
         printf("dicembre\n");
         break;
      default:
         printf("Valore inserito scorretto!\n");
         break;
   }
return 0;
}

Esercizio 4

Utilizzando l’istruzione switch, scrivere un programma che realizza una semplice calcolatrice in grado di compiere le 4 operazioni tra numeri interi. Realizzare un menù di scelta dove l’utente indica con un numero (da 1 a 4) l’operazione da eseguire, successivamente il programma dovrà leggere i due operandi e restituire il risultato.dell’operazione scelta dall’utente.

Questa voce è stata pubblicata in i miei allievi, programmazione e contrassegnata con , , , , , , , , , , . Contrassegna il permalink.

5 risposte a Lezione 02 – corso di programmazione in C

  1. Umberto scrive:

    Ciao , sto seguendo con molto interesse le tue lezioni di programmazione in c, sono molto utili e mi stanno facendo imparare in fretta 😀 .Sei un grande!!!

    Volevo sapere quando sara’ disponibile la Lezione 03.
    Aspetto fiducioso la soluzione degli esercizi e non vedo l’ora di imparare qualcosa di nuovo .

  2. Silvio scrive:

    Salve, stò seguendo anche io con molto interesse le sue lezioni, però dove posso consultare le altre lezioni, perchè nel sito arriva fino al “lezione 02”? O almeno un consiglio dove poter imparare in fretta il C?

    • admin scrive:

      Ciao Silvio. Si hai ragione non ho messo online le altre lezioni perché attualmente sono solo in modalità slide per le mie classi. Cerco di metterle online, in ogni caso se non riesco nel breve ti lascio un commento con tutti i link che possono esserti di aiuto. Nel mentre vai sul sito di mia sorella che insegna informatica ha un sito che utilizza esclusivamente per i suoi studenti, il link è http://www.maffucci.cc spero possa esserti di aiuto.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.