Informatica
Grafica
Fondamenti di
Linguaggio C
Prof. M. Roveri
2. Variabili
Una variabile pu essere descritta come un contenitore, il cui contenuto sempre a disposizione e rappresenta il
valore della variabile stessa.
Ad ogni variabile e' associato:
un nome (identificatore);
un tipo (insieme dei valori che puo' assumere);
un'area di memoria (per contenere il valore assunto);
un indirizzo (riferimento all'area di memoria);
un valore (in istanti diversi la variabile pu assumere valori differenti, purch coerenti con il tipo).
Il C un linguaggio:
tipato, poich le variabili sono dotate di tipo.
non strettamente tipato, poich i controlli sui tipi non sono stretti a differenza, per esempio, di quanto avviene nel
Pascal (linguaggio strettamente tipato).
short (dichiarabile nei seguenti modi short int, signed short, signed short int);
int (dichiarabile nei seguenti modi signed int, signed);
long (dichiarabile nei seguenti modi long int, signed long, signed long int).
Il loro intervallo di definizione va da -2 n-1 a +2 n-1 -1, dove n dipende dal compilatore e rappresenta il numero di bit
impiegati per la loro rappresentazione.
Analizzando la loro occupazione in memoria (direttamente legata al numero di bit con il quale il dato memorizzato e
quindi allintervallo di rappresentazione), valgono le seguenti relazioni:
sizeof(short) <= sizeof(int) <= sizeof(long);
sizeof(short) >= 2 (ovvero, almeno 16 bit);
sizeof(long) >= 4 (ovvero, almeno 32 bit).
Loperatore sizeof() in C ritorna il numero di byte occupati da una variabile o da un tipo di dato che gli viene passato
come operando.
I valori limite sono contenuti nel file limits.h, che definisce le costanti:
SHRT_MIN, SHRT_MAX, INT_MIN, INT_MAX, LONG_MIN, LONG_MAX
Queste costanti possono ad esempio servire in un programma per controllare se il dato immesso da un utente cade
nellintervallo di rappresentazione. Se non lo fosse, possiamo segnalarlo allutente al posto che far continuare
lesecuzione e generare quindi un probabile errore di overflow/underflow.
Se si vuole dichiarare una costante, si scriveranno i numeri interi semplicemente in decimale, ad esempio 0, 10, -10, . .
.
Gli operatori utilizzabili sono: +, -, *, /, %, ==, !=, <, >, <=, >=
Per quanto riguarda le funzioni di ingresso/uscita si usano le funzioni printf e scanf, con i seguenti indicatori di formato
(dove d indica decimale):
%hd per short
%d per int
%ld per long (con l minuscola)
Ad esempio per stampare un intero che era stato definito come short si pu scrivere:
printf(%hd", contatore);
4. Costanti
Riepiloghiamo quanto visto precedentemente sulle costanti.
Costanti intere:
decimali: la prima cifra deve essere significativa.
Es.: 23
ottali: 0oooo Prefisso 0 (zero).
o= cifra ottale ([0..7]).
Es.: 034
esadecimali: 0xhhhh Prefisso 0x o 0X.
h= cifra esadecimale ([0..9,a..f,A..F]).
Es.: 0x12A
suffisso:
U o u: indica interi di tipo unsigned. (Es.: 50000U, 0xf000U)
L o l: indica interi di tipo long. (Es.: 34L, 50000000L)
UL o ul: indica interi di tipo unsigned long. (Es.: 34UL)
Costanti reali:
per default sono di tipo double (Es.: 3.14, 314e-2).
il suffisso F o f indica numeri reali di tipo float (Es.: 3.14F).
L o l indica numeri reali di tipo long double (Es.: 3.14L).
Costanti carattere:
Le costanti carattere sono indicate fra apici.
Ad esempio: a, F.
Vi sono alcune costanti carattere speciali (utilizzabili soprattutto nelle printf):
'\a' segnale di alert <BELL> (beep)
'\b' spazio indietro <BS> (backspace)
'\f' salto pagina <FF> (form feed)
'\n' a capo <LF> new line (line feed)
'\r' ritorno a inizio riga <CR> (carriage return)
'\t' tabulazione orizzontale <TAB>
'\v' tabulazione verticale <VT> (vertical tab)
'\?' ? (punto interrogativo)
'\\' \ (back slash)
'\'' ' (apice singolo)
5. Strutture di controllo
Le istruzioni di controllo del flusso specificano lordine secondo il quale i calcoli devono essere effettuati.
5.2 Blocchi
In C i blocchi sono realizzati mediante l'uso delle parentesi graffe dentro le quali vi una sequenza di istruzioni.
E' possibile dichiarare delle variabili locali all'interno di un blocco di istruzioni C. I blocchi possono essere innestati uno
dentro laltro a piacere: le dichiarazioni delle variabili locali seguono immediatamente la parentesi sinistra e
precedono la parte eseguibile del blocco.
{ dichiarazioni istruzioni }
L'impiego dei blocchi finalizzato alla:
scrittura di un insieme di istruzioni (nei casi in cui la sintassi permetta l'inserimento di solamente una istruzione);
definizione del corpo di una funzione.
Esempio 1:
int a, b;
....
{ int temp; /* parte dichiarativa del blocco */
temp = a;
a = b;
b = temp;
} /* Attenzione: da qui in poi la variabile temp cessa di esistere */
Esempio 2:
{} /* blocco vuoto */
Valgono le usuali regole di visibilit: le variabili locali sono visibili dal punto della loro dichiarazione fino alla fine del
blocco cui appartengono; inoltre, le variabili locali nascondono (rendendo non accessibili) le variabili omonime globali,
cio dichiarate in blocchi pi esterni
5.3.1 Costrutto IF
E composto da una espressione e uno/due/tre/enne blocchi di codice (chiamati i "rami" dell'if).
Le due forme tipiche in cui si pu presentare la sintassi relativa al costrutto IF sono le seguenti:
1 caso:
if (espressione)
istruzione_1
2 caso:
if (espressione)
istruzione_1
else
istruzione_2
istruzione_1 viene eseguita se espressione, una volta valutata assieme a tutti i suoi effetti collaterali, torna un
valore vero (cio non zero); altrimenti se espressione torna un valore falso (cioe' uguale a zero) viene eseguita
istruzione_2, se esistente.
Nel caso di IF innestate, la parte else viene abbinata sempre all'ultima if posta nello stesso blocco della else, ma non
gia' abbinata ad una precedente else.
Per migliorare la leggibilita' e' consigliata una buona e coerente indentazione del programma, tale che rispecchi la
struttura del codice.
Per evitare possibili ambiguita' nelle IF innestate, e' possibile l'utilizzo di blocchi per racchiudere i costrutti piu' interni.
Esempio 1:
if (a > b)
m = 0;
else
m = 5;
Esempio 2:
if (a > b)
if (c > d)
n = 0;
else
m = 5; /* a > b e c <= d */
Esempio 3:
if (a > b)
{
if (c > d)
n = 0;
}
else
m = 5; /* a <= b */
Esempio 4 (con N istruzioni):
if (expr1)
istr1
else
if (expr2)
istr2
else
if (expr3)
istr3
else
if (expr4)
istr4
else
istr5
break;
case '1':
n_cifre = n_cifre + 1;
break;
.....
case '9':
n_cifre = n_cifre + 1;
break;
case ' ':
n_separatori = n_separatori + 1;
break;
case '\n':
n_separatori = n_separatori + 1;
break;
case '\t':
n_separatori = n_separatori + 1;
break;
default:
n_altri = n_altri + 1;
}
...
Il problema principale delle strutture iterative che possono entrare in ciclo infinito. Questo accade se per un errore
di programmazione o per qualche condizione esterna alla espressione del while rimane sempre vera.
All'interno del blocco di istruzioni puo' comparire l'istruzione BREAK che, se eseguita, provoca il termine del WHILE
nonch l'istruzione CONTINUE che, una volta invocata, forza linizio delliterazione successiva del ciclo, provoca cio
lesecuzione immediata della parte di controllo del ciclo.
In caso di cicli innestati, entrambe le istruzioni BREAK e CONTINUE non hanno influenza sui cicli piu' esterni.
Esempio: vengono sommati i numeri interi che lutente immette da tastiera fino a quando non viene immesso uno
zero.
#include <stdio.h>
int main()
{
int i, somma;
somma = 0;
i = 1; // valore iniziale (serve solo per entrare nel while)
while (i != 0)
{
scanf ("%d" , &i);
somma = somma + i;
}
printf("La somma e' %d", somma);
istruzionen
}
in cui:
expr1 lespressione iniziale,
expr2 lespressione booleana (del ciclo),
expr3 lespressione incremento.
L'espressione iniziale permette di inizializzare le variabili di ciclo e viene eseguita una volta sola, prima di qualsiasi altra
operazione.
Esempio: contatore = 0.
Successivamente ad essa, viene valutata l'espressione del ciclo e, se questa ha valore diverso da 0, viene eseguita
l'istruzione che costituisce il corpo del ciclo (o il blocco di istruzioni fra parentesi graffe).
Esempio: contatore < 9.
Al termine dell'esecuzione del corpo del ciclo, viene valutata l'espressione-incremento, di solito per poter aggiornare i
valori delle variabili di ciclo.
Esempio: contatore = contatore + 1.
Quindi, si valuta nuovamente l'espressione del ciclo e cosi via. Il ciclo si ripete finch non si valuta come falsa
l'espressione del ciclo (valore 0).
Allinterno di un blocco di istruzioni pu comparire l'istruzione BREAK che, se eseguita, provoca il termine del FOR
nonche' l'istruzione CONTINUE che, una volta invocata, forza linizio delliterazione successiva del ciclo dopo avere
valutato espr3.
In caso di cicli innestati, entrambe le istruzioni BREAK e CONTINUE non hanno influenza sui cicli piu' esterni
6. ISTRUZIONI DI INPUT/OUTPUT
6.1 Output: printf
Obiettivo: dichiarare una variabile i intera, assegnarvi un valore e stamparla a video.
Un semplice programma che esegue queste azioni il seguente:
#include <stdio.h>
int main()
{
int i;
i = 3;
printf("%d", i);
}
Nella parte dichiarativa si dichiara la variabile i come variabile intera (int). Nella prima riga della parte esecutiva si
assegna il valore 3 alla variabile i.
La terza riga del main chiama la funzione printf che permette di stampare la variabile i passata (alla destra della
virgola) a terminale. Alla sinistra della virgola presente una stringa chiamata stringa di controllo. Essa ha il compito di
definire in che modo il contenuto della variabile i debba essere stampato. Ad esempio %d significa che i verr
stampata come un intero: a monitor comparir il numero 3.
Come gi visto, se si scrive:
printf("Hello WORLD");
compare a monitor:
Hello WORLD
Se invce si scrive:
printf("Il valore contenuto e: %d", i)
compare a monitor:
Il valore contenuto e: 3
Questo accade poich la funzione printf stampa la stringa di controllo e sostituisce alle parti della stringa che iniziano
con % (in questo caso %d) i valori delle variabili passati alla destra della virgola (il valore di i).