Corso di C con Linux

Funzioni e blocchi di funzione (II)

 

Continuamo l’esame del codice primo.c, soffermandoci sulla seconda linea dell'esempio:

#include <stdio.h>

che è una direttiva al preprocessore.
Infatti il codice di un programma scritto in C può includere alcune istruzioni dirette al compilatore, dette appunto direttive al preprocessore, che sono contenute in linee che iniziano con il carattere #.
Il significato della nostra linea di programma è:

"Cerca su disco il file stdio.h e inserisci in questo punto del programma tutto il contenuto di quel file".

I file *.h vengono chiamati header e fanno generalmente riferimento ad una libreria.
Il file stdio.h (stdio = standard input/output) viene usato in tutti i programmi che richiedono una qualche forma di immissione o emissione dati (I/O, input/output), ovvero la quasi totalità dei programmi.

Inserendo il file stdio.h nel programma è possibile utilizzare le funzioni di input/output, in questo si è utilizzata la routine printf.
L’inclusione di un file header può essere fatta in due modi diversi:

#include <stdio.h>
#include "stdio.h"

Apparentemente le due linee di codice sembrano uguali, se escludiamo le virgolette, ma dal punto di vista del compilatore la differenza è sostanziale.
Infatti:
-  Le parentesi angolari (< >) che precedono e seguono il nome di un file header indicano al preprocessore di cercare il file header richiesto nella directory standard degli header (/usr/include).
- Le virgolette (" ") indicano al preprocessore di cercare il file header prima nella directory corrente e poi, se non viene trovato, nella directory standard.

Se scriviamo:

#include "/home/deneb/myio.h"

specifichiamo esattamente il percorso dove trovare l'header myio.h.

Alla riga successiva dell'esempio troviamo la funzione:

int main(void)

che restituisce un valore intero e non riceve nulla in ingresso.
All'interno della funzione main() viene chiamata un'altra funzione:

printf("Ciao Mondo!\n");

che è una funzione di I/O contenuta nell'header stdio.h, il cui compito è quello di stampare sullo schermo i caratteri compresi tra i doppi apici.
Il carattere \n (newline) indica che non appena viene scritta la stringa ci sia un ritorno del carrello (cioè si vada a capo).
Così come avviene in ogni funzione, per la printf tutto ciò che è compreso tra le parentesi tonde costituisce l’argomento della funzione stessa.

Infine la funzione main() restituisce il valore 0, che indica che il programma è terminato correttamente.
A tal proposito dobbiamo sapere che esistono due macro definite dalla libreria GNU, EXIT_SUCCESS e EXIT_FAILURE, rappresentanti i valori di uscita di un programma rispettivamente nel caso in cui venga eseguito correttamente e nel caso in cui vi siano errori.
In Linux, è buona pratica specificare nella funzione principale (ovvero main) un valore di uscita per il programma.
Per definizione, se il programma ha eseguito tutte le operazioni correttamente uscirà con valore 0, altrimenti con valore maggiore di 0 (generalmente 1).

Vedremo in seguito che valori di uscita diversi da 1 possono essere utilizzati per facilitare il debugging del codice o per comunicare con altri processi.
Le macro EXIT_SUCCESS e EXIT_FAILURE sono state create per migliorare la leggibilità del codice, infatti le istruzioni:

return 1;
return EXIT_FAILURE;


sono equivalenti.
Per utilizzarle occorre includere nel codice sorgente il file header <stdlib.h>.
Nella tabella seguente sono riassunti i valori delle due macro descritte.

Macro

Valore

EXIT_SUCCESS

0

EXIT_FAILURE

1

Abbiamo visto dunque che una funzione può richiamarne un'altra, ma, perché ciò sia possibile, deve essere visibile alla funzione che la richiama; è per questo motivo che l'header è posto all'inizio del programma e non in fondo.

In generale un programma C è così composto:

1) Comandi per il preprocessore
2) Definizione di tipi
3) Prototipi di funzioni (dichiarazione dei tipi delle funzioni e delle variabili passate alle funzioni)
4) Variabili
5) Funzioni

L'esecuzione di ogni programma, al di là della sua struttura, inizia sempre dal main() e prosegue discendendo per ogni funzione e istruzione in esso contenuta fino al termine del blocco funzione del main stesso.

 

Torna all'indice Generale del corso di Corso di C con Linux di Software Planet