IL LINGUAGGIO ”C”
Per l’eleganza della sintassi e la compattezza dei
costrutti, il C è una sfida permanente alle capacità
intellettuali del programmatore.
E’ un linguaggio di alto livello con un insieme ristretto
di costrutti di controllo e parole chiave (circa
trenta), ma possiede un buon numero di operatori.
Il C e' diventato un linguaggio professionale
ampiamente utilizzato perché ha appunto strutture di
alto livello ma può maneggiare attività di basso livello.
Produce inoltre programmi efficienti e può essere
compilato su un'ampia gamma di sistemi operativi.
Il primo programma in “C”
Il più semplice in assoluto è il famoso "Hello World!"
(Ciao Mondo) che ha soltanto lo scopo di stampare a
video la suddetta scrittura.
1
2
3
4
5
6
7
8
9
10
/* Un primo programma in C */
#include <stdio.h>
int main ()
{
printf("Hello World! \n");
return 0;
}
Analizziamo le singole righe
Si comincia con
/* ……. */ alla riga 1 per indicare che questa
linea è di commento.
I programmatori inseriscono dei commenti per documentare i
programmi e migliorare la loro leggibilità.
Alla riga 3 troviamo una direttiva per il prepocessore. Le righe che
cominciano con # sono comandi che permettono di richiamare le
librerie del C, in questo caso quella che ci permette di eseguire le
operazioni di input-output (stdio.h = standard i/o) come printf.
La main è la funzione principale in un qualsiasi programma e
identifica il punto d’inizio dell’esecuzione. All’interno delle parentesi
tonde si possono inserire, se necessari, dei parametri.
La parentesi graffa aperta deve aprire il corpo di ogni funzione e
una corrispondente parentesi graffa chiusa lo deve chiudere. La
parte contenuta fra le due parentesi è detta blocco.
Analizziamo le singole righe
Alla riga 7 l’istruzione printf ordina al computer di eseguire
un’azione: visualizzare sullo schermo la stringa di caratteri indicata
fra le virgolette. La sequenza \n significa newline e provoca il
posizionamento del cursore sulla riga successiva alla stringa
stampata.
Il punto e virgola, invece, serve per "chiudere" un'istruzione, per
far capire che dopo quel simbolo inizia una nuova istruzione.
La riga 10, return 0; è inclusa alla fine di ogni main ed indica che il
programma è terminato con successo.
N.B. Per poter visualizzare il risultato del programma, occorre
inserire:
#include <conio.h>
……
getch();
Questo impedisce al sistema operativo di chiudere la finestra di
visualizzazione del risultato una volta completata l’esecuzione.
Risultato
#include <stdio.h>
#include <conio.h>
int main ()
{
printf("Hello World! \n");
getch();
return 0;
}
Ottenendo la videata
mostrata a lato
L’editor di testo
Un programma in C può essere scritto anche con un semplice
editor di testi. Per poter vedere il risultato del codice
dobbiamo salvare necessariamente il file con un'estensione ".c",
ad esempio "hello world.c".
Puntare il
mouse
su File,
Nuovo, File
Sorgente
La compilazione
A questo punto non dobbiamo fare altro che compilare il
programma.
Puntare
il mouse
su
Compila
La compilazione
La compilazione di un programma in C segue varie fasi:
Il codice sorgente viene controllato dal preprocessore che ha i
seguenti compiti:
- rimuovere eventuali commenti presenti nel sorgente;
- interpretare speciali direttive per il preprocessore denotate da
"#"
- controllare eventuali errori del codice
Il risultato del preprocessore sarà un nuovo codice sorgente "pulito"
ed “espanso" che viene tradotto dal compilatore C in codice assembly
L'assembler sarà incaricato di creare il codice oggetto salvandolo
con estensione .obj
Il Link editor ha il compito di collegare tutti i file oggetto
risolvendo eventuali dipendenze e creando il programma (.exe)
La compilazione
Tutte queste operazioni
possono individuare facilmente
errori di sintassi, ma mai e poi
mai potranno trovare errori
logici (come ad esempio un
ciclo che non finisce), anche
se spesso vengono segnalati
dei Warning che non
costituiscono errore, ma che
segnalano parti di codice
strane e quindi sulle quali
porre attenzione per eventuali
errori logici.
Correggere gli errori e
ripetere la procedura.
L’esecuzione
Puntare il
mouse
su Esegui
Il programma provvederà, non
solo ad eseguire tutte le
operazioni citate, ma, una
volta compilato, manderà in
esecuzione il vostro file
presentandovi il risultato a
video. Questo file, in ambiente
Dos/Windows generalmente
ha lo stesso nome del sorgente
ma con estensione .exe invece
che .c
La variabile
Il concetto di variabile.
Pensiamo, ad esempio, a quando salviamo un numero di telefono di
un nostro amico sul cellulare; se vogliamo chiamare il nostro
amico, basterà inserire il suo nome (nome della variabile) ed il
cellulare comporrà automaticamente il numero di telefono (valore
della variabile). Si può vedere quindi che una variabile esiste in
funzione del nome e del suo valore corrispondente; la comodità
risiede (come nel cellulare) nel poter usare un nome per valori, che
possono essere numeri o lettere, di grande entità o difficili da
ricordare. Un altro vantaggio, non da sottovalutare, è la possibilità
di usare il nome della variabile al posto del suo valore per
eseguirvi sopra delle operazioni, con la possibilità, in seguito, di
modificare il valore come e quante volte vogliamo.
Le variabili vengono definite da un tipo e da un nome.
La variabile
Il nome di una variabile è costituito da una o più lettere, cifre o
caratteri e deve iniziare con una lettera o il carattere di
sottolineatura (underscore "_" ); la loro lunghezza massima dipende
dal compilatore, ma generalmente non si possono superare i 31
caratteri, ed inoltre il C è case-sensitive, quindi si fa distinzione
tra lettere maiuscole e lettere minuscole.
Il tipo della variabile indica quale tipo di valori può assumere il
contenuto della variabile stessa. Si può ben capire che un tipo
intero conterrà soltanto dei numeri, mentre il tipo carattere
conterrà solamente lettere dell'alfabeto, numeri e simboli.
Va fatto notare che l'intero '7' è estremamente diverso dal
carattere '7', infatti l'intero viene trattato come un numero e su di
esso si possono svolgere le più svariate operazioni matematiche,
mentre il carattere viene gestito come un simbolo.
La variabile
Tutte le variabili, prima di essere utilizzate, devono essere
dichiarate, cioè deve essere detto al compilatore il tipo della
variabile ed il suo nome (es. int x), questo per permettergli di
allocare la memoria necessaria alla variabile stessa; la dichiarazione
generalmente viene fatta all'inizio del programma, ma in
programmi di grandi dimensioni può trovarsi anche in altre posizioni
(o altri file), ma bisogna ricordare che comunque la dichiarazione di
una variabile può essere fatta una ed una sola volta.
Successivamente la variabile deve essere inizializzata, cioè le deve
essere assegnato un valore, operazione che generalmente viene fatta
contemporaneamente alla dichiarazione.
// solo dichiarazione
int x;
// inizializzazione
x = 10;
// dichiarazione ed inizializzazione
int y = 15;
Tipi di variabile
Tipi di
Rappresentazione
dichiarazione
N. di byte
Char
Carattere
1 (8 bit)
Int
Numero intero
2 (16 bit)
Short
Numero intero
"corto"
2 (16 bit)
Long
Numero intero
"lungo"
4 (32 bit)
Float
Numero reale
4 (32 bit)
Double
Numero reale
"lungo"
8 (64 bit)
Tipi di variabile
Il tipo char è adibito a contenere uno ed un solo carattere
Per dichiarare ed inizializzare una variabile char, ad esempio
inizializzandola con la lettera 'r', basta scrivere:
char a = 'r';
Il tipo int contiene numeri, appunto, interi, quelli che in
matematica
vengono chiamati numeri naturali, e cioè senza la virgola e parti
frazionate.
int x = 7;
Attenzione:
int y = 3;
int z;
z = x / y;
z vale 2, cioè la parte intera della divisione tra 7 e 3
Tipi di variabile
I tipi float e double sono chiamati anche numeri in virgola mobile,
cioè quelli che in matematica vengono chiamati numeri reali.
La differenza tra i due sta solamente nei bit che sono riservati per
la loro rappresentazione.
float x = 7.0
float y = 2.0
float z;
z=x/y
// z vale 3.5
short e long sono le due varianti del tipo int anche se in realtà un
tipo int è già di per sè un tipo short.
Gli operatori aritmetici

Operatori aritmetici. Comprendono somma, sottrazione,
moltiplicazione, divisione intera, divisione con modulo ecc.
Lavorando con i
numeri float o
double manca la
"divisione con
modulo" che non
ha ragione di
esistere.
Operazioni con gli
int
Simbolo
Esempio
Addizione
+
4 + 27 = 31
Sottrazione
-
76 - 23 = 53
Moltiplicazione
*
4 * 7 = 28
/
10 / 3 = 3
(3 è il n di volte
divisibili senza
resto)
%
11 / 6 = 5
(5 è il resto della
divisione)
Divisione intera
Divisione con
modulo
Gli operatori aritmetici
Esistono poi gli operatori di incremento (++) e quello di decremento
(--), che possono essere preposti o posposti alla variabile; se sono
preposti il valore è calcolato prima che l'espressione sia valutata,
altrimenti viene calcolato dopo; l'incremento ed il decremento
avvengono sempre nel valore di una unità sul valore della variabile.
Ad esempio x++ equivale a scivere x = x + 1;
int x = 2;
int y = 5;
int z = 9;
int k = 6;
printf("%d\ n", x++); // 2, che si incrementerà a 3 dopo il printf
printf("%d \n", ++y); // 6, si incrementa prima del printf
printf("%d \n", z--); // 9, che si decrementerà a 8 dopo il printf
printf("%d \n", --k); // 5, si decrementa prima del printf
Gli operatori aritmetici
Esiste nel C una forma contratta come mostrata in tabella.
Supponiamo di assumere c = 3, d =5, e = 4, f = 6, h = 12
Operatore Espressione Spiegazione
Assegna
+=
c += 7
c=c+7
10 alla variabile c
-=
d -= 4
d=d-4
1 alla variabile d
*=
e *= 5
e=e*5
20 alla variabile e
/=
f /= 3
f=f/3
2 alla variabile f
%=
h %= 9
h=h%9
3 alla variabile h
Gli operatori di confronto

Operatori di confronto. Operatori che permettono di verificare
determinate condizioni, come ad esempio l'uguaglianza o la
disuguaglianza.
Simbolo
Significato
Utilizzo
==
uguale a
a == b
!=
diverso da
a != b
<
minore
a<b
>
maggiore
a>b
<=
minore o uguale
a <= b
>=
maggiore o uguale
a >= b
Gli operatori logici

Operatori logici. Da utilizzare con le istruzioni condizionali ed
iterative.
Simbolo
Significato
Utilizzo
&&
AND logico
a && b
||
OR logico
a || b
!
NOT logico
a!b
^^
XOR logico
a ^^ b
Queste operazioni restituiscono necessariamente 1 quando sono vere e 0
quando sono false, quindi facendo "a || b" questa assume valore uno se e
solo se "a" o "b" valgono uno, mentre vale zero se entrambi gli operandi
valgono zero; analogamente quando si ha "a & b", questa assume valore
zero se "a" o "b" valgono zero, uno nel caso entrambi valgano uno.
Priorità degli operatori
Il C valuta le espressioni aritmetiche in una sequenza precisa,
generalmente la stessa adottata dall’algebra.
o In primo luogo saranno valutate le operazioni di divisione,
moltiplicazione e resto che hanno stesso livello di priorità. Se
ce ne sono più di una di seguito all’altra, la valutazione
procederà da sinistra a destra.
o
In seguito saranno valutate le somme e le sottrazioni
analogamente al caso precedente.
Attenzione alle parentesi!
x = (a + b + c)/2
anche nel linguaggio C
è diverso da
x = a + b + c /2
Priorità degli operatori
Esempio 1
Dato
y=a*x*x+b*x+c
e supponendo che a = 2, b = 3, c = 7 e x = 5, come sarà valutato il
precedente polinomio?
Passo 1:
Passo 2:
Passo 3:
Passo 4:
Passo 5:
Passo 6:
y = 2 * 5 * 5 + 3 * 5 + 7 (la moltiplicazione più a sinistra)
y = 10 * 5 + 3 * 5 + 7 (la moltiplicazione più a sinistra)
y = 50 + 3 * 5 + 7 (prima la moltiplicazione dell’addizione)
y = 50 + 15 + 7 (l’addizione più a sinistra)
y = 65 + 7 (l’ultima addizione)
y = 72 (l’ultima operazione posiziona 72 in y)
Priorità degli operatori
Esempio 2
Dato il polinomio
z=p*r%q+w/x-y
gli operatori saranno valutati nel seguente ordine.
La moltiplicazione, il resto e la divisione saranno valutati per primi
in ordine da sinistra a destra, poiché hanno una priorità maggiore
dell’addizione e della sottrazione. In seguito saranno valutate la
somma e la sottrazione anche queste da sinistra a destra.
ATTENZIONE
Non confondere l’operatore di uguaglianza ==
con quello di assegnamento =
Ciò che rende questi scambi così dannosi è che essi, solitamente,
non provocano degli errori di sintassi e quindi non vengono
segnalati dal compilatore.
Se vogliamo verificare che la variabile x assuma il valore 0 dovremo
scrivere x == 0. Nel caso in cui vogliamo assegnare il valore 0 a
suddetta variabile dovrò scrivere x = 0.
Operazioni di input – output
printf
Per fare questo tipo di operazioni dobbiamo includere il file
<stdio.h> che mette a disposizione alcune funzioni predefinite
per eseguire la lettura da un dispositivo di input (es. tastiera) o
scrittura su un dispositivo di output (es. video).
L'istruzione per stampare a video più usata è la printf, che ha il
controllo su ciò che viene stampato, nel senso che permette di
decidere cosa stampare ed in quale forma.
Si possono stampare:
•
caratteri ordinari (questi vengono copiati nell'output)
•
specificazioni di conversione (contraddistinte dal carattere
percentuale "%" e da un carattere che specifica il formato con
il quale stampare le variabili presenti nella lista di argomenti)
Operazioni di input - output
La tabella seguente mostra i possibili formati che possono essere
usati per formattare le variabili; tali considerazioni si applicano
anche al comando scanf
Operazioni di input - output
E’ possibile inserire, tra il simbolo % e l'identificativo del formato,
una delle seguenti voci:
•
Segno meno (-), esegue la giustificazione a sinistra
•
Un numero intero, specifica l'ampiezza del campo
•
m.d, dove m è l'ampiezza del campo e d è la precisione del
numero; usato generalmente per le stringhe o per un numero di
tipo reale
ESEMPIO:
int x = 10;
printf("Il numero è %d", x);
// l'output a video è "Il numero è 10"
print("%-.2.3f \n", 24.392734);
// l'output a video è 24.393
Operazioni di input - output
Le sequenze di escape servono per rappresentare quei caratteri
"speciali" presenti nella codifica ASCII e che non stampano nulla a
video, ma permetto di introdurre ad esempio eventuali spaziature.
Si inseriscono prima di chiudere le virgolette:
int x = 10;
printf("Il numero è %d\n", x);
// l'output a video è "Il numero è 10“ e il cursore torna a capo
Operazioni di input – output
scanf
La funzione scanf serve per leggere dallo stdin (generalmente la
tastiera) una sequenza di caratteri (lettere o cifre) che
verranno memorizzate all'interno di opportune variabili.
A differenza della printf, però la variabile deve essere preceduta
dal simbolo &, perché in realtà tra gli argomenti non dobbiamo
passare il nome della variabile, ma il suo indirizzo, cosa che può
essere fatta tranquillamente utilizzando un puntatore.
E’ possibile usare gli specificatori di conversione anche per la
scanf, che quindi si comporta in modo molto simile a printf.
Operazioni di input – output
ESEMPIO:
#include <stdio.h>
int main()
{
int i;
scanf("%d \n", & i);
printf("%d \n", i);
}
Questo semplice programma sopra esposto serve solamente per leggere
un numero da tastiera e ristamparlo a video.
Operazioni di input – output
Una piccola particolarità limitatamente all'uso delle stringhe e
degli array con la funzione scanf, è la seguente:
char stringa[100];
scanf("%s", stringa);
In questo caso è possibile omettere il simbolo & che richiama
l'indirizzo del puntatore, ed usare, invece, il nome della variabile,
perché il nome di un array corrisponde all'indirizzo di partenza
dell'array stesso.
Esempio: Somma fra due numeri
/* Programma di addizione */
#include <stdio.h>
int main( )
{
int = A;
int = B;
int = somma;
printf(“Inserisci il primo numero\n”);
scanf(“%d”, &A);
printf(“Inserisci il secondo numero\n”);
scanf(“%d”, &B);
somma = A + B;
}
printf(“La somma è %d\n”, somma);
return 0;
Nozioni sulla memoria
Ammettiamo che si voglia fare la somma fra A = 3 e B = 2 (numeri
che immettiamo da tastiera), ottenendo banalmente somma = 5.
Il computer sistemerà i precedenti valori in apposite locazioni di
memoria, distruggendo il dato che c’era scritto prima, identificate
rispettivamente dal nome A, B e somma.
Da osservare che queste locazioni non saranno
necessariamente adiacenti.
N.B. Mentre l’operazione di scrittura di un dato
in memoria è distruttiva, non lo è quella di
lettura.
Le funzioni
Le funzioni sono uno degli strumenti più potenti del C infatti
permettono un notevole risparmio e riuso del codice, con ovvii
vantaggi del programmatore. Le funzioni esistono più o meno in tutti
i linguaggi e vengono chiamate anche procedure o subroutine.
I programmi C sono scritti tipicamente combinando le nuove funzioni
scritte dal programmatore con quelle “preconfezionate” disponibili
nelle librerie. Il C assume che ogni funzione ritorni un valore, questo
accade utilizzando l'istruzione return seguita, eventualmente, da un
valore. Le funzioni sono invocate da una chiamata che specifica il
nome della funzione e fornisce delle informazioni (gli argomenti) di
cui la funzione chiamata ha bisogno per completare le attività per
cui è stata progettata. Un capo (la funzione chiamante) chiede ad un
operaio (la funzione chiamata) di eseguire un compito e tornare
indietro a riferire. Esempio: il main (capo) chiede alla funzione printf
(operaio) di visualizzare delle informazioni, poi restituirà il controllo.
Le funzioni della libreria matematica
Funzione
sqrt(x)
exp(x)
log(x)
log10(x)
fabs(x)
ceil(x)
floor(x)
pow(x,y)
fmod(x,y)
sin(x)
cos(x)
Descrizione
radice quadrata di x
funzione esponenziale e
logaritmo naturale di x
logaritmo base 10 di x
valore assoluto di x
arrotonda x all’intero più
piccolo non < di x
arrotonda x all’intero più
grande non > di x
x elevato alla potenza di y
resto di x/y in virgola mobile
seno trigonometrico di x
coseno trigonometrico di x
Esempio
sqrt(900) è 30
exp(1,0) è 2,718282
log(2,718282) è 1,0
log10(1,0) è 0
fabs(-5) è 5
ceil(9,2) è 10
floor(9,2) è 9
pow(2,7) è 128
fmod(13,6,2,3) è 1,9
sin(0,0) è 0,0
cos(0,0) è 1,0
Le definizioni di funzione
ESEMPIO: programma che utilizza la funzione square per calcolare
e visualizzare i quadrati degli interi compresi fra 1 e 10
#include <stdio.h>
int square(int y);
int main( )
{
int x;
for(x = 1; x <=10; x++) {
/*prototipo della funzione*/
/*contatore */
/* itera 10 volte, calcola e visualizza
il quadrato di x ad ogni ciclo*/
printf(“% d ”,square(x));
/* chiamata di funzione */
}
return 0;
}
/* funzione square*/
int square(int y)
/* il parametro y è una copia di x*/
{
return y * y;
/*restituisce il quadrato di y come intero*/
}
Formato delle funzioni
Il formato di una definizione di funzione è:
tipo_del_valore_di_ritorno nome_funzione(lista_parametri)
{
dichiarazioni
(intestazione della funzione)
istruzioni
}
Il nome della funzione è un qualsiasi identificatore valido. Il tipo
del valore di ritorno è quello del risultato restituito al chiamante.
Se questo è void indica che la funzione non restituirà nessun
valore. Se non specificato sarà considerato int dal compilatore.
La lista dei parametri è un elenco, separato da virgole, che
specifica i parametri ricevuti dalla funzione alla chiamata. Il tipo
dei parametri deve essere specificato salvo che non siano di tipo
int.
Scarica

IL LINGUAGGIO C - Pr.. - IIS Cartesio Luxemburg