Sei sulla pagina 1di 110

Il linguaggio C

Progettato nel 1972 da D. M. Ritchie presso i laboratori AT&T Bell,


per poter riscrivere in un linguaggio di alto livello il codice del sistema
operativo UNIX.

Definizione formale nel 1978 (B.W. Kernigham e D. M. Ritchie)

Nel 1983 e‘ stato definito uno standard (ANSI C) da parte


dell’American National Standards Institute.

Caratteristiche principali:
• Elevato potere espressivo:
• Tipi di dato primitivi e tipi di dato definibili dall’utente
• Strutture di controllo (programmazione strutturata,
funzioni e procedure)

• Caratteristiche di basso livello (gestione delle memoria, accesso


alla rappresentazione)

• Stile di programmazione che incoraggia lo sviluppo di programmi


per passi di raffinamento successivi (sviluppo top-down)

• Sintassi definita formalmente

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 1


Elementi del testo di un programma C:
Nel testo di un programma C possono comparire:
• parole chiave
• commenti
• caratteri e stringhe
• numeri (interi o reali) valori costanti
• identificatori

Parole chiave:
auto break case const
continue default do double
else enum extern float
for goto if int
long register return short
signed sizeof static struct
switch typedef unsigned void
volatile while

Le parole chiave sono parole riservate, cioe` non possono essere


utilizzate come identificatori (ad esempio di variabili)

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 2


Commenti:
Sono sequenze di caratteri ignorate dal compilatore.
Vanno racchiuse tra /* ... */:

/* questo e‘
un commento
dell’autore */

I commenti vengono generalmente usati per introdurre note


esplicative nel codice di un programma.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 3


Costanti

Caratteri:
Insieme dei caratteri disponibili (e‘ dipendente dalla
implementazione). In genere, ASCII esteso (256 caratteri). Si
indicano tra singoli apici:

’a’ ’A’
Caratteri speciali:
newline \n
tab \t
backspace \b
form feed \f
carriage return \r
codifica ottale \OOO con O cifra ottale 0-7
\041 è la codifica del
carattere !
\' \\ \" \0 (carattere nullo)

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 4


Stringhe:
Sono sequenze di caratteri tra doppi apici " ".

"a" "aaa" "" (stringa nulla)

Esempi:
printf("Prima riga\nSeconda riga\n");
printf("\\\"/");

Prima riga
Seconda riga
\"/

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 5


Numeri interi
Rappresentano numeri relativi (quindi con segno):

2 byte 4 byte
base decimale 12 70000, 12L
base ottale 014 0210560
base esadecimale 0xFF 0x11170

Numeri reali
Varie notazioni:

24.0 2.4E1 240.0E-1

Suffissi: l, L, u, U ( interi-long, unsigned)


f, F (reali - floating)

Prefissi: 0 (ottale) 0x, 0X(esadecimale)

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 6


Identificatori
Un identificatore e‘ un nome che denota un oggetto usato nel
programma (ad esempio, variabili, costanti, tipi, procedure e
funzioni).

• Deve iniziare con una lettera (o con il carattere ‘_’), a cui


possono seguire lettere e cifre in numero qualunque (dipende
dalla realizzazione):

<identificatore>::=<lettera>{<lettera>|<cifra>}

• distinzione tra maiuscole e minuscole


(linguaggio case-sensitive)
• underscore (‘_’) iniziale solo per oggetti di sistema
_8087 - variabile globale del Turbo C++
vale 1 se il PC ha il coprocessore matematico
Esempi:
Alfa beta corretti
Gamma1 Gamma2

3X int non sono corretti

In ciascuna realizzazione esistono identificatori standard e non-


standard predefiniti (parole chiave).

+ prima di essere usato, un identificatore deve essere gia` stato


definito in una parte di testo precedente.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 7


Struttura di un programma C

Nel caso piu‘ semplice, un programma C consiste in:

<programma>::= [<parte-dich-globale>] <main>


[{<altre-funzioni>}]

A sua volta la parte <main> di un programma e‘ suddivisa in:

<main> ::=
main() { <parte-dichiarazioni> <parte-istruzioni> }

+ il <main> e‘ costituito da due parti:

• Una parte di dichiarazioni (variabili, tipi, costanti, etichette, etc.)


in cui vengono descritti e definiti gli oggetti che vengono utilizzati
dal main;

• Una parte istruzioni che descrive l’algoritmo risolutivo utilizzato,


mediante istruzioni del linguaggio.

Formalmente:

il main e` una funzione che non restituisce alcun valore.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 8


Esempio:

/*programma che, letti due numeri a


terminale, ne stampa la somma*/
LQFOXGHVWGLRK!
main()
{
int X,Y; /* p. dichiarativa */

scanf("%d%d",&X,&Y);/*p. istruzioni*/
printf("%d",X+Y);
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 9


Dati e Operazioni

Dati:
I dati manipolati da un programma possono essere classificati in:

• costanti, dati che non cambiano di valore durante l’esecuzione

• variabili, dati che cambiano di valore durante l’esecuzione

Operazioni:
Istruzione di assegnamento: (variabile come astrazione della cella
di memoria)

<identificatore-variabile> = <espressione>;

Istruzioni di lettura e scrittura:

scanf(<stringa-controllo>,<sequenza-elementi>);

printf(<stringa-controllo>,<sequenza-elementi>);

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 10


Istruzioni di controllo:

• istruzione composta: (blocco)


{ <sequenza-istruzioni> }

• istruzione condizionale: (selezione)


if <espressione> <istruzione>
else <istruzione>;

• istruzione di iterazione: (ciclo)


while <espressione> <istruzione>;

Sono in realta` molte di piu`.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 11


Definizione di variabili
Una variabile rappresenta un dato che puo‘ cambiare il proprio
valore durante l’esecuzione.

La definizione di variabile associa ad un identificatore (nome della


variabile) un tipo.

<def-variabili> ::= <identificatore-tipo>


<identificatore-variabile>
{, <identificatore-variabile> } ;

int A, B, SUM; /* dati interi */


float root, Root; /* dati reali */

char C ; /* carattere */

+ La definizione di una variabile provoca come effetto l'allocazione


in memoria della variabile specificata.
Ogni istruzione successiva alla definizione di una variabile A,
potra` utilizzare A

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 12


Variabile
Il concetto di variabile nel linguaggio C rappresenta una astrazione
della cella di memoria.

L’istruzione di assegnamento, quindi, e‘ l’astrazione dell’operazione


di scrittura nella cella che la variabile rappresenta.

Assegnamento:
<identificatore-variabile> = <espressione>

Esempio:
int a;
...
a=100;

V 

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 13


Esempio:

#include <stdio.h>
main()
{
/* programma che letto un numero a
terminale stampa il valore
della circonferenza del cerchio
con quel raggio */
float X, Y;
scanf("%f",&X);
Y = 2*3.14*X;
printf("%f",Y);
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 14


Definizione di costanti
Una costante rappresenta un dato che non puo‘ cambiare di valore
nel corso dell’esecuzione.

La dichiarazione di una costante associa ad un identificatore (nome


della costante) un valore (numero o altro identificatore di costante).

<dichiarazionezione-costanti> ::= const <tipo>


<identificatore-costante>=<costante>

<costante> ::= (+ | -) <identificatore-costante> |


(+|-)<numero-senza-segno> | <altre-costanti>

const float pigreco = 3.14;


const float pigreco = 3.1415926; e = 2.7182;
menoe = - e;

+ prima di essere usato, un identificatore deve essere gia` stato


definito (ad es., e per definire menoe).

Si aumenta la leggibilita` e modificabilita` dei programmi.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 15


Esempio:

#include <stdio.h>
main()
{
/* programma che, letto un numero a
terminale stampa il valore della
circonferenza del cerchio con quel raggio
*/

const float pigreco = 3.1415926;


float X, Y;

scanf("%f",&X);
Y = 2*pigreco*X;
printf("%f",Y);
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 16


Il concetto di Tipo
Nei linguaggi di programmazione più recenti si fa uso dei tipi:
Proprietà:
+ Ciascun dato (variabile o costante) del programma deve
appartenere ad un solo tipo.

+ Ciascun operatore richiede operandi di tipo specifico e produce


risultati di tipo specifico.
Vantaggi:
Se un linguaggio di programmazione e‘ tipato:

+ Astrazione:L’utente esprime i dati ad un livello di astrazione piu`


alto della loro organizzazione fisica. L’insieme di bit che
rappresenta un valore di un certo tipo non e` accessibile.
Maggior portabilita`.

+ Protezione: Il linguaggio protegge l’utente da combinazioni


errate di dati ed operatori (controllo statico sull’uso di variabili,
etc. in fase di compilazione).

Portabilita‘: l’indipendenza dall’architettura rende possibile la


compilazione dello stesso programma su macchine profondamente
diverse.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 17


Tipo di Dato in C

In C si possono utilizzare:

• tipi primitivi: sono tipi di dato previsti dal linguaggio (built-in) e


quindi rappresentabili direttamente.
• tipi non primitivi: sono tipi definibili dall’utente (mediante
appositi costruttori di tipo, v. typedef).

Inoltre si distingue tra:

• tipi scalari, il cui dominio e` costituito da elementi atomici, cioe`


logicamente non scomponibili.

• tipi strutturati, il cui dominio e` costituito da elementi non atomici


(e quindi scomponibili in altri componenti).

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 18


Classificazione dei tipi di dato in C

tipi di dato

scalari strutturati

predefiniti definiti costruttori definiti


dall’utente predefiniti dall’utente
int
char [ ] (vettori)
float enum struct (record) .
double * puntatori union .
.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 19


Tipi primitivi
Il C prevede quattro tipi primitivi:

• char (caratteri)
• int (interi)
• float (reali)
• double (reali in doppia precisione)

Qualificatori e Quantificatori
+ E` possibile applicare ai tipi primitivi dei quantificatori e dei
qualificatori:

• I quantificatori (long e short) influiscono sullo spazio in memoria


richiesto per l’allocazione del dato.
• short (applicabile al tipo int)
• long (applicabile ai tipi int e double)

int X; /* X e’ rappresentato da 16
bit */
long int Y; /*Y -> 32 bit */

• I qualificatori condizionano il dominio dei dati:


• signed (applicabile ai tipo int e char)
• unsigned (applicabile ai tipo int e char)

int A; /*A in[-2e15,2e15-1] */


unsigned int B; /*B in[0,2e16-1]*/

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 20


Il tipo int

Il dominio associato al tipo int rappresenta l’insieme dei numeri interi


(cioe` Z, insieme dei numeri relativi): ogni variabile di tipo int e` quindi
l'astrazione di un intero.

int A; /* A e‘ un dato intero */

+ Poiche` si ha sempre a disposizione un numero finito di bit per la


rappresentazione dei numeri interi, il dominio rappresentabile e`
di estensione finita.

Ad esempio:
se il numero n di bit a disposizione per la rappresentazione di un
intero è 16, allora il dominio rappresentabile è composto di:

2n= 216 = 65.536 valori

e l’intervallo di valori rappresentabili è

[-(2n-1), (2n-1 - 1)]

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 21


Uso dei quantificatori short/long:
Aumentano/diminuiscono il numero di bit a disposizione per la
rappresentazione di un intero:

spazio(short int) <= spazio(int) <= spazio(long int)

Uso dei qualificatori:


• signed: di solito non viene usato solo per gli interi perchè signed
int è equivalente ad int.

• unsigned: vengono rappresentati valori a priori positivi.


Intervallo rappresentabile con n bit:

[0, (2n - 1)]

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 22


Operatori sugli interi
Al tipo int (e tipi ottenuti da questo mediante
qualificazione/quantificazione) sono applicabili i seguenti operatori:
Operatori aritmetici:
forniscono risultato intero:

+ , -, *, / somma, sottrazione, prodotto, divisione


intera.
% operatore modulo: resto della divisione
intera:
10%3 ù 1
++, -- incremento e decremento: richiedono un
solo operando (una variabile) e possono
essere postfissi (a++) o prefissi (++a) (v.
espressioni)

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 23


Valori logici (vero, falso)

+ in C non esiste un tipo primitivo per rappresentare dati logici.

Come vengono rappresentati i risultati di espressioni


relazionali ?

Il C prevede che i valori logici vengano rappresentati attraverso


interi:

• Ad esempio, l'espressione A > B restituisce:

ù 0, se la relazione non e` vera (falso)


ù 1 , se la relazione e` vera (vero)

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 24


Operatori relazionali:
si applicano ad operandi interi e producono risultati interi
appartenenti all’insieme {0,1} (valori logici, il valore 0 corrisponde
a ”falso”, il valore 1 corrisponde a “ vero”).:

==, != uguaglianza, disuguaglianza:


10==3 ù falso, risultato = 0
10!=3 ù vero, risultato = 1
<, >, <=, >= minore, maggiore, minore o uguale,
maggiore o uguale

10>=3 ù vero, risultato = 1

Operatori logici:
si applicano ad operandi di tipo int e producono risultati interi
appartenenti all'insieme {0,1} (valori logici). In particolare
l’insieme degli operatori logici e`:

&& operatore AND logico


|| operatore OR logico
! operatore di negazione (NOT)

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 25


Definizione degli operatori logici:

a b a&&b a||b !a
falso falso falso falso vero
falso vero falso vero vero
vero falso falso vero falso
vero vero vero vero falso

+ In C, gli operandi di operatori logici sono di tipo int:


• se il valore di un operando e` diverso da zero, viene interpretato
come vero.
• se il valore di un operando e` uguale a zero, viene interpretato
come falso.
Quindi, gli operatori logici in C:
a b a&&b a||b !a
0 0 0 0 1
0 ≠0 0 1 1
≠0 0 0 1 0
≠0 ≠0 1 1 0

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 26


Esempi sugli operatori tra interi:

37 / 3 ù 12
37 % 3 ù 1
7<3 ù 0
7 >=3 ù 1
0 || 1 ù 1
0 || -123 ù 1
12 && 2 ù 1
0 && 17 ù 0
!2 ù 0

Overloading:
Il C (come Pascal, Fortran e molti altri linguaggi) operazioni primitive
associate a tipi diversi possono essere denotate con lo stesso
simbolo (ad esempio, le operazioni aritmetiche su reali od interi).

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 27


I tipi float e double (reali)

Rappresentano l’insieme dei numeri reali.


In realtà, sono un'approssimazione dei reali, sia come precisione
che come intervallo di valori.

Lo spazio allocato (e quindi l'insieme dei valori rappresentabili)


dipende dalla rappresentazione adottata.

Uso del quantificatore long:


si puo` applicare a double, per aumentare la precisione:

spazio(float) <= spazio(double) <= spazio(long double)

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 28


Ad Esempio:

Rappresentazione dei reali in TurboC++:


+ 4 byte per float e 8 per double (10 byte per long double).

Tipo: Precisione Valori


__________________________________________________
float 6 cifre dec. 3.4 ×10-38 .. 3.4 ×10+38
double 15 cifre dec. 1.7 × 10-308 . 1.7 × 10+308

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 29


Operatori sui Reali

Operatori aritmetici:
+, -, *, /, ++, -- si applicano a operandi reali e producono
risultati reali

Operatori relazionali:
hanno lo stesso significato visto nel caso degli interi:
==, != uguale, diverso
<, >, <=, >=, minore, maggiore etc.

+ producono un risultato intero appartenente a {0,1}


0, se la relazione è falsa
1, se la relazione è vera

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 30


Esempi:
5.0 / 2 ù 2.5
2.1 / 2 ù 1.05
7.1 < 4.55 ù 1
17== 121 ù 0

+ A causa della rappresentazione finita, ci possono essere errori di


conversione. Ad esempio, i test di uguaglianza tra valori reali (in
teoria uguali) potrebbero non essere verificati.

(x / y) *y == x

Meglio utilizzare "un margine accettabile di errore":


(X == Y) ù (X<=Y+epsilon) && (X<=Y+epsilon)
dove, ad esempio:
const float epsilon=0.000001;

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 31


Il tipo char
Rappresenta l’insieme dei caratteri disponibili sul sistema di
elaborazione (set di caratteri).

Per carattere si intende ogni simbolo grafico rappresentabile


all'interno del sistema. Ad esempio:
• le lettere dell'alfabeto (maiuscole, minuscole)
• le cifre decimali ('0',..'9')
• i segni di punteggiatura (',', '.' etc.)
• altri simboli di vario tipo ('+', '-', '&', '@', etc.).
• i caratteri di controllo (bell, lf, , ff, etc.)

Ogni valore viene specificato tra singoli apici.

Ad esempio:
‘a’ ‘b’ ‘A’ ‘0’ ‘2’

Il dominio associato al tipo char e` ordinato.


L’ordine dipende dal codice utilizzato nella macchina.

Di solito, codice ASCII esteso.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 32


Operatori sui caratteri
Il linguaggio C rappresenta i dati di tipo char come degli interi:

ù ogni carattere viene mappato sull’intero che rappresenta il codice


nella tabella dei set di caratteri.

+ sui dati char e‘ possibile eseguire tutte le operazioni previste per


gli interi. Ogni operazione, infatti, e‘ applicata ai codici associati
agli operandi.

Operatori relazionali:
==,!=,<,<=,>=,> per i quali valgono le stesse regole viste
per gli interi

Ad esempio:
char x,y;
x<y se e solo se codice(x) < codice(y)
Operatori aritmetici:
sono gli stessi visti per gli interi.
Operatori logici:
sono gli stessi visti per gli interi.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 33


Esempi:

’A’ < ’C’ ù 1 (infatti 65 < 67 e‘ vero)

’"’+’#’ ù ’C’ (codice(")+codice(#)=67)

! ’A’ ù 0 (codice(A) e‘ diverso da zero)

’A’ && ’a’ ù 1

Uso dei qualificatori:

In C il tipo char e‘ visto come dominio di valori interi:

Tipo: Dimensione Valori


__________________________________________________
signed char 1 byte -127 .. 128
unsigned char 1 byte 0 .. 255

char è realizzato con un signed char o un unsigned char


a seconda del sistema.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 34


Espressioni Omogenee ed Eterogenee
In C è possibile combinare tra di loro operandi di tipo diverso:
• espressioni omogenee: tutti gli operandi sono dello stesso tipo
• espressioni eterogenee: gli operandi sono di tipi diversi.

Regola adottata in C:
• sono eseguibili le espressioni eterogenee in cui tutti i tipi
referenziati risultano compatibili (cioe`: dopo l’applicazione della
regola automatica di conversione implicita di tipo del C risultano
omogenei ).
• non sono eseguibili le espressioni eterogenee se tutti i tipi
referenziati risultano non compatibili (cioe` restano eterogenei
anche dopo l’applicazione della regola automatica di conversione
implicita di tipo del C).

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 35


Regole di conversione implicita previste dal
C
Data una espressione x op y.

1. Ogni variabile di tipo char o short (incluse le rispettive versioni


signed o unsigned) viene convertita nel tipo int;

2. Se dopo l’esecuzione del passo 1 l'espressione e` ancora


eterogenea, rispetto alla seguente gerarchia

int < long < unsigned< unsigned long < float < double < long double

si converte temporaneamente l'operando di tipo inferiore al tipo


superiore (promotion);

3. A questo punto l'espressione e` omogenea e viene eseguita


l'operazione specificata. Il risultato e` di tipo uguale a quello
prodotto dall'operatore effettivamente eseguito. (In caso di
overloading, quello piu` alto gerarchicamente).

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 36


Compatibilita‘ e conversione implicita di tipo
+ La compatibilita‘, di solito, viene controllata staticamente,
applicando le regole di conversione implicita in fase di
compilazione senza conoscere i valori attribuiti ai simboli
(tipizzazione forte).
Esempio 1: espressione semplice
x/y
3 / 3.0 ù 1.0 (reale)
3.0 /3 ù 1.0 (reale)
3/3 ù1 (intero)

Esempio 2: espressione composta


int x;
char y;
double r;
(x+y) / r

La valutazione dell’espressione procede da sinistra verso destra:

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 37


• passo 1: (x+y)

• y viene convertito nell'intero corrispondente


• viene applicata la somma tra interi
ù risultato intero tmp

• passo 2:
tmp / r
• tmp viene convertito nel double corrispondente
• viene applicata la divisione tra reali
ù risultato reale

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 38


Istruzioni: classificazione
In C, le istruzioni possono essere classificate in due categorie:
• istruzioni semplici
• istruzioni strutturate: si esprimono mediante
composizione di altre istruzioni (semplici e/o
strutturate). Di questa categoria fanno parte le
istruzioni per il controllo del flusso di esecuzione.

istruzioni

SEMPLICI STRUTTURATE

assegnamento istruzione composta


ingresso / uscita if else
goto while do
for
do while
switch

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 39


Assegnamento
E‘ l’istruzione con cui si modifica il valore di una variabile.

<istruzione-assegnamento>::=
<identificatore-variabile> = <espressione>

Ad esempio:
int A, B;

A=20;
B=A*5;

Compatibilita‘ di tipo ed assegnamento:


In un assegnamento, l'idendificatore di variabile e l’espressione
devono essere dello stesso tipo (eventualmente, conversione
implicita).

Esempio:
int x;
char y;
double r;

x=y; /* char -> int*/


x=y+x;
r=y; /* char -> int -> double*/
x=r; /* troncamento*/

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 40


Esempio:

main()
/* intestazione programma */
{
/* segue parte dichiarazioni */
/* parte dichiarazioni variabili */
int X,Y;
unsigned int Z;
float SUM;
/* segue parte istruzioni */
X=27;
Y=343;
Z = X + Y -300;
X = Z / 10 + 23;
Y = (X + Z) / 10 * 10;
/* qui X=30, Y=100, Z=70 */
X = X + 70;
Y = Y % 10;
Z = Z + X -70;
SUM = Z * 10;
/* qui X=100, Y=0, Z=100 , SUM=1000.0*/
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 41


Inizializzazione delle variabili

È possibile specificare un valore iniziale di un oggetto in fase di


definizione.

• Variabili scalari, vettori, strutture.

I tipi scalari vengono inizializzati con una sola espressione che puo`
essere racchiusa tra una coppia di { }.

Esempio:

int x = {10};
char y = ‘a’;
double r = 3.14*2;

+ Differisce dalla definizione di costanti, perche‘ i valori delle


variabili, durante l’esecuzione del programma, potranno essere
modificati.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 42


Espressioni

Un’espressione e‘ una regola per il calcolo di un valore. E‘ una


combinazione di operandi tramite operatori.
3 * (17 - 193) % 19
(3 < 7) && (4 <= 5) or (X > 10)

+ A ciascuna variabile che compare in una espressione deve


essere gia` stato attribuito un valore: l’espressione utilizza il
valore corrente della variabile.

Espressioni Aritmetiche:
A seconda del tipo degli operandi, restituiscono valore intero
oppure reale.

• Espressioni aritmetiche di incremento e decremento: Si


applicano ad operandi di tipo intero (o reale, o carattere) e
producono un risultato dello stesso tipo.

int A=10;

A++; /*equivale a: A=A+1; */


A--; /*equivale a: A=A-1; */

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 43


• Notazione Prefissa: (ad esempio, ++A) significa
che l'incremento viene fatto prima dell'impiego del
valore di A nella espressione.
• Notazione Postfissa: (ad esempio, A++) significa
che l'incremento viene effettuato dopo l'impiego del
valore di A nella espressione.

Ad esempio:

int A=10, B;
char C=’a’;

B=++A; /*A e B valgono 11 */


B=A++; /* A=12, B=11 */
C++; /* C vale ’b’ */

int i, j, k;
k = 5;
i = ++k; /* i = 6, k = 6 */
j = i + k++; /* j=12, i=6,k=7 */

j = i + k++; /*equivale a:
j=i+k; k=k+1;*/

+ Si possono scrivere espressioni il cui valore e` difficile da predire:

k = 5;
j = ++k + k++; /* j=12,k=7 */

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 44


Espressioni relazionali:
Restituiscono un valore vero (in C, uguale a 1) o falso (in C, uguale a
0). Sono ottenute applicando gli operatori relazionali ad operandi
compatibili.
(3 < 7)
x <= y

Espressioni logiche:
Sono ottenute mediante gli operatori di:
• complemento (not) !
• congiunzione (and) &&
• disgiunzione (or) ||

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 45


Algebra di Boole:

{vero, falso}

A B A && B A || B !A
_______________________________________________
falso falso falso falso vero
falso vero falso vero vero
vero falso falso vero falso
vero vero vero vero falso

Proprieta‘:
!! A = A (idempotenza)
A || falso = A
A && vero = A
(A && B) && C = A && (B && C)
(A || B) || C = A || (B || C)
(A && B) || C = (A || C) && (B || C)
(A || B) && C = (A && C) || (B && C)

Leggi di De Morgan:
! (A && B) = (! A) || (! B)
! (A || B) = (! A) && (! B)

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 46


Valutazione di Espressioni
Nelle espressioni, gli operatori sono valutati secondo una precedenza
prestabilita (altrimenti parentesi tonde), e seguendo opportune regole
di associativita‘.

Precedenza ed Associativita‘ degli Operatori

La precedenza degli operatori è stabilita dalla sintassi delle


espressioni.

a+b*c

equivale sempre a

a + (b * c)

L'associatività è ancora stabilita dalla sintassi delle espressioni.

a+b+c

equivale sempre a

(a + b) + c

Regole di Precedenza e Associativita‘ degli Operatori C:

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 47


Operatore Associativita‘
() [] -> da sinistra a destra
! ~ ++ -- & sizeof da destra a sinistra
* / % da sinistra a destra
+ - da sinistra a destra
<< >> da sinistra a destra
< <= > >= da sinistra a destra
== != da sinistra a destra
& da sinistra a destra
^ da sinistra a destra
| da sinistra a destra
&& da sinistra a destra
|| da sinistra a destra
?: da destra a sinistra
=+ =- =* =/ da destra a sinistra
, da sinistra a destra

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 48


Espressioni
• E` possibile forzare le regole di precedenza mediante l'uso delle
parentesi.

• In caso di pari priorita`, l'ordine di valutazione e` quello testuale


(da sinistra a destra).

3*5 % 2 ù equivale a: (3*5) % 2


3 < 0 && 3 < 10 ù 0 && 1
3<(0 && 3) < 10 ù 3 < 0 < 10

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 49


Esercizi:
Sia V=5, A=17, B=34. Determinare il valore delle seguenti
espressioni logiche:

A<=20 || A>=40
! (B=A*2)
A<=B && A<=V
A>=B && A>=V
! (A>=B && A<=V)
! (A>=B) || !(A<=V)

Soluzioni:
A<=20 || A>=40 ù vero {A<20, short cut}
! (B=A*2) ù falso {B=34=17*2}
A<=B && A<=V ù falso {A>V}
A>=B && A>=V ù falso {A<B}
! (A<=B && A<=V) ù vero
! (A>=B) || !(A<=V) ù vero

/ Esercizio:
Determinare, applicando le leggi di De Morgan, se le seguenti
espressioni sono equivalenti:

! (A && B && C) (! A) or (! B) || (! C)
! (! A && ! B) A && B
! (! A || ! B) A && B
! (! A || ! B) A || B
Soluzioni: Nell’ordine: si‘, no, si‘ no.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 50


Istruzioni di ingresso ed uscita (input/output)
L'immissione dei dati di un programma e l’uscita dei suoi risultati
avvengono attraverso operazioni di lettura e scrittura.

Il C non ha istruzioni predefinite per l'input/output.

In ogni versione ANSI C, esiste una Libreria Standard (stdio) che


mette a disposizione alcune funzioni (dette funzioni di libreria) per
effettuare l'input e l'output.

Le dichiarazioni delle funzioni messe a disposizione da tale libreria


devono essere essere incluse nel programma: #include <stdio.h>

+ #include e` una direttiva per il preprocessore C:


nella fase precedente alla compilazione del programma ogni
direttiva “#...” viene eseguita, provocando delle modifiche testuali
al programma sorgente. Nel caso di #include
<nomefile>:
viene sostituita l’istruzione stessa con il contenuto del file
specificato.
Dispositivi standard di input e di output:
per ogni macchina, sono periferiche predefinite (generalmente
tastiera e video).

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 51


Input/Output
Il C vede le informazioni lette/scritte da/verso i dispositivi standard di
I/O come file sequenziali, cioe‘ sequenze di caratteri (o stream).

Gli stream di input/output possono contenere dei caratteri di controllo:


• End Of File (EOF)
• End Of Line
...
Sono disponibili funzioni di libreria per:

• Input/Output a caratteri
• Input/Output a stringhe di caratteri
• Input/Output con formato

a 7 1 3.7 b 57 * c 6

testina fine
lettura linea fine file
(EOF)
(ctrl-Z)

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 52


I/O con formato
Nell’I/O con formato occorre specificare il formato (tipo) dei dati che
si vogliono leggere oppure stampare.

Il formato stabilisce:
• come interpretare la sequenza dei caratteri immessi
dal dispositivo di ingresso (nel caso della lettura)
• con quale sequenza di caratteri rappresentare in
uscita i valori da stampare (nel caso di scrittura)
Lettura: scanf
E` una particolare forma di assegnamento: la scanf assegna i
valori letti alle variabili specificate come argomenti (nell'ordine di
lettura).

scanf(<stringa-formato>, <sequenza-variabili>);

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 53


scanf
Ad esempio:
int X;
float Y;
scanf("%d%f", &X, &Y);

• legge una serie di valori in base alle specifiche contenute in


<stringa-formato>: in questo caso "%d%f" indica che devo
leggere due valori, uno decimale (%d) ed uno reale (%f)
• memorizza i valori letti nelle variabili (X, Y nell'esempio)
• e` una funzione che restituisce il numero di valori letti e
memorizzati, oppure EOF in caso di end of file
+ Gli identificatori delle variabili a cui assegnare i valori sono
sempre preceduti dal simbolo &.
[Infatti le variabili devono essere specificate attraverso il loro
indirizzoù operatore & (v. puntatori e funzioni)]
+ La <stringa_formato> puo` contenere dei caratteri qualsiasi (che
vengono scartati, durante la lettura), che si prevede vengano
immessi dall’esterno, insieme ai dati da leggere.
Ad esempio:
scanf(“%d:%d:%d”, &A, &B, &C);
=> richiede che i tre dati da leggere vengano immessi separati
dal carattere “:”.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 54


Scrittura: printf
La printf viene utilizzata per fornire in uscita il valore di una
variabile, o, piu‘ in generale, il risultato di una espressione.
Anche in scrittura e‘ necessario specificare (mediante una
stringa di formato) il formato dei dati che si vogliono stampare.

printf(<stringa-formato>,<sequenza-elementi>)

Ad esempio:
int X;
float Y;
printf("%d%f", X*X,Y);

• scrive una serie di valori in base alle specifiche contenute in


<stringa-formato>. In questo caso, un intero (%d), ed un reale
(%f).

• i valori visualizzati sono i risultati delle espressioni che


compaiono come argomenti

• restituisce il numero di caratteri scritti.

• La stringa di formato della printf puo` contenere sequenze


costanti di caratteri da visualizzare.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 55


Esempio:
main()
{
int k;

scanf("%d",&k);
printf("Quadrato di %d: %d",k,k*k);
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 56


Input/Output

Formati più comuni:


short long
signed int %d %hd %ld
unsigned int %u (decimale) %hu %lu
%o (ottale) %ho %lo
%x (esadecimale) %hx %lx

float %e, %f, %g


double %le, %lf, %lg

carattere singolo %c
stringa di caratteri %s

puntatori (indirizzi) %p

Caratteri di controllo:
newline \n
tab \t
backspace \b
form feed \f
carriage return \r

Per la stampa del carattere ’%’ si usa: %%

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 57


Esempi:

scanf("%c%c%c%d%f", &c1,&c2,&c3,&i,&x);

Se in ingresso vengono dati:

ABC 3 7.345

le variabili
char c1 ’A’
char c2 ’B’
char c3 ’C’
int i 3
float x 7.345

char Nome=’F’;
char Cognome=’R’;
printf("%s\n%c. %c. \n\n%s\n",
"Programma scritto da:",
Nome,Cognome,"Fine");

ù viene stampato:

Programma scritto da:


F. R.

Fine

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 58


Esempi:
main()
{
int a;
printf("Da un carattere ottieni \
il valore decimale, ottale \
e hex ");
scanf("%c",a);
printf("\n%c vale %d in decimale, \
%o in ottale \
e %x in hex.\n",a, a, a, a);
}

main()
{
float x;
int ret, i;
char name[50];
printf("Inserisci un numero
decimale, ");
printf("un floating ed una stringa
con meno ");
printf("di 50 caratteri e senza
bianchi");
ret = scanf("%d%f%s",&i,&x,name);
printf("%d valori letti %d %f %s",
ret, i, x, name);
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 59


/ Esercizio:

Calcolo dell’orario previsto di arrivo.


Scrivere un programma che legga tre interi positivi da terminale,
rappresentanti l’orario di partenza (ore, minuti, secondi) di un vettore
aereo, legga un terzo intero positivo rappresentante il tempo di volo
in secondi e calcoli quindi l’orario di arrivo.
Approccio top-down:
Nel caso di un problema complesso puo` essere utile adottare una
metodologia top-down:

Si applica il principio di scomposizione, dividendo un problema in


sotto-problemi e sfruttando l’ipotesi di conoscere le loro soluzioni
per risolvere il problema di partenza:

a) dato un problema P ricavarne una soluzione attraverso la sua


scomposizione in sottoproblemi piu` semplici

b) eseguire a), b) per ogni sottoproblema individuato, che non sia


risolvibile attraverso l'esecuzione di un sottoproblema
elementare.

La soluzione finale si ottiene dopo una sequenza finita di passi di


raffinamento relativi ai sottoproblemi via via ottenuti, fino ad
ottenere sottoproblemi elementari.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 60


Prima specifica:

main()
{
/*dichiarazione dati */
/* leggi i dati di ingresso */
/*calcola l’orario di arrivo */
/*stampa l’orario di arrivo */
}

Codifica:

Come dati occorrono tre variabili intere per l’orario di partenza ed una
variabile intera per i secondi di volo.
/*definizione dati */
unsigned int Ore, Minuti, Secondi;
long unsigned int TempoDiVolo;

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 61


/*leggi i dati di ingresso*/:
/*leggi l’orario di partenza*/
printf("%s\n","Orario di partenza (hh,mm,ss)?");
scanf("%d%d%d\n", &Ore, &Minuti, &Secondi);
/*leggi il tempo di volo*/
printf("%s\n","Tempo di volo (in sec.)?");
scanf("%d\n", &TempoDiVolo);

/*calcola l’orario di arrivo*/:


Secondi = Secondi + TempoDiVolo;
Minuti = Minuti + Secondi / 60;
Secondi = Secondi % 60;
Ore = Ore + Minuti / 60;
Minuti = Minuti % 60;
Ore = Ore % 24;

/*stampa l’orario di arrivo*/:


printf("%s\n","Arrivo previsto alle (hh,mm,ss):");
printf("%d%c%d%c%d\n",
Ore,‘:’,Minuti,‘:’, Secondi);

Per Ore, Minuti, Secondi si puo` oltrepassare l’estremo superiore


dell’intervallo.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 62


main()
{
/*dichiarazione dati */
unsigned char Ore, Minuti, Secondi;
long unsigned int TempoDiVolo;
/*leggi i dati di ingresso*/:
/*leggi l’orario di partenza*/
printf("%s\n","Orario di partenza (hh,mm,ss)?");
scanf("%d%d%d", &Ore, &Minuti, &Secondi);
/*leggi il tempo di volo*/
printf("%s\n","Tempo di volo (in sec.)?");
scanf("%d", &TempoDiVolo);

/*calcola l’orario di arrivo*/


Secondi = Secondi + TempoDiVolo;
Minuti = Minuti + Secondi / 60;
Secondi = Secondi % 60;
Ore = Ore + Minuti / 60;
Minuti = Minuti % 60;
Ore = Ore % 24;

/*stampa l’orario di arrivo*/


printf("%s\n","Arrivo previsto alle (hh,mm,ss):");
printf("%d%c%d%c%d\n",
Ore,‘:’,Minuti,‘:’, Secondi);
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 63


/ Esercizio:

Calcolo della media di tre voti


Si scriva un programma che acquisisca in ingresso i voti relativi a
tre esami sostenuti da uno studente (si supponga che i voti siano
espressi in trentesimi).
Successivamente il programma deve:
• stampare la media dei voti riportati (espressa come numero
reale in trentesimi)
• convertire e stampare i voti in centesimi
• stampare la media espressa in centesimi

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 64


#include <stdio.h>

main()
{
const float conv= 100.0/30.0;
int voto1, voto2, voto3;
float v1c, v2c, v3c, media;
/* Parte 1: Acquisizione dei dati */
printf(“Immetti il primo voto: “);
scanf(“%d”, &voto1);
printf(“\nImmetti il secondo voto: “);
scanf(“%d”, &voto2);
printf(“\nImmetti il terzo voto: “);
scanf(“%d”, &voto3);

/* Parte 2: Calcolo dei risultati */


v1c=voto1 * conv;
v2c=voto2 * conv;
v3c=voto3 * conv;
printf(“\nMedia in trentesimi: %f\n”,
(voto1+voto2+voto3)/3.0);
printf(“Voti convertiti in centesimi\n”);
printf(“Voto 1:\t%f\nVoto 2:\t%f\nVoto 3”
“:\t%f\n”, v1c, c2c, v3c”);
media=(v1c+v2c+v3c)/3;
printf(“Media in centesimi: %f\n”,media);
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 65


Istruzioni di controllo
• istruzione composta: (blocco)
• istruzioni condizionali: (selezione)
• istruzioni di iterazione: (ciclo)

Sono alla base della programmazione strutturata.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 66


Programmazione strutturata (Dijkstra, 1969)
La programmazione strutturata nasce come proposta per
regolamentare e standardizzare le metodologie di
programmazione.
Obiettivo:
rendere piu’ facile la lettura dei programmi (e quindi la loro
modifica e manutenzione).

Idea di base:

eliminazione dei salti incondizionati

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 67


Programmazione Strutturata
+ Abolizione di salti incondizionati (goto) nel flusso di controllo.

ù La parte istruzioni (o parte esecutiva) di un programma viene


vista come un comando (complesso, o strutturato) ottenuto
componendo comandi elementari (assegnamento, chiamata di
procedura), mediante alcune regole di composizione (strutture
di controllo).
Strutture di controllo:
• concatenazione (o composizione);
• alternativa (o istruzione condizionale) che ramifica il flusso di
controllo in base al valore di un’espressione (logica o
relazionale);
• ripetizione (o iterazione) che provoca l’esecuzione ripetuta di
un’istruzione (eventualmente composta) finche` un’espressione
booleana rimane vera.
Vantaggi:
• leggibilita`
• supporto a metodologia di progetto top-down
• supporto a metodologia bottom-up
• facilita` di verifica e manutenzione

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 68


Strutture di controllo

Caratteristiche:
• Hanno un solo punto di ingresso ed un solo punto di uscita.
• Possono essere interpretate come una singola azione in una
computazione sequenziale.
• I programmi sono più leggibili

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 69


Concatenazione

{I1; I2; ...; In}

I1

I2

I3

In

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 70


Esempio: istruzione composta
 SURJUDPPDFKHOHWWLGXHQXPHULD
WHUPLQDOHQHVWDPSDODVRPPD 
LQFOXGHVWGLRK!
PDLQ
^
LQW;<

SULQWI ³,QVHULVFLGXHQXPHUL´ 
^
VFDQI GG ; < 
SULQWI G;< 
`

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 71


Istruzioni di alternativa

Istruzione if:
if (<espressione>)
<istruzione1>
else
<istruzione2>;

se il risultato di espressione è vero (diverso da zero) viene


eseguita l’istruzione 1, altrimenti viene eseguita l’istruzione 2.

(!=0) (==0)
espressione

Istruzione1 Istruzione2

La parte else è opzionale.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 72


Esempio:
Programma che legge due numeri e determina qual è il
maggiore.

/* determina il maggiore tra due numeri


file c2.c */

#include <stdio.h>
main()
{
int primo,secondo;

scanf("%d%d",&primo,&secondo);
if (primo>secondo)
printf("%d",primo);
else printf("%d",secondo);
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 73


<istruzione1> ed <istruzione2> possono essere di tipo qualunque,
semplice o strutturato, eventualmente anche un’istruzione
composta:

Esempio: if
/* Programma che calcola le radici di
un’equazione di secondo grado*/

#include <stdio.h>
#include <math.h> /*lib. matematica*/
main()
{
int a,b,c;
float d,x1,x2;

scanf("%d%d%d",&a,&b,&c);
if ((b*b) < (4*a*c))
printf("%s","radici complesse");
else
{
printf("%d%d%d",a,b,c);
d=sqrt(b*b-4*a*c);
x1=(-b+d)/(2*a);
x2=(-b-d)/(2*a);
printf("%f%f",x1,x2);
};
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 74


/ Esercizio:
Risolvere un sistema lineare di due equazioni in due incognite
a1x + b1y = c1
a2x + b2y = c2

x = (c1b2-c2b1) / (a1b2- a2b1) = XN / D


y = (a1c2- a2c1) / (a1b2- a2b1) = YN / D
Soluzione:
#include <stdio.h>
main()
{
int A1,B1,C1,A2,B2,C2,XN,YN,D;
float X,Y;

scanf("%d%d%d%\n",&A1,&B1,&C1);
scanf("%d%d%d%\n",&A2,&B2,&C2);
XN = (C1*B2 - C2*B1);
D = (A1*B2 - A2*B1);
YN = (A1*C2 - A2*C1);
if (D == 0)
{if (XN == 0)
printf("sist. indeterm.\n");
else
printf("Nessuna soluz.\n");
}
else
{X= XN/D;
Y= YN/D;
printf("%f%f\n",X,Y);
}
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 75


Istruzione if:
if (<espressione>)
<istruzione1>
else
<istruzione2>;

• <istruzione1> ed <istruzione2> possono essere ancora istruzioni


if.

+ Si possono avere piu` istruzioni if annidate:

if (<e1>)
if (<e2>)
<i1>;
else
<i2>;

(==0) (!=0)
e1

(==0) (!=0)
e2

i2 i1

L’else si riferisce sempre all’if più “interno”, se non specificato


altrimenti.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 76


if (n > 0)
if (a > b)
n = a; /*n > 0 && a > b */
else n = b; /* n > 0 && a <= b */

+ Se si vuole riferire l’else all’if piu‘ esterno, si usano le graffe:

if (n > 0)
{ if (a > b) n = a; }/*n>0 && a>b */
else
n = b; /* n <= 0 */

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 77


If annidati
/ Esercizio:
Dati tre numeri interi positivi che rappresentano i tre lati di un
triangolo, si stampi il tipo del triangolo (equilatero, isoscele o
scaleno).

Prima specifica:

main()
{
/*dichiarazione dati */
/* leggi le lunghezze dei lati */
/*se triangolo, stampane il tipo */
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 78


Codifica:
Come dati occorrono tre variabili intere per rappresentare le
lunghezze dei segmenti.

/*dichiarazione dati */
unsigned int primo,secondo,terzo;

/* leggi le lunghezze dei segmenti */


scanf("%d%d%d",&primo,&secondo,&terzo);

/*se triangolo, stampane il tipo */


if (primo + secondo>terzo)
if (primo==secondo)/*det. il tipo */
{if (secondo==terzo)
printf("equilatero");
else
printf("isoscele");}
else
{if (secondo==terzo)
printf("isoscele");
else
{if (primo==terzo)
printf("isoscele");
else
printf("scaleno");}
}
Annidamento:
l’“indent” delle linee del testo del programma rispetta
l’annidamento delle varie istruzioni ù si aumenta la leggibilita` del
programma (modifica piu` facile).

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 79


Istruzione di Alternativa Multipla: Switch

Switch:
switch (<EspressioneIntegralType>)
{
case <costante1>: <blocco1>; [break;]
case <costante2>: <blocco2>; [break;]
...
case <costanteN>: <bloccoN>; [break;]
[default: <bloccoDiDefault>;]
}

• L’espressione e` detta selettore. Deve avere un valore di tipo


IntegralType (enumerabile).

• Ciascuna costante di una etichetta case deve essere dello


stesso tipo del selettore.

• Un valore puo` comparire al piu` in un’etichetta.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 80


Istruzione Switch

Significato:
Se l’espressione ha un valore che corrisponde ad una costante (per
esempio <costante1>), si esegue il <blocco1> e tutti i blocchi dei rami
successivi.

+ Le alternative non sono mutuamente esclusive: possibilità di


eseguire in sequenza più blocchi contigui di istruzioni.

+ Necessità di forzare l’uscita mediante l'istruzione break (che


provoca l'uscita forzata dallo switch).

Ramo di default:
E` possibile specificare un'etichetta default: essa viene eseguita per
qualunque valore ritornato da selettore.
In pratica, consente di utilizzare una “alternativa” che viene eseguita
se il valore dell'espressione non corrisponde ad alcuna etichetta.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 81


Esercizio

#include <stdio.h>

#define GENNAIO 1
#define FEBBRAIO 2
#define MARZO 3
#define APRILE 4
......
#define OTTOBRE 10
#define NOVEMBRE 11
#define DICEMBRE 12
main()
{
...
switch (mese)
{
case GENNAIO: giorni = 31; break;
case FEBBRAIO:
if (bisestile) giorni = 29;
else giorni = 28;
break;
case MARZO: giorni = 31; break;
...
case DICEMBRE: giorni = 31;
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 82


2a soluzione:

switch (mese)
{
case FEBBRAIO:
if (bisestile) giorni = 29;
else giorni = 28;
break;
case APRILE: giorni = 30; break;
case GIUGNO: giorni = 30; break;
case SETTEMBRE: giorni = 30; break;
case NOVEMBRE: giorni = 30; break;
default: giorni = 31;
}

3a soluzione:

switch (mese)
{
case FEBBRAIO:
if (bisestile) giorni = 29;
else giorni = 28;
break;
case APRILE:
case GIUGNO:
case SETTEMBRE:
case NOVEMBRE: giorni = 30; break;
default: giorni = 31;
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 83


Calcolo della data
Scrivere un programma che letta una data di un giorno G
(espressa nel formato “giorno/mese/anno”), calcoli la data del
giorno successivo a G.
Soluzione
Per risolvere il problema, si ricordi che un anno non è bisestile:
• se non è divisibile per 4
• se è divisibile per 4 ed è multiplo di 100, ma non è multiplo di
400
• in un anno bisestile il mese di febbraio ha 29 giorni
Il programma che risolve il problema è il seguente:

#include <stdio.h>

#define GENNAIO 1
#define FEBBRAIO 2
#define MARZO 3
......
#define OTTOBRE 10
#define NOVEMBRE 11
#define DICEMBRE 12

main()
{
int g1,g2;
int m1,m2;
int a1,a2;
int m, durata;
/* acquisizione dei dati */
printf(“Dammi la data (giorno/mese/anno): “):
scanf(“%d/%d/%d”,&g1,&m,&a1);
m1=m;

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 84


/* calcolo della durata del mese */
switch(m1)
{
case FEBBRAIO:
if (a1%4==0)
if (a1%100==0 && a1%400!=0)
durata=28;
else durata = 29;
else durata = 28;
break;
case APRILE:
case GIUGNO:
case SETTEMBRE:
case NOVEMBRE: durata = 30; break;
default: durata = 31;
}
/* calcolo della data del giorno successivo
*/
if (g1==durata)
/* e’ l’ultimo giorno del mese */
{
g2=1;
if (m1==DICEMBRE)
{
m2=GENNAIO;
a2=a1+1;
}
else
{
m2=m1+1;
a2=a1;
}
}
else /* non e’ l’ultimo giorno del mese */
{
g2=g1+1;
m2=m1;

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 85


a2=a1;
}
printf(“Il giorno successivo al %d/%d/%d e’:
%d/%d/%d\n”,g1,m1,a1,g2,m2,a2);
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 86


Esempio: Una calcolatrice
Si vuole realizzare un programma che emuli il comportamento di
una calcolatrice in grado di effettuare le operazioni aritmetiche su
due operandi A e B.
Si supponga che l’utente immetta l’operazione nel formato:
A op B =
dove op puo` valere +, -, *, /, %, :.

#include <stdio.h>

main()
{
int A, B;
char op;

printf("Digita l’operazione che vuoi effettuare


[formato da usare A op B=] :\n");
scanf("%d%c%d =", &A, &op, &B);
switch (op)
{
case ’+’: printf("%d\n", A+B);break;
case ’-’: printf("%d\n", A-B);break;
case ’*’: printf("%d\n", A*B);break;
case ’%’: printf("%d\n", A%B);break;
case ’/’: printf("%d\n", A/B);break;
case ’:’: printf("%f\n",(float)A/(float)B);break; /*
divisione non intera*/
default: printf("\n operazione non prevista\n");
}
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 87


Istruzioni di iterazione

Istruzione while:

while (<espressione>)
<istruzione>;

(==0) (!=0)
Espressione

Istruzione

L’epressione (condizione di ripetizione) viene valutata all’inizio di


ogni ciclo.
• Il ciclo viene eseguito finche` il valore dell’espressione rimane
diverso da zero (vero logico).
• Si esce dal ciclo quando l’espressione restituisce un valore = 0
(falso logico).
• Se inizialmente ha valore zero, il corpo del ciclo non viene mai
eseguito.

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 88


/ Esercizio:
Scrivere un programma che calcoli la media degli N voti riportati
da uno studente.

/* Media di n voti */
#include <stdio.h>
main()
{
int sum,voto,N,i;
float media;

printf(“Quanti sono i voti ?”);


scanf("%d",&N);
sum=0;
/* ripeti ...*/
printf(“Dammi un voto:”);
scanf("%d",&voto);
sum=sum+voto;
/* ... per N volte */
media=sum/N;
printf("Risultato: %f",media);
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 89


Esercizio (continua):

/* Media di n voti*/
#include <stdio.h>
main()
{
int sum,voto,N,i;
float media;

printf(“Quanti sono i voti ?”);


scanf("%d",&N);
sum=0;
i=1;
while (i <= N)
{ /* corpo ciclo while */
printf(“Dammi il voto n.%d:”,sum);
scanf("%d",&voto);
sum=sum+voto;
i=i+1;
}
media=sum/N;
printf("Risultato: %f",media);
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 90


/ Esercizio:
Programma che calcola il prodotto X*Y come sequenza di
somme (si suppone Y>0, X >=0).

INIZIO

READ:
X,Y

Z:=0

SI
X=0

NO
ciclo

X:=X-1

Z:=Z+Y

WRITE:
Z

FINE

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 91


Codifica:

/* moltiplicazione come sequenza di


somme */
#include <stdio.h>
main()
{
int X,Y,Z;

printf(“Dammi i fattori:”);
scanf("%d%d",&X,&Y);
Z=0;
while (X!=0)
{ /* corpo ciclo while */
Z=Z+Y;
X=X-1;
}
printf("%d",Z);
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 92


Cicli Innestati
while (<espressione>)
<istruzione>;

• <istruzione> puo` essere a sua volta una istruzione while ù cicli


innestati

/ Esercizio:
Si legga un numero naturale N. Stampare una volta il numero 1,
due volte il numero 2,..., N volte il numero N.
• Dominio di ingresso (0,1,2,...,N)
• Dominio di uscita ((), (1), (1,2,2),(1,2,2,3,3,3)...).

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 93


INIZIO

LEGGI:
N

I:=1

SI
I>N

NO

J:=1

STAMPA:
I

J:=J+1

NO
J>I

SI

I := I + 1

FINE

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 94


Codifica:
#include <stdio.h>
main()
{
int N,I,J;

printf(“dammi N:”);
scanf("%d",&N);
I=1;
while (I<=N)
{ /* corpo ciclo esterno */
printf(“Prossimo valore:”);
printf("%d",I);
J=1;
while (J<I)
{ /* corpo ciclo interno */
printf("%d",I);
J=J+1;
}
I=I+1;
}
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 95


/ Esercizio:
Stabilire se un numero naturale N e‘ primo.
(Un numero naturale N e‘ primo, se non e‘ divisibile per alcun
numero intero minore di esso.)

Nota: non e‘ necessario eseguire tutte le divisioni di N per 2, 3,


..., (n-1), ma basta eseguire le divisioni per i naturali minori o
uguali alla radice quadrata di N.

/* Numero primo */
#include <stdio.h>
#include <math.h>
#define true 1
#define false 0

main()
{
int N, I;
float N1;
int primo;

scanf("%d",&N);
N1=sqrt(N);
I=2;primo=true;
while ((I<=N1) && (primo==true))
{if (((N / I) * I) == N)
{primo=false;}
else I=I+1; }
if (primo==true)
printf("numero primo");
else printf("numero non primo");
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 96


/ Esercizio:
Calcolo del fattoriale di un numero intero non negativo N:

• fattoriale(0) = 1
• fattoriale(N) = N * (N-1)*...*1=fattoriale(N-1)*N

/* Calcolo del fattoriale */


#include <stdio.h>
#include <math.h>
main()
{
int N, F, I;
printf(“Dammi N:”);
scanf("%d",&N);
F=1;
I=2;
while (I <= N)
{ F=F*I;
I=I+1; }
printf("%s%d","Fattoriale: ",F);
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 97


Esempio:
Divisione tra numeri interi positivi attraverso somma e sottrazione.

/* divisione tra interi positivi */


#include <stdio.h>
main()
{
unsigned int X,Y,Quoz,Resto;

scanf("%d%d",&X,&Y);
Resto=X;
Quoz=0;
while (Resto >= Y)
{ Quoz=Quoz+1;
Resto=Resto-Y; }
printf("%d%s%d%s%d%s%d",
X," diviso ", Y, " = ", Quoz,
" resto ", Resto);
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 98


Istruzioni di iterazione

Istruzione do:

do
<istruzione>
while (<espressione>);

• Nell'istruzione while, la condizione di ripetizione viene


verificata all’inizio di ogni ciclo

somma=0; j=1;
while (j <= n)
{ somma = somma + j; j++; }

• Nell’istruzione do la condizione di ripetizione viene verificata


alla fine di ogni ciclo

/* In questo caso: n >0 */


somma = 0; j = 1;
do
{ somma = somma + j; j++; }
while (j <= n);

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 99


Istruzione do:

S1

... do
S1;
S2;
Sn ...
Sn
while Espressione
true
Espressione

false

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 100


Esempio:
do
scanf("%c",&Car)
while (Car !=’ ’) /* salta spazi
bianchi */

Prima dell’esecuzione del ciclo, il valore di Car e` indeterminato.

Con il while:

Car=’ ’;
while (Car==’ ’)
scanf("%c", &Car);

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 101


Istruzioni di Iterazione
Istruzione for:

for(<espressione1>; <espressione2>; <espressione3>)


<istruzione>;

• <espressione1> e` l'espressione di inizializzazione: viene


eseguita una volta sola, prima di entrare nel ciclo
• <espressione2> rappresenta la condizione di permanenza nel
ciclo (valutata all'inizio di ogni iterazione)
• <espressione3> e` l'espressione di passaggio al ciclo successivo
(valutata alla fine di ogni iterazione).

for è equivalente a:
<espressione1>; /* Inizializzazione */
while (<espressione2>) /* Condizione di
Ripetizione */
{
<istruzione>;
<espressione3>; /* InizioNuovoCiclo */
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 102


Esempio while/for:

somma = 0; /* while */
j = 1;
while (j <= n)
{
somma=somma+j;
j++;
}

con il for:
somma = 0; /* for */
for(j=1;j<=n;j++)
somma = somma + j;

Esempio calcolo del fattoriale:

/* Calcolo del fattoriale */


#include <stdio.h>
#include <math.h>
main()
{
int N, F, I;

printf(“Dammi N:”);
scanf("%d",&N);
F=1;
for (I=2,I <= N, I++)
{ F=F*I;
I=I+1; }
printf("%s%d","Fattoriale: ",F);
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 103


For:
for(<espressione1>; <espressione2>; <espressione3>)
<istruzione>;

• Ognuna delle espressioni può essere omessa (il punto e


virgola deve rimanere)
• Se manca espressione2, si ha un ciclo infinito.

Cosa eseguono i seguenti for ?

for (i = 1; i <= n; i++) printf("%d ",i);


for (;;) { ... }

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 104


Istruzioni per il trasferimento del controllo:

Istruzione break:
L’istruzione break provoca l’uscita immediata dal ciclo (o da
un’istruzione switch) in cui è racchiusa

false true
Condizione

Blocco di
Istruzioni

break

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 105


Istruzione continue:
L’istruzione continue provoca l’inizio della successiva iterazione
del ciclo in cui è racchiusa (non si applica a switch).

Esempio continue:

for (i = N; i > 0; i – – )
{
/* Salta alla prossima ripetizione
se N è multiplo di i */
if (N % i) continue;
/* Esci dal ciclo se i vale 55 */
if (i == 55) break;
...
}

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 106


Istruzione goto:

goto label

L’istruzione goto provoca il salto all’istruzione etichettata


dall’etichetta label.

Una label è un identificatore seguito da un due punti e può


essere applicata ad una qualunque istruzione della medesima
funzione in cui si trova il goto

...
goto errore;
...
errore: ...
...

Formalmente l'istruzione goto non è necessaria.

Usare il goto solo nei rari casi in cui il suo uso rende più leggibile
il codice - ad esempio:
• per uscire dall'interno di strutture molto nidificate
• per convergere in caso di errore, in un unico punto da punti
diversi del programma

Problemi se si entra in flusso innestato


(procedure o blocchi)

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 107


Esercizi:

Leggere una sequenza di numeri interi a terminale e calcolarne la


somma, nei seguenti casi:

1) La lunghezza della sequenza non e` nota, ma l’ultimo valore e`


seguito da un intero negativo (while);

2) Come il caso 1, ma sicuramente la sequenza ha lunghezza


maggiore o uguale ad uno (do);

3) La sequenza di numeri da sommare e` preceduta da un numero


intero che rappresenta la lunghezza della sequenza (for);

4) La sequenza contiene un intero per ogni linea ed il termine della


sequenza di ingresso e` segnalato con il carattere di fine file
(Ctrl-Z) (test eof).

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 108


Espressioni (complementi)

Operatori sui bit:

<< shift a sinistra k<<4 shift a sinistra di 4 bit


equivale a k*16
>> shift a destra k>>4 shift a destra di 4 bit
equivale a k/16
& and bit a bit c nnnn‘nn
| or inclusivo bit a bit
^ or esclusivo bit a bit
~ complemento a 1

Operatore condizionale:
?: condizione ? parteVera : parteFalse
• la parteVera viene valutata solo se la condizione è verificata
(valore diverso da 0)
• la parteFalse viene valutata solo se la condizione non è
verificata (valore uguale a zero)

x = (y != 0 ? 1/y : INFINITY);
k = a < b ? a : b; /* assegna il minore */

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 109


Assegnamento (forma abbreviata)

v op= e è quasi equivalente a v = v op (e)

dove op è uno dei seguenti operatori:

+ – * / % >> << & ^ |

k += j /* equivale a k = k + j */
k *= a + b /* equivale a k = k * (a + b) */

Le due forme sono quasi equivalenti perchè in:


v op= e
v viene valutato una sola volta, mentre in:
v = v op (e)
v viene valutato due volte.

Se la valutazione di v non genera effetti collaterali (side effects)


le due forme sono del tutto equivalenti,
in caso contrario le due forme non sono equivalenti

FONDAMENTI DI INFORMATICA IL LINGUAGGIO C 110