Sei sulla pagina 1di 40

Linguaggio C

(Istruzioni del Linguaggio)

Indice Lezioni Linguaggio C


! Tipi di dato primitivi e Operatori

! Dichiarazioni

! Espressioni

•  Istruzioni

•  Tipi di dato strutturati

•  Funzioni

Istruzioni 2
Programmazione strutturata
•  [Teorema di Böhm-Jacopini] Un algoritmo descritto da un
diagramma di flusso qualsiasi può essere implementato, in
modo equivalente, usando le tre sole strutture di controllo
1.  Struttura sequenza
2.  Struttura alternativa (if_then_else)
3.  Struttura iterativa (while_do)

•  In un programma strutturato queste sono le strutture


fondamentali, anche se normalmente si usano altre strutture
quali ad esempio il do_while
•  In un programma strutturato manca l’istruzione di salto
incondizionato GO-TO

Programmazione strutturata in C

•  Struttura sequenza - Istruzioni composte


–  sequenza di istruzioni racchiusa in un blocco ! { }

•  Struttura alternativa - Istruzioni condizionali


–  scelta (semplice o alternativa)! if (), if () else
–  scelta multipla ! switch ()

•  Struttura iterativa - Istruzioni iterative


–  ciclo ! while (), do while (), for ( ; ; )

Istruzioni 4
Istruzioni semplici
Qualsiasi espressione (logica, condizionale,
assegnamento) seguita da un ; è un istruzione
(semplice)

ESEMPI
x = 0; y = 1; /* due istruzioni */

k++; /* una sola istruzione */

3; /* non fa nulla */

; /* istruzione nulla */

Istruzioni 5

Blocco
<blocco> ::=
{
[ <dichiarazioni > ]
{ <istruzioni> }
}

•  dopo un blocco non occorre il punto e virgola (esso


termina le istruzioni semplici, non separa istruzioni)
•  i blocchi possono essere innestati
•  il campo d’azione delle <dichiarazioni > che compaiono
entro il blocco è il blocco stesso
" verrà studiato con la visibilità delle variabili
Istruzioni 6
Esempio (blocco)
Data una temperatura in ingresso, espressa in gradi Celsius o
Fahrenheit, calcolare il corrispondente valore espresso rispettivamente in
gradi Fahrenheit o Celsius.
Le relazioni tra le grandezze: c * 9/5 = f – 32
c = (f - 32) * 5/9
f = 32 + c * 9/5
#include <stdio.h>
main()
{ /* INIZIO BLOCCO */
const float F1=9.0, F2=5.0, SH=32;
float temp_inp, temp_out;
char scala;
scanf("%f", &temp_inp);
scanf("%c", &scala);
temp_out = (scala == 'C') ?
(SH + temp_inp * F1 / F2) : (F2 / F1 * (temp_inp - SH)) ;
printf ("%f\n", temp_out);
} /* FINE BLOCCO */
Istruzioni 7

Esempio (blocco innestato)


#include <stdio.h>
main() Il campo d azione della
{ /* INIZIO BLOCCO */ variabile scala è limitato
al blocco più interno
const float F1=9.0, F2=5.0, SH=32;
in cui scala è dichiarata.
float temp_inp, temp_out;
scanf( %f , &temp_inp); La variabile scala non è
{ /* INIZIO BLOCCO INTERNO */ più visibile
char scala; (e neppure esistente!)
scanf( %c , &scala); dopo la } che chiude il
temp_out = (scala == C') ? blocco interno
(SH + temp_inp * F1 / F2)
: (F2 / F1 * (temp_inp - SH)) ;
} /* FINE BLOCCO INTERNO */
printf ("%f\n", temp_out);
} /* FINE BLOCCO */

Istruzioni 8
Esercizio
•  Specifica: Inverti l ordine delle cifre che formano un intero
positivo compreso fra 100 e 999.
–  Per esempio: 234 ! 432
•  Algoritmo: Utilizzare le operazioni di modulo e di divisione fra
numeri interi. Dato un numero, valgono le seguenti relazioni:
–  Unita = (numero)%10;
o  Es., 234%10 = 4

–  Decine = (numero/10)%10;
o  Es., (244/10)%10 = 3

–  Centinaia = (numero/100)%10;
o  Es., (234/100)%10 = 2

Istruzioni 9

Esercizio - Programma
#include <stdio.h>
main(){
int numero;
int unita, decine, centinaia, risultato;

scanf("%d", &numero);

unita = numero % 10;


numero = numero / 10;
decine = numero % 10;
numero = numero / 10;
centinaia= numero % 10;
risultato =unita*100+decine*10+centinaia;

printf("%d", risultato);
}

Istruzioni 10
Esercizio
•  Scrivere un programma che effettua lo scambio dei valori
di due variabili
main(){
int a=10,b=2;
a=b; a 10 2
b=a;
} b 2 2
•  Questo programma non può funzionare!!

Istruzioni 11

Esercizio (cont.)

•  Serve una variabile ausiliaria (temp) dove salvare il valore


della variabile che viene sovrascritta per prima per poi
assegnarlo alla seconda variabile
2
a b
1 3
main(){ temp
int a=10,b=2,temp; a 10 2
temp=a
a=b; b 2 10
b=temp;
} temp ? 10
Istruzioni 12
Esercizio
Scrivere un programma che, dati hh:mm:ss di inizio viaggio e
il tempo di percorrenza in secondi, calcoli l’arrivo nella forma
hh:mm:ss.
#include <stdio.h>
main ()
{ int ore, minuti, secondi, tempov;

printf("ore: "); scanf("%d",&ore); 10


printf("minuti: "); scanf("%d",&minuti); 21
printf("secondi:"); scanf("%d",&secondi); 37
printf("tempo in secondi:"); scanf("%d",&tempov); 23678
secondi = secondi+tempov; printf("%d\n",secondi); 23715
minuti = minuti+secondi/60; printf("%d\n",minuti); 416
secondi = secondi % 60; printf("%d\n",secondi); 15
ore = ore + minuti / 60; printf("%d\n",ore); 16
minuti = minuti % 60; printf("%d\n",minuti); 56
ore = ore % 24; printf("%d\n",ore); 16
}
Istruzioni 13

Esercizio
Scrivere un programma per il calcolo del resto per macchine
per pagamenti automatici.

•  Si supponga che la macchina disponga di un numero


illimitato di monete da ! 1 e ! 2 e di banconote da ! 5.
•  Il programma riceve in input la cifra spesa e quella inserita
dal cliente per il pagamento. Entrambi i valori sono interi.
•  Il programma deve stampare la composizione del resto
(ovvero quanti pezzi da !1,!2,!5) che si realizza col minor
numero di pezzi.

Istruzioni
14
Esercizio (Programma)

#include <stdio.h> resto = contanti - spesa;


#define moneta1 1 pezzi3 = resto/moneta3;
#define moneta2 2 resto = resto % moneta3;
#define moneta3 5 pezzi2 = resto/moneta2;
resto = resto%moneta2;
pezzi1 = resto/moneta1;
int main(void) {
printf("Composizione del
int spesa, contanti,resto; resto\n");
int pezzi1,pezzi2,pezzi3; printf("pezzi da ! %d: %d
\n",moneta1,pezzi1);
printf("Cifra spesa: "); printf("pezzi da ! %d: %d
\n",moneta2,pezzi2);
scanf("%d",&spesa);
printf("pezzi da ! %d:
printf("Cifra inserita:"); %d",moneta3,pezzi3);
scanf("%d",&contanti); }

Istruzioni 15

Struttura Alternativa - Istruzioni condizionali


Sono disponibili due tipi di istruzioni condizionali:
1.  Istruzione di SCELTA (semplice o alternativa)
2.  Istruzione di SCELTA MULTIPLA
non è essenziale, ma migliora l’espressività del linguaggio, cioè
la semplicità con la quale si riescono a codificare gli algoritmi

•  L espressione condizionale <cond> ? <espr1> : <espr2>


fornisce già un modo per esprimere il concetto di alternativa,
però ha un’espressività limitata : diviene praticamente illeggibile
appena la complessità del problema aumenta (anche di poco)

•  Le istruzioni condizionali forniscono un più alto livello di


espressività, comprensibilità e leggibilità.

Istruzioni 16
Istruzione di scelta (semplice o alternativa)
•  Consente di scegliere fra due istruzioni alternative in
base al verificarsi di una condizione

<istruzione-di-scelta> ::=
if (condizione) < istruzione1>
[ else < istruzione2> ] Opzionale

•  Condizione è un’espressione logica che viene valutata al momento


dell’esecuzione dell’istruzione if
•  Se condizione risulta vera si esegue <istruzione1>, altrimenti si
esegue <istruzione2>
•  In entrambi i casi l’esecuzione continua poi con l istruzione che segue
l’istruzione if; quindi se condizione è falsa e la parte else (opzionale)
è omessa, si passa subito all’istruzione che segue l’istruzione if.

Istruzioni 17

Istruzione di scelta : osservazioni


•  Secondo la sintassi, <istruzione1> e <istruzione2> sono
ciascuna una singola istruzione
•  Per specificare più istruzioni, si dovrà quindi utilizzare un blocco
if (n > 0)
{ /* inizio blocco */
a = b + 5;
c = x + a - b;
} /* fine blocco */
else
n = b*5;

Attenzione: non mettere ; in questo punto!


il ; termina l’istruzione if quindi risulterebbe
un else senza if : errore sintattico

Istruzioni 18
Istruzioni if annidate
•  <istruzione1> o <istruzione2> potrebbero essere
un’altra <istruzione-di-scelta>
•  In questo caso occorre fare attenzione ad associare le
parti else (che sono opzionali) all’ if corretto
In base alla sintassi del linguaggio C, l else è sempre
associato all if più interno
Se questo comportamento non soddisfa o crea ambiguità,
occorre inserire esplicitamente un blocco

if (n > 0)
? if (a>b) n = a;
else n = b*5; /* else riferito a if (a>b) */

if (n > 0)
{ if (a>b) n = a; }
else n = b*5; /* else riferito a if (n>0) */
Istruzioni 19

Istruzioni if annidate: alcuni casi

Istruzioni 20
Istruzioni if annidate: alcuni esempi
n (prima) a b n (dopo) ?
if (n > 0)
10 11 5
if (a>b) n = a;
else n = b*5; 10 11 12
-10 11 5
-10 11 12

n (prima) a b n (dopo) ?
if (n > 0)
{ if (a>b) n = a; } 10 11 5
else n = b*5; 10 11 12
-10 11 5
-10 11 12

Istruzioni 21

Esempio
Data una temperatura in ingresso, espressa in gradi Celsius o Fahrenheit, calcolare il
corrispondente valore espresso rispettivamente in gradi Fahrenheit o Celsius
#include <stdio.h>
main()
{
const float F1=9.0, F2=5.0, SH=32;
float temp_inp, temp_out;
char scala;
printf("inserire temperatura e scala (C o F):");
scanf("%f", &temp_inp); fflush(stdin);
scanf("%c", &scala);
if (scala == 'C')
temp_out = (SH + temp_inp * F1 / F2);
else
temp_out = (F2 / F1 * (temp_inp - SH));
printf ("%f\n", temp_out);
}
Istruzioni 22
Esempio
Dato il seguente frammento di codice indicare il valore delle variabili al
termine dell'esecuzione.
Notare come l'indentazione sia molto utile per esprimere al meglio la
struttura di un programma e quindi per migliorare la sua leggibilità.

int a=2,b=-1; int a=2,b=-1;


if ( ((b*b)%2) != (a+3) ) { if ( ((b*b)%2) != (a+3) )
if ((a = -(b-2)%3) != b+1) {
if ((a = -(b-2)%3) != b+1)
b= (b-1)/2+a++; }
else { b= (b-1)/2+a++;
}
if (a = b+1)
else
if(a%2==0)
{
b= (b-1)/2+a++;
else a += (b-1)/2; } if (a = b+1)
if(a%2==0)
b= (b-1)/2+a++;
else a += (b-1)/2;
}
Istruzioni 23

Esercizio
Dato il seguente programma indicare il valore delle variabili a, b, c
e f al termine di ogni istruzione:
(NB: compilare solo le risposte di fianco alle istruzioni
effettivamente eseguite)

int a=3, b=1, c=2; float f=0.0;

a+ = ++b*c; a= b= c= f=

if(b>2) b=c-=a;
else b=c+=2; a= b= c= f=

f = a+b+c / 3; a= b= c= f=

Istruzioni 24
Esercizio

Dato il seguente frammento di codice indicare il valore


delle variabili al termine dell'esecuzione.
int a=3,b=2;
if (((b*b+1)%2)==(a-2)) {
a = (b-1)%3;
b -= a*a;}
else
a = (b+1)/2;
b -= a;

a = b =

Istruzioni 25

Esercizio
Cosa stampa il seguente frammento di programma con i valori delle
variabili specificati ?
int stampa=0;
if ((b && d) || c) stampa = 2;
else if ((b||c) && (!b && a)) stampa = 1;
else if (! (c&&d) && (!b || c)) stampa = 2;
if (stampa) printf ("%d", stampa++); else printf("stampa");

a=0, b=1, c=1, d=0 ____________________

a=1, b=0, c=0, d=0 ____________________

a=1, b=1, c=0, d=0 ____________________

a=0, b=0, c=0, d=0 ____________________

a=1, b=1, c=1, d=1 ____________________


Istruzioni 26
Struttura iterativa
 #
 #
•  Le istruzioni di iterazione forniscono strutture di controllo
 # per esprimere la necessità di ripetere una certa istruzione
 #
 # durante il verificarsi di una certa condizione.
 #
 #
•  Per il Teorema di Jacopini-Böhm, una struttura iterativa
 # è sufficiente (insieme alle strutture sequenza e alternativa)
 #
 # •  Tuttavia, per migliorare l’espressività del linguaggio,
 #
 # vengono rese disponibili vari tipi di istruzioni di iterazione:
 # –  while ( )
 #
 # –  do … while ( )
–  for ( ; ; )

istruzioni 27

Motivare iterazioni con un problema


•  Dato un numero naturale N, calcolare la corrispondente
somma dei primi N numeri naturali:
Somma(N) = 0 + 1 + 2 + ! + N
•  Allora
–  Somma(0) = 0
–  Somma(1) = 0 + 1 = Somma(0) +1
–  Somma(2) = 0 + 1 + 2 = Somma(1)+2
"
–  Somma(N) = Somma(N-1) + N

•  Definizione per induzione


–  Caso Base: Somma(0) = 0
–  Caso Induttivo: Somma(N) = Somma(N-1) + N

istruzioni 28
Soluzione del problema

È quindi necessario
•  Inizializzare la somma a 0: Somma(al passo 0)=0
•  Ripetere l’operazione di somma per N volte:
Somma(al passo i-esimo) = Somma(al passo i-1) + 1

Rappresentazione dei dati


•  La variabile n rappresenta il numero naturale N dato
•  La variabile i è il contatore: rappresenta un ausilio
per scorrere tutti i valori naturali da 1 fino a N
ovvero conta il numero di iterazioni
•  La variabile s rappresenta la somma calcolata fino al
passo i-esimo
istruzioni 29

Algoritmo e Programma
start

READ n

s=0

i=1
finché resta vero che

no i<=n

while (i<=n)
WRITE s yes
{
s=s+i s = s+i;
i = i+1;
end

i = i +1
}

istruzioni 30
Istruzione iterativa while
<istruzione-while> ::=
while (condizione) <istruzione>
falsa
condizione

vera

istruzione

•  <istruzione> viene ripetuta per tutto


il tempo in cui l’espressione condizione rimane vera
•  Se condizione è già inizialmente falsa, il ciclo non viene
eseguito neppure una volta; in generale, non è noto a
priori quante volte <istruzione> verrà eseguita

istruzioni 31

Istruzione iterativa while : Osservazioni


•  Direttamente o indirettamente, <istruzione> deve modificare
prima o poi la condizione, altrimenti si ha un ciclo infinito
•  Per questo motivo, molto spesso <istruzione> è in realtà un
blocco, che contiene una istruzione di modifica di qualche
variabile che compare nella condizione
•  Esempio precedente

while (i<=n)
{ Istruzione di modifica
s = s+i; della condizione del while
i = i+1;
}

istruzioni 32
Esercizio (Programma completo)
#include <stdio.h>
main()
{
int n, i, s;

printf("Inserisci il numero: ");


scanf("%d",&n);
s = 0;
i = 1;
while(i<=n)
{
s = s+i;
i = i+1;
}
printf("La somma fino a %d è %d", n, s);
}

istruzioni 33

Esercizio: calcolo del valore minimo


•  Problema: Ricercare il minimo di K numeri forniti in input;
K è fornito in input dall’utente ed è maggiore o uguale a 1.
•  Algoritmo: è necessario definire il minimo per induzione
perchè i valori vengono inseriti uno alla volta
–  CASO BASE: minimo({X})=X
–  CASO INDUTTIVO:
minimo({X1,..,Xn+1})= minore tra minimo({X1,..,Xn}) e Xn+1

•  Rappresentazione dei dati – variabili:


–  k rappresenta il numero di valori su cui calcolare il minimo
–  x rappresenta il valore inserito dall’utente
–  i è un contatore per il numero di valori inseriti
–  min rappresenta il minimo fino all’i-esimo valore inserito

istruzioni 34
Calcolo del valore minimo (Algoritmo)
START

READ K, X

MIN = X

I=1

WRITE
I< K? NO END
MIN

YES

READ X
while(i<k)
{
scanf("%d", &x);
YES X < MIN ? if (x<min)
min = x;
MIN = X
NO
i=i+1;
}
I=I+1

Algoritmi 35

Calcolo del valore minimo (Programma)

#include <stdio.h>

main(){
int k, i;
int x, min;
Inizializzazione del
printf("Quanti valori vuoi inserire?"); minimo
scanf("%d", &k); (caso base)
printf("Inserisci un valore? ");
scanf("%d", &x); Confronto fra il
min = x; numero di valori
i=1; inseriti e quelli da
while(i<k){ inserire
printf("Inserisci un valore? ");
scanf("%d", &x); Aggiornamento del
if (x<min) minimo
min = x; (caso induttivo)
i=i+1;}
Aggiornamento
printf("Il minimo valore inserito è %d", min);
del numero di
}
elementi inseriti
istruzioni 36
Calcolo del valore minimo (Programma)

#include <stdio.h>

main(){
int k, i;
int x, min;
Uguali a quelle del ciclo!
printf("Quanti valori vuoi inserire?"); Per non ripeterle:
scanf("%d", &k);
printf("Inserisci un valore? ");
scanf("%d", &x); Non avendo x non posso
min = x; inizializzare min
i=1;
while(i<k){
printf("Inserisci un valore? "); Inizializzazione del minimo
scanf("%d", &x); (caso base per i==o)
if (i==0 || x<min) OPPURE
min = x; Aggiornamento del minimo
i=i+1;} (caso induttivo per i>0)
printf("Il minimo valore inserito è %d", min);
}

istruzioni 37

Calcolo del valore minimo: variante

•  Problema: Ricercare il minimo di un insieme di numeri


inseriti in input; il numero di valori inseriti non è noto a priori.
•  Osservazioni:
–  La definizione per induzione rimane invariata
–  L’unica differenza è che non conosco il numero di valori che
verranno inseriti e quindi il numero di iterazioni non è più
controllato da k e i ma sarà l’utente a dire al programma
quando non ha più valori da inserire

•  Rappresentazione dei dati – variabili:


–  x rappresenta il valore inserito dall’utente
–  min rappresenta il minimo fino all’i-esimo valore inserito
–  continua è un flag che indica la “fine immissione dei dati”:
variabile char che assume valore 's' (si) oppure 'n' (no)
istruzioni 38
Calcolo del valore minimo (Programma)

#include <stdio.h>

main(){
int x, min;
char continua;

printf("Inserisci un valore?"); Viene richiesto


scanf("%d", &x); fflush(stdin); all’utente se desidera
min = x; continuare
printf("Vuoi continuare (s /n)?");
scanf("%c", &continua); Condizione di
while(continua == 's'){ continuazione
printf("Inserisci un valore?");
scanf("%d", &x); Viene richiesto
if (x<min) all’utente se desidera
min = x; continuare
printf("Vuoi continuare (s/n)? ");
scanf("%c", &continua);}
printf("Il minimo valore inserito è %d", min);
}

istruzioni 39

Istruzione iterativa do"while


<istruzione-do-while> ::=
do <istruzione> while(condizione);
istruzione

vera
falsa
condizione

•  È una variante dell’istruzione while


•  A differenza del while , la condizione è verificata dopo aver
eseguito <istruzione>
Quindi il ciclo viene sempre eseguito almeno una volta

istruzioni 40
Osservazioni

•  Analogamente al while , per evitare il ciclo infinito,


<istruzione> deve modificare prima o poi la condizione

•  Si noti che, come nel caso del while , si esce dal ciclo
quando la condizione è falsa

•  È adatta a quei casi in cui, per valutare condizione, è


necessario aver già eseguito <istruzione>
–  esempio tipico: Controllo valori di input

•  Non è adatta a quei casi in cui il ciclo può non dover


essere mai eseguito.
istruzioni 41

Controllo valori di input

•  Per controllare che i valori di input soddisfino una certa


<condizione> scriveremo il seguente ciclo do-while
do
<leggi valori di input>
while ( ! <condizione> )

•  Questa è la forma generale; a volte risulta più semplice


per chi scrive il programma riformulare la condizione del
ciclo eliminando la negazione !
•  Nel seguito vengono fatti alcuni esempi utilizzando
!<condizione>. Quindi gli stessi esempi verranno riscritti in
modo equivalente eliminando la negazione !
istruzioni 42
Controllo valori di input: esempi
Esempio 1: n deve essere positivo
do
scanf("%d", &n);
while (!(n>0));
Esempio 2: n deve essere un voto (ovvero compreso fra 16 e 30)
do
scanf("%d", &n);
while (!((n>=16) && (n<=30)));

Esempio 3: n deve essere negativo o compreso fra 3 e 15


do
scanf("%d", &n);
while ( ! ( (n<0) || ((n>=3) && (n<=15)) ) );

Esempio 4: risposta deve essere s o n


do
scanf("%c", &risposta);
while ( ! ( (risposta == 's') || (risposta == 'n') ) );
istruzioni 43

Controllo valori di input: esempi senza !


Esempio 1: n deve essere positivo
do
scanf("%d", &n);
while ( (n<=0));
Esempio 2: n deve essere un voto (ovvero compreso fra 16 e 30)
do
scanf("%d", &n);
while ( (n<16) || (n > 30)));

Esempio 3: n deve essere negativo o compreso fra 3 e 15


do
scanf("%d", &n);
while ( ( (n>=0) && ((n<3) || (n> 15)) ) );

Esempio 4: risposta deve essere s o n


do
scanf("%c", &risposta);
while ( (risposta != 's') && (risposta != 'n') );
istruzioni 44
Controllo valori di input: Esempio
Acquisire da input un intero n positivo, effettuando al massimo 10
tentativi, cioè dopo 10 tentativi di leggere un intero positivo il programma
deve comunque terminare
do Sono due i casi di terminazione,
leggi n cioè si può terminare in un caso
while ! ( n positivo OPPURE oppure
nell’altro caso.
eseguiti 10 tentativi)

Il numero di tentativi/letture fatte viene contato tramite una variabile


(contatore) count, che inizialmente vale 0
eseguiti 10 tentativi ! count == 10

count =0;
do {
scanf("%d",&n);
count++;
} while (! ( (n > 0) || (count == 10) ) );

istruzioni 45

Istruzione “break”
•  Determina l’uscita immediata dall’istruzione corrente
–  determina l’uscita immediata da un ciclo senza valutare
l’espressione di controllo e viene avviata l'esecuzione
dell'istruzione successiva.
–  Esempio precedente:
count =0;
do { Se sono state fatte già
if (count == 10) 10 tentativi si
break; interrompe il ciclo
scanf("%d",&n);
count++;
} while (! (n > 0) );

•  break può rendere il codice meno leggibile, in quanto alcune


condizioni di terminazione non sono riportate nella condizione di
controllo del ciclo ma sono nascoste all’interno del ciclo stesso.
istruzioni 46
Istruzione iterativa for
•  Non è l’istruzione per implementare cicli definiti
come in altri linguaggi
•  È una evoluzione dell’istruzione while, rispetto a cui mira
ad eliminare alcune frequenti sorgenti di errore:
–  mancanza delle necessarie inizializzazioni delle variabili
–  mancanza dell’istruzione di modifica della condizione del ciclo
! rischi di cicli infiniti

•  Per questo, l’istruzione for comprende esplicitamente:


- una espressione di inizializzazione
- una espressione di modifica del ciclo

istruzioni 47

Istruzione iterativa for (sintassi)


<istruzione-for> ::=
for (espr-inizializz. ; condizione ; espr-modifica)
<istruzione>;

espr-inizializzazione

falsa
Struttura condizione
del while
vera

istruzione

espr-modifica

istruzioni 48
Istruzione iterativa for : esempi
main ()
{ … main ()
i = 1; { …
while (i<=n){ for (i=1; i<=n; i++) s = s+i;
s = s+i; …
i++; } }
… Espressione di Espressione di modifica
}
inizializzazione del ciclo della condizione del for

main() main()
{ … { …
i=0; for(i=0; i<k; i++){
while(i<k){ printf("Inserisci un valore?");
printf("Inserisci un valore?"); scanf("%d", &x);
scanf("%d", &x); if (x<min)
if (x<min) min = x;}
min = x; …
i=i+1;} }

}
istruzioni 49

Istruzione iterativa for : osservazioni


•  Per inizializzare (o modificare) più variabili si può usare
una espressione composta (operatore , )
•  L’espressione di modifica della condizione appare in modo
più evidente (la sua mancanza si nota !)
•  L’ <istruzione> che compare nel corpo del ciclo è solo
l’operazione vera e propria da ripetere:
# migliore leggibilità

•  Ognuna delle espressioni può essere omessa, ma il


separatore ; deve rimanere
Se manca la condizione, la si assume sempre vera

istruzioni 50
Esercizio (Specifica)

•  Codificare mediante i costrutti while e for l’algoritmo che


esegue la moltiplicazione di due numeri letti in input
mediante somma (già descritto con i flowchart)

Rappresentazione dei dati


•  Servono 2 variabili (int) per rappresentare i valori da
moltiplicare: a, b

•  Per l iterazione, servono due variabili ausiliarie (int), una


come contatore e l altra per contenere il prodotto calcolato
ad ogni passo: i, prod

istruzioni 51

Esercizio (Programma)
#include <stdio.h>
main()
{
int a, b, i, prod;
printf("Inserisci i due valori da moltiplicare: ");
scanf("%d", &a);
scanf("%d", &b);
prod=0; i=0;
while (i<b)
{ prod=prod+a; for (prod=0,i=0; i<b; i++)
i++; prod=prod+a;
}
printf("Risultato prodotto di %d e %d = %d", a, b, prod);
}

istruzioni 52
Esercizio (verifica per un caso)
main()
{
a ? i ?
int a, b, i, prod;
b ? prod ?
printf("Inserisci …:");
scanf("%d", &a); a 5 i 0
scanf("%d", &b);
b 3 prod 0
prod=0; i=0;

while (i<b)
a 5 i 1 2 3
{ prod=prod+a;
i++; b 3 prod 5 10 15
}
printf("Risultato …"); Output: Risultato prodotto di 3 e 5 = 15
}
istruzioni 53

Cicli Innestati
•  L’istruzione di una istruzione iterativa può essere a sua
volta una istruzione iterativa (o contenerne una), dando
origine a cicli innestati.
•  Esempio: Stampa della “tabellina pitagorica” 10 X 10
Algoritmo principale Algoritmo per la
stampa della tabellina dell’N
- per i valori di N da 1 a 10
- stampa la tabellina dell’N ! - per i valori di M da 1 a 10
- vai a capo - stampa N * M

for(N=1; N<=10;N++){
for(M=1;M<=10;M++)
printf("%d ", N*M);
printf("\n");
}

Istruzioni 54
Esempio
•  Calcolo della potenza di interi.
Acquisire l’esponente ed effettuare per ogni numero fornito il
calcolo della potenza.
Si conviene di terminare quando la base fornita è 0.

Algoritmo principale Algoritmo per il calcolo della


potenza
- acquisisci l’esponente E
- acquisisci la base B
- fino a quando B è diverso da zero
- calcola la potenza B elevato a E ! - inizializza P a uno
(neutro moltiplicativo)
- visualizza il risultato - per tutti i valori di I da 1 a E
- acquisisci un numero B - moltiplica P per B

Istruzioni 55

Esempio (programma)
#include <stdio.h>
main(){
int B,P,E,I;
printf("Inserire l'esponente non negativo > ");
scanf("%d",&E);
printf("Inserire la base (zero per terminare) ");
scanf("%d",&B);
while (B!= 0) {
P=1;
for (I=1;I<=E;I++)
P*=B;
printf("%d elevato a %d = %d\n",B,E,P);
printf("Inserire la base (zero per terminare) ");
scanf("%d",&B);
}
}
Istruzioni 56
Esercizio
•  Specifica: Stampare un rettangolo costituito da nxm caratteri
asterisco, dove i valori di m e n sono inseriti da tastiera.
Ad esempio: m=5 n=2 deve apparire il rettangolo
*****
start *****
READ m, n

i=1

no i<=n

-  per i valori di i da 1 a n
end yes -  stampa riga di m asterischi
Stampa riga di m asterischi

i = i +1

istruzioni 57

Esercizio
•  Servono 2 variabili (int) per rappresentare il numero delle righe
e il numero delle colonne: n, m

•  Servono, poi, due variabili ausiliarie (int) :


–  i, per contare il numero di righe stampate
–  j, per contare il numero di caratteri asterisco stampati sulla
i-esima riga corrente

Descrizione informale
- acquisisci il numero di righe n e di colonne m
- per i valori di i da 1 a n
- per i valori di j da 1 a m
- stampa il carattere '*'
- vai a capo

istruzioni 58
Esercizio (Programma)
#include <stdio.h>
main()
{
int n, m, i, j;
printf("Inserisci il numero di righe e di colonne: ");
scanf("%d", &n);
scanf("%d", &m);
for(i=1; i<=n;i++){
for(j=1;j<=m;j++)
printf("*");
printf("\n");
}
}

istruzioni 59

Esercizio (Quesito)
•  È possibile unificare le due inizializzazioni, i=1 e j=1,
ovvero i seguenti frammenti di codice

for(i=1; i<=n;i++){ for(i=1, j=1; i<=n;i++){


for(j=1;j<=m;j++) for(;j<=m;j++)
printf("*"); printf("*");
printf("\n"); printf("\n");
} }
} }

sono equivalenti?

NO, perchè j deve essere inizializzato a 1 per ogni valore


di i da 1 a n!
istruzioni 60
Esercizi (Varianti sul tema)
•  Scrivere un programma che stampi un triangolo rettangolo costituito
da 1, 2, ", n caratteri asterisco rispettivamente sulla 1°, 2°,",n°-
esima riga, dove il valore di n è inserito da tastiera.
Ad esempio: n=3 deve apparire il triangolo rettangolo:
*
**
***
•  Scrivere un programma che stampi un rettangolo nxm costituito da
una cornice di caratteri cancelletto (#) e l’interno di caratteri asterisco
(*), dove i valori di m e n sono inseriti da tastiera.

Ad esempio: m=5 n=3 deve apparire il rettangolo:

#####
#***#
#####
istruzioni 61

Istruzione di scelta multipla : switch


 #
 #
•  Consente di scegliere fra molte istruzioni in base al
 # valore di un’espressione di selezione
 #
 # •  L espressione di selezione deve denotare un valore
 #
 #
numerabile (intero, carattere,")
 # •  Il valore di tale espressione viene confrontato con le
 #
 # costanti che etichettano i vari casi: l’esecuzione prosegue
 #
 # dal ramo dell’etichetta corrispondente (se esiste)
 #
 #
•  Se nessuna etichetta corrisponde al valore
 # dell’espressione, si segue il ramo default (se specificato)
•  Se neanche questo esiste, l’esecuzione prosegue con
l’istruzione successiva all’istruzione switch
Istruzioni 62
Istruzione di scelta multipla - sintassi
<istruzione-di-scelta-multipla> ::=
switch expr
(<espressione_di_selezione> ) { espressione
case <etichetta_1> : di selezione
< istruzione1> [break;]
expr = etichetta_1
case <etichetta2> : break
< istruzione_2> [break;] istruzione1

[ default : < istruzione> ] expr = etichetta_2
break
} istruzioni2

•  <espressione_di_selezione> … break
è un’espressione che denota
un valore numerabile default
che viene valutata all’esecuzione istruzione

dell’istruzione switch
•  <etichetta_i>
è una costante dello stesso tipo di
<espressione_di_selezione>
Istruzioni 63

Scelta multipla – sintassi completa


<istruzione-di-scelta-multipla> ::=
switch(<espr_intera>) {<corpo_switch> }
<corpo_switch> ::= <lista_case> <sequenza_istr>
<sequenza_istr> ::= <istr> | <istr> <sequenza_istr>
<lista_case> ::= <case> | <case> < lista_case >
<case> ::= case <etichetta> : |
default:

• c’è al massimo un <case> con default

• non ci possono essere più <case> con lo stesso


valore di <etichetta>;

Istruzioni 64
Scelta multipla: Osservazioni
•  <istruzioni> denota una sequenza di istruzioni per cui non
occorre un blocco per specificare più istruzioni
•  I vari rami non sono mutuamente esclusivi: una volta
imboccato un ramo, l’esecuzione prosegue in generale con le
istruzioni dei rami successivi
•  Per avere rami mutuamente esclusivi occorre forzare
esplicitamente l’uscita mediante l’istruzione break
•  Per eseguire la stessa <sequenza_istr> per più casi, cioè
per più valori dell’etichetta elencare in sequenza i vari case:

switch (risposta){
case 's': case 'S': case 'y': case 'Y':
printf("risposta affermativa"); break;
default : printf("risposta negativa"); }

Istruzioni 65

Scelta multipla formulata con if_then_else


La formulazione dello switch con if_the_else mette in evidenza
l’importanza dell’istruzione break alla fine di ogni <case>
switch (E) { if (E==c1)
case c1 : S1 S1 S2 ... Sn Sd
case c2 : S2 else
... if (E==c2)
case cn : Sn S2 S3 ... Sn Sd
default : Sd else ...
} ...
else
if (E==cn)
Sn Sd
else
Sd

switch (E) { if (E==c1)


case c1 : S1 break S1
case c2 : S2 break else if (E==c2)
... S2
case cn : Sn break else ...
default : Sd ...
} else
if (E==cn)
Sn
else
Sd

Istruzioni 66
Esempio
#include <stdio.h>
main() {
const float F1=9.0, F2=5., SH=32;
int c, f, temp;
char scala;

printf("Inserisci la temperatura e la scala (C o F): ");


scanf("%d", &temp); fflush(stdin); Necessità di break per
scanf("%c", &scala); rendere le due alternative
switch (scala) mutuamente esclusive
{
case 'C': c = temp; f = SH+temp*F1/F2; break;
case 'F': f = temp; c = F2/F1*(temp-SH); break;
default: printf("Errore\n");
}
printf ("%f\n", temp_out); Inutilità di break
} nell’ultimo ramo

Istruzioni 67

Esercizio : Una piccola calcolatrice


•  Scrivere un programma che riceve in input una
espressione del tipo
<op1> op <op2>
dove <op1> e <op2> sono operandi interi e op è un
operatore algebrico (+, -,*, /) (ad esempio 2+3, 3/4) e
restituisce in output il risultato.
PROBLEMA
Gli operandi sono interi e quindi riesco a leggerli e
associarli direttamente a 2 variabili di tipo int.
Ma come faccio a gestire l’operatore?
L’operatore non può che essere di tipo char, ma poi devo
essere in grado di interpretarlo all’interno del programma e
quindi di eseguire l’operazione corretta.
Istruzioni 68
Esercizio
#include <stdio.h>

main(){
int op1, op2, ris;
char op;
printf("Digita l’espressione: ");
scanf("%d %c %d”, &op1, &op, &op2);
switch (op)
{
case '+' : ris = op1+op2; break;
case '-': ris = op1-op2; break;
case '*': ris = op1*op2; break;
case '/': ris = op1/op2; break;
default: printf("Errore\n");
}
printf("%d %c %d = %d", op1, op, op2, ris);
}
Istruzioni 69

Pro e contro della scelta multipla


•  L istruzione switch evita una (lunga) serie di if

•  Tuttavia:
–  è utilizzabile solo con espressioni ed etichette di tipo
numerabile (int, char)
–  non è utilizzabile con numeri reali (float, double) o con
tipi strutturati (stringhe, vettori, strutture...)

Istruzioni 70
Esercizio (Specifica)
•  Dati tre valori a " b " c che rappresentano le lunghezze di
tre segmenti, valutare se possono essere i tre lati di un
triangolo.
Se sì, stabilire il tipo di triangolo: scaleno, isoscele,
equilatero.

OSSERVAZIONE
–  perché tre segmenti possano costituire i lati di un
triangolo, deve valere la relazione c < (a + b)

Istruzioni 71

Esercizio (Algoritmo)
START

READ a, b, c

triangolo=equilatero=scaleno=isoscele= false

c < a+b V

triangolo = true

F a==b && b==c V

F a==b || b==c || a==c equilatero = true


V
F

scaleno = true isoscele = true

END

Istruzioni 72
Esercizio (variabili)

•  Servono 3 variabili (float) per rappresentare i valori dei 3


segmenti: a, b, c

•  Serve, poi, una variabile logica (in C, di tipo int) per


rappresentare il fatto se i 3 segmenti possono costituire o
meno un triangolo: triangolo

•  Servono, infine, 3 variabili logiche (in C, di tipo int) per


rappresentare quale caratteristica del triangolo è vera:
scaleno, isoscele, equilatero

Istruzioni 73

Esercizio (Programma)
#include <stdio.h>
main()
{
float a, b, c;
int triangolo, scaleno, isoscele, equilatero;

printf("Inserisci le lunghezze dei tre segmenti:");


scanf("%f %f %f",&a,&b,&c);
triangolo=scaleno=isoscele=equilatero=0;
if (a+b>c)
{ triangolo = 1;
if ((a==b) && (b==c))
equilatero=1;
else
if ((a==b) || (b==c) || (a==c))
isoscele=1;
else
scaleno=1; }
}
Istruzioni 74
Esercizio (nota)
•  Sarebbe stato possibile utilizzare
–  delle espressioni condizionali?
–  Un’istruzione di scelta multipla switch invece di tanti if
annidati (innestati) ?
•  No! Perché:
–  Si tratta di verificare condizioni annidate (innestate)
–  Si tratta di verificare condizioni complesse (uguaglianze
multiple), non di semplici scelte da fare in base al valore di
una espressione di selezione.

•  Completare l’esercizio stampando il risultato: è un


triangolo di tipo scaleno ovvero “non è un triangolo” "

Istruzioni 75

Esercizio 2

•  Specifica:
Dati tre valori a, b, c, rappresentanti i coefficienti di
un’equazione di secondo grado
a x2 + b x + c = 0,
calcolare le due radici (se reali)

•  Algoritmo:
1.  Calcolare il valore: delta = b2 - 4 a c
2.  Se delta#0
•  calcolare d = !delta
•  calcolare le due radici:
x1 = - (b + d) / 2a
x2 = - (b - d) / 2a
altrimenti le radici sono complesse e non bisogna calcolarle
Istruzioni 76
Esercizio 2 (variabili)
•  Servono 3 variabili (float) per rappresentare i valori dei 3
coefficienti dell’equazione: a, b, c

•  Serve, poi, una variabile float per rappresentare delta


(potrebbe essere utile, per chiarezza, utilizzare un’altra
variabile per rappresentare la radice quadrata di delta: d)

•  Servono, infine, 2 variabili float per rappresentare le due


radici dell’equazione: x1, x2

Istruzioni 77

Esercizio 2 (Programma)
#include <math.h>
main ()
{
float a=1.0, b=2.0, c=-15.0;
float delta, d, x1, x2;
delta = b*b-4*a*c; La direttiva al pre-processore #include<math.h>
if (delta>=0) non è un istruzione C
Ha lo scopo di rendere disponibili le funzioni
{ matematiche, come sqrt(), fornite nella libreria
d = sqrt(delta); math.h del linguaggio C
x1 = -(b+d)/(2*a);
x2 = -(b-d)/(2*a);
}
}

Istruzioni 78
Esercizio 3
Dire quante volte viene visualizzato “Passo!” per i=4 e j=3 .

for (i=0;k<i;k=k+2)
for(s=k;s>-j;s--)
printf(“\nPasso!”);

volte = 8

Istruzioni 79

Compito del 21/07/2008


Indicare cosa stampa il seguente programma se in j si inseriscono i
seguenti valori:
6 : __________5______________
1 : __________5______________
-3 : __________5______________

void main ()
{
int x = 5, j; scanf (“%d”,&j);
if( j %3==0 ) {int x; x = 3;} printf (“%d”,x);
}

Istruzioni 80

Potrebbero piacerti anche