INTRODUZIONE AL
LINGUAGGIO C ANSI
INDICE
➢Storia
➢Informazioni preliminari
➢Sintassi di base
➢Controlli condizionali
➢Le funzioni
➢Esempio di codice funzionante
STORIA
Il linguaggio fu originariamente sviluppato da
Dennis Ritchie tra il 1969 e il 1973, con lo scopo
di utilizzarlo per la stesura del sistema operativo
UNIX.
Nel 1978, la pubblicazione del libro Il linguaggio
C ne fece crescere rapidamente la diffusione,
portando alla nascita di diversi dialetti e dunque
alla necessità di definire uno standard.
La prima standardizzazione del C fu realizzata
dall'ANSI nel 1989
INFORMAZIONI PRELIMINARI
C è un linguaggio IMPERATIVO PROCEDURALE;
Vale a dire che i programmi scritti in questo
linguaggio sono composti da espressioni
matematiche e da istruzioni imperative
raggruppate in procedure parametrizzate.
Tali procedure sono definite FUNZIONI
Si tratta di un linguaggio ad ALTO LIVELLO;
Utilizza cioè una sintassi vicina al linguaggio
umano e relativamente distante dal linguaggio
assembly e dal linguaggio macchina;
* In altre parole, una gran parte delle istruzioni
esistenti in C prende origine dalla lingua inglese.
Il C è un linguaggio compilato:
Significa che, prima di poter funzionare, il codice
sorgente del programma scritto deve essere
“tradotto” in linguaggio macchina da un
software definito compilatore;
Tale software genera un file eseguibile in grado
di essere elaborato dal processore e
dall’hardware della macchina, grazie al
coordinamento del sistema operativo.
Il linguaggio C è estremamente flessibile e viene
tutt’oggi utilizzato in un gran numero di scenari.
Ad esempio, è possibile utilizzare il C per:
• Scrivere un intero sistema operativo
• Programmare dispositivi connessi
• Creare librerie dedicate ai giochi
• Effettuare calcoli matematici complessi.
SINTASSI DI BASE
• Statement
• La direttiva #include
• Tipi di dati
• Definizione di variabili
• Operatori principali
Un programma in C viene scritto avvalendosi di
FILE SORGENTI, nei quali vengono specificate le istruzioni
da eseguire per elaborare i dati nel modo scelto.
Il C utilizza un approccio sequenziale:
Le istruzioni vengono eseguite nel medesimo ordine in
cui sono specificate nel codice sorgente.
STATEMENT
Lo statement è l’entità di base del linguaggio C
È un’istruzione completa che, elabora i dati.
Lo statement termina sempre con un: ; (punto e virgola)
e può effettuare qualsiasi tipo di operazione:
• Addizionare due numeri
• Paragonare due stringhe di caratteri
• Richiamare una funzione
• Dichiarare o assegnare un valore a una variabile
Ciascuno statement contiene un “comando” di
manipolazione dati.
Per convenzione, ciascuno statement in C
dovrebbe risiedere su una riga diversa del
codice sorgente.
*Lo statement printf(“Ciao a tutti!”); contiene il comando per stampare a
video la frase “Ciao a tutti”.
LA DIRETTIVA
#INCLUDE
Un programma in C può snodarsi su diversi file
sorgenti
Questo succede per tenere un certo ordine in progetti
molto grandi.
(Digitare tutto in un solo file di migliaia di righe, farebbe impazzire
anche il programmatore più paziente)
In base a questo criterio, il C prevede una speciale
direttiva, #include
Viene specificata all’inizio di ciascun codice sorgente
e comunica al compilatore i file da “includere” nel
programma in fase di compilazione.
Per fare un esempio, quasi tutti i programmi
scritti in C iniziano con la direttiva #include
<stdio.h>
In questo modo, è possibile utilizzare tutti i
comandi C specificati nella cosiddetta
LIBRERIA DI STANDARD INPUT/OUTPUT.
La libreria stdio.h contiene le definizioni dei
comandi di base e delle costanti, per permettere
al programmatore la manipolazione
dell’input/output e la gestione dei file.
I comandi di base più utilizzati sono:
• printf(), fprintf() e sprintf() – Permettono, rispettivamente, di
scrivere dati sul dispositivo di output standard (schermo), su file
e su stringhe di caratteri.
• scanf(), fscanf() e sscanf() – Prelevano dati rispettivamente
dallo standard input (la tastiera), da file e da stringhe di
caratteri.
• fopen() e freopen() – Permettono di aprire un file all’interno
di un programma, così da poter leggere dati al suo interno o
scriverne altri.
• fread() e fwrite() – Permettono, rispettivamente, la lettura e
la scrittura da un file.
La direttiva include può essere specificata in due
modi:
#include <libreria.h>
Denota l’inclusione di una libreria presente nell’ambiente
di sviluppo predefinito.
#include “libreria.h”
Specifica l’inclusione di una libreria scritta dal
programmatore e presente nella stessa cartella del file
sorgente in cui è dichiarata.
TIPI DI DATI
Il C non è un linguaggio a oggetti, dunque le strutture dati più
complesse vanno dichiarate e strutturate in memoria
manualmente.
Tale linguaggio è in grado di gestire e manipolare
nativamente numerosi tipi di dati, che vengono assegnati alle
variabili necessarie per il funzionamento del programma.
I dati vengono acquisiti come valori in input o resi come
valori di ritorno delle funzioni.
I tipi di dati più utilizzati sono:
• char – Denota un singolo carattere e occupa 8 bit in
memoria. Per le funzioni di I/O è necessario specificare il
codice %c
• int – Denota i numeri interi, occupa 16 bit e contiene i
valori che vanno da -32767 a +32767. Il suo
identificatore, nelle operazioni di input/output, è %i
• float e double – Identificano i numeri in virgola mobile
semplici e i numeri in virgola mobile doppi. Occupano
rispettivamente 32 e 64 bit
Gli identificatori da assegnarvi sono %f e %fd.
void – Identifica il non valore, cioè un’entità che non
occupa alcuno spazio in memoria.
In genere, il void viene specificato come valore di ritorno o
come input nelle funzioni che non lo prevedono
(come a voler dire al compilatore “questa operazione non
ritornerà alcun valore o non accetta valori in input”).
Il void, non ha un identificatore caratteristico per I/O.
DEFINIZIONE DI VARIABILI
VARIABILE: Una variabile è un “contenitore” situato in
memoria, che deve contenere valori che possono essere
modificati durante l’esecuzione di un programma.
DICHIARAZIONE DI UNA VARIABILE
Si avvisa il compilatore che bisogna allocare una
porzione di memoria per contenere dei dati
DEFINIZIONE O ASSEGNAZIONE DI UNA VARIABILE
Si va a riempire la memoria con i dati richiesti
* È possibile dichiarare una variabile senza definirla, ma non
è possibile definire una variabile senza dichiararla
Come dichiarare una variabile in C:
• Digitare uno statement che specifichi il tipo di dato che la
variabile deve contenere;
• Il suo nome;
• Se necessario, il valore iniziale (specificato con l’operatore
di assegnazione =)
Si può dunque dichiarare una variabile intera vuota attraverso
lo statement int variabile;
oppure assegnarle il valore iniziale (es:10) impartendo
int variabile = 10.
Una volta dichiarata una variabile, è possibile
manipolarla nelle parti successive del codice
utilizzando l’assegnazione con gli operatori di
incremento, decremento o quanto previsto dal
tipo di dati specificato.
Per essere utilizzata, una variabile deve essere
necessariamente dichiarata in una parte
precedente del codice
Il C è un linguaggio sequenziale, dunque non
può chiedere a uno statement di operare su un
dato che non conosce!
In C è possibile riferirsi alle variabili in due modi
differenti:
• PER OPERAZIONI DI ASSEGNAZIONE TRAMITE L’OPERATORE =
O FUNZIONI DI MANIPOLAZIONE DELL’OUTPUT (AD ES. PRINTF()):
Si utilizza semplicemente il suo nome (ad es. printf(“%i”,
variabile); oppure somma = aggiungi(a,b);
• PER SCRIVERE DATI IN UNA VARIABILE Usando DET. FUNZIONI DI
MANIPOLAZIONE DELL’INPUT (AD ES. LA FUNZIONE SCANF()):
È necessario farvi riferimento attraverso un puntatore al
contenuto in memoria;
Per farlo, è sufficiente anteporre al nome della variabile il
carattere & (ad es. scanf(“%i”, &variabile);).
OPERATORI PRINCIPALI
La programmazione in C richiede l’utilizzo degli operatori;
Sono caratteri che, all’interno di uno statement, possono
acquisire un significato “speciale”.
Il linguaggio C prevede un gran numero di operatori per la
gestione dei più disparati casi.
Il più importante è l’operatore di assegnamento: =
Permette di assegnare un valore (o un’espressione) a una
o più variabili.
* Esempio: Digitare lo statement int a = 1+2+3+4; significa dichiarare una
variabile intera a e attribuirle il valore iniziale di 10
Oltre all’operatore di assegnamento, esistono altri
operatori;
Si dividono in quattro categorie:
• OPERATORI ARITMETICI
Permettono l’esecuzione di operazioni aritmetiche di base:
+ denota l’addizione,
– la sottrazione,
* la moltiplicazione,
/ la divisione,
++ l’incremento di uno
-- il decremento di uno
% restituisce il resto della divisione intera tra i valori.
• OPERATORI RELAZIONALI
Mettono in relazione un valore rispetto a un altro:
> e < (maggiore/minore)
>= e <= (maggiore/minore uguale a)
== e != (uguale e diverso)
Si basano sul concetto di vero/falso
*Esempio: var = 10>5 assegna a var il valore true, poiché il numero 10 è
maggiore del numero 5.
• OPERATORI LOGICI
Seguono lo stesso approccio vero/falso visto poco fa, ma
vengono utilizzati per confrontare il collegamento tra due
relazioni, tipico dell’algebra booleana.
&& (and logico)
|| (or logico)
! (il not)
• OPERATORI BIT A BIT
Permettono di intervenire sui singoli byte dei tipi di dato
char e int, effettuando esclusioni, spostamenti e confronti.
Vengono impiegati nella scrittura di moduli per sistemi operativi o
di driver di periferica.
CONTROLLI CONDIZIONALI
C è un linguaggio sequenziale (esegue istruzioni nello
stesso ordine in cui compaiono nel codice sorgente).
Esistono tuttavia delle direttive che permettono di
modificare il flusso di esecuzione del programma,
modificandone l’ordine al verificarsi di det. condizioni;
Queste direttive sono i controlli condizionali:
• If/else
• Switch/case
• Operatori ternari
if/else
Il controllo condizionale if
Impartire questa istruzione significa, comunicare al
programma qualcosa di simile a:
“SE si verifica una precisa condizione, allora esegui questa
istruzione”.
Sintatticamente, il controllo si presenta nella forma:
if (condizione) {
istruzioni
}
Clausola else
Se si desidera, si specificare un’ulteriore condizione
avvalendoti della clausola else
Unita all’if, permette di astrarre il concetto:
“Se si verifica una precisa condizione, allora esegui queste
istruzioni, ALTRIMENTI (else) esegui queste altre”.
if (condizione) {
istruzioni
} else {
altre istruzioni
}
Se necessario, si può “arricchire” il costrutto visto poco fa
con la clausola else if
Permette di specificare ulteriori condizioni:
if (condizione1) {
istruzioni per gestire condizione1
}
else if (condizione2) {
istruzioni per gestire condizione2
}
else {
istruzioni per gestire tutti gli altri scenari possibili
}
Switch/case
Il costrutto switch/case, come quello if/else, può
influenzare l’esecuzione sequenziale delle istruzioni
presenti nel codice.
Lo switch/case, è usato nelle decisioni dipendenti dal
valore di una variabile e non da un’operazione booleana.
Può essere visto come:
“Salta al caso (case) X se la variabile da analizzare (switch)
assume il valore X, altrimenti esegui l’operazione predefinita
(default)”.
Operatori ternari
Gli operatori ternari,permettono di “abbreviare” la sintassi
del condizionale visto in precedenza
Sono particolarmente usati se bisogna impartire due
differenti istruzioni a seconda del risultato (vero o falso)
dell’espressione booleana di confronto.
condizione ? istruzione_se_vera : istruzione_se_falsa
*Esempio: Volendo confrontare due variabili e dare
comunicazione all’utente riguardo l’esito, si potrebbe usare
il codice seguente:
LE FUNZIONI
CONCETTO DI FUNZIONE: Una funzione in C è una
parte di codice che esegue l’algoritmo necessario a
ottenere il risultato desiderato.
In altre parole, è l’insieme di statement atti a manipolare
i dati in ingresso e produrre dati in uscita che siano in
linea con le necessità del programmatore.
Le funzioni possono essere:
DICHIARATE
Si “avvisa” il compilatore dei dati in entrata, dei dati in uscita
e del nome della funzione stessa.
DEFINITE:
Si specificano gli statement necessari all’elaborazione dei dati
Esempio
int aggiungi(int a, int b) { //funzione per eseguire una somma
return a+b;
}
* Il valore che la funzione deve restituire è espresso
attraverso la clausola return, specificata subito prima della
fine del codice della funzione stessa
NB: Tutti gli statement che ne fanno parte, inoltre, devono
essere racchiusi tra due parentesi graffe.
In linea del tutto generale, le funzioni vengono
dichiarate prima del corpo del main e definite subito
dopo di esso.
Una funzione dichiarata può essere inclusa nel codice
che ne precede la definizione ma deve essere
obbligatoriamente definita nel codice sorgente in cui
viene richiamata, altrimenti verrà generato un errore in
fase di esecuzione del programma (che, invece, verrà
compilato senza problemi).
LA FUNZIONE “SPECIALE” MAIN()
È la funzione da cui parte l’esecuzione di ogni codice sorgente.
Rappresenta il flusso di esecuzione principale di un codice
sorgente e contiene tutte le istruzioni necessarie.
È il “motore” di un programma C, che permette di eseguire
l’algoritmo principale.
Al suo interno possono essere utilizzate variabili ed espressioni
condizionali di ogni tipo, richiamate funzioni appartenenti alle
librerie, funzioni dichiarate e definite all’interno dello stesso corpo
del codice sorgente.
IL CODICE SORGENTE C, AFFINCHÉ POSSA ESSERE ESEGUITO,
DEVE CONTENERE UNA E UNA SOLA FUNZIONE MAIN()
ESEMPIO DI CODICE FUNZIONANTE
“Hello World”
Di seguito è riportato un programma che stampa a video il
saluto “Ciao, mondo!”
Codice sorgente HelloWorld.c