Programmi con argomenti passati da linea di comando

Documenti analoghi
STRUTTURA DI UN PROGRAMMA!

STRUTTURA DI UN PROGRAMMA

f2.obj compilatore compilatore linker f3.obj compilatore

Progetti su più File Sorgenti

deve conoscerne solo l interfaccia:

Esiste però anche un ambiente globale: quello dove tutte le funzioni sono definite. Qui si possono anche definire variabili, dette variabili globali

Esiste però anche un ambiente globale: quello dove tutte le funzioni sono definite. Qui si possono anche definire variabili, dette variabili globali

PROGETTI SU PIU` FILE

per costruire specifici componenti software

Esiste però anche un ambiente globale:! quello dove tutte le funzioni sono definite. Qui si possono anche definire variabili, dette variabili globali!

PROCEDURE. Una procedura permette di. void p(int x) { x = x * 2; printf( %d, x); }

PROCEDURE. Una procedura permette di. void p(int x) { x = x * 2; printf( %d, x); }

Unità Didattica 1 Linguaggio C. Fondamenti. Struttura di un programma.

Preprocessore, linker e libreria standard

Preprocessore, linker e libreria standard

Perché il linguaggio C?

FUNZIONI. Esempi (pseudo-c): dare un nome a una espressione rendere tale espressione parametrica. float f(){ * sin(0.75); } float f1(int x) {

Una funzione riceve dati di ingresso in corrispondenza ai parametri

Perché il linguaggio C?

FUNZIONI. Esempi (pseudo-c): dare un nome a una espressione rendere tale espressione parametrica. float f(){ * sin(0.75); } float f1(int x) {

Il sistema C è formato dal linguaggio C, dal preprocessore, dal compilatore, dalle librerie e da altri strumenti di supporto.

FUNZIONI COME COMPONENTI SW FUNZIONI COME COMPONENTI SW FUNZIONI MODELLO CLIENTE/SERVITORE

FUNZIONI FUNZIONI COME COMPONENTI SW

Le direttive del Preprocessore

Unix e comandi di base

FUNZIONI FUNZIONI COME COMPONENTI SW

Il linguaggio C Funzioni e procedure

Introduzione al C. Unità 10 Preprocessore

FUNZIONI COME COMPONENTI SW FUNZIONI COME COMPONENTI SW FUNZIONI MODELLO CLIENTE/SERVITORE

Introduzione al C. Unità 10 Preprocessore. D. Bloisi, S. Peluso, A. Pennisi, S. Salza

Lab 01 Introduzione a Codelite

Il preprocessore. Direttiva define Direttiva include Direttiva if

PER UTILIZZARE LCC IN LAB

Funzionalità. Il preprocessore C. Inclusione di file. Inclusione di file

Lezione 19: Il preprocessore

Funzioni, Stack e Visibilità delle Variabili in C

Esempi (pseudo-c):! float f(){ * sin(0.75); } float f1(int x) { 2 + x * sin(0.75); } Esempio

Il linguaggio C. Il preprocessore...

#include <stdio.h> main() { - 1 -

prova.c #include <stdio.h> char funzione(char); codice oggetto del main()

Linguaggio di Riferimento: C

Introduzione al linguaggio C Funzioni

C: primi elementi. Lezione 4

Lezione 5: Introduzione alla programmazione in C

Il linguaggio C. Il preprocessore...

Cenni sul preprocessore e il suo utilizzo

Preprocessore. Unità 9. Corso di Laboratorio di Informatica Ingegneria Clinica BCLR. Domenico Daniele Bloisi Si ringrazia Raffaele Nicolussi

Funzioni, Stack e Visibilità delle Variabili in C

Passare argomenti al programma

Esempio. Le istruzioni corrispondono a quelle di sopra, ma sono scritte in modo simbolico. E indipendente dalla machina

Fondamenti di Informatica

MS Visual Studio: Linea di Comando

Il Linguaggio C. Caratteristiche. Caratteristiche. Esempio di programma in C. Tipi di dato primitivi in C. Dati

Primo passo: il preprocessor. Il preprocessore. Esempi di direttive al preprocessore: #include. Esempi di direttive al preprocessore: #define

Complementi. - Ridefinizione di tipo - - Costrutto switch - - Programmazione su più file - - Parametri della funzione main - Funzione system -

C funzioni à scope di variabili

Lezione 21 e 22. Valentina Ciriani ( ) Laboratorio di programmazione. Laboratorio di programmazione. Lezione 21 e 22

Programmazione I - Laboratorio

Funzioni come parametri

Complementi. - Ridefinizione di tipo - - Costrutto switch - - Programmazione su più file - - Parametri della funzione main - Funzione system -

Il linguaggio C. Notate che...

Struttura di un. Struttura dei programmi C

Esercitazione. Uso di funzioni e librerie di funzioni

passaggio di vettori come parametri di funzioni/procedure. I Quando si passa un vettore come parametro ad una funzione, in

Client - Interfaccia - Implementazione

Introduzione alla programmazione in C

Ambienti di Programmazione per il Software di Base

Dati due punti sul piano calcolare la loro distanza

Corso di Fondamenti di Informatica L-B

Primi passi col linguaggio C

Allocazione dinamica della memoria

OOP in C++ ha membro (dati membro) e funzioni membro In Java i dati membro sono chiamati attributi e le funzioni membro metodi

Linguaggio C. Generalità sulle Funzioni. Variabili locali e globali. Passaggio di parametri per valore.

I/O da tastiera e direttive processore. Alessandra Giordani Lunedì 3 maggio

Lezione 8: Stringhe ed array multidimensionali

COSTRUZIONE DI UN APPLICAZIONE

Linea di comando. Compilazione. Aprire una shell di DOS tramite:

C: panoramica. Violetta Lonati

Introduzione alla programmazione in C

Variabili e Funzioni. Informatica 1 / 19

Uso di GCC da riga di comando

Sunto della scorsa lezione Il linguaggio C. Un Programma con Errori. Il preprocessore. Linguaggi di Programmazione I.

Linguaggio C: Variabili e assegnamento e semplici comandi di I/O

Primi passi Output formattato Le quattro operazioni. Programmazione 1. Lezione 2 Parte 2. Vincenzo Marra.

Programmazione Procedurale in Linguaggio C++

Laboratorio di Programmazione 1. Docente: dr. Damiano Macedonio Lezione 4 24/10/2013

Fondamenti di Informatica II 3. Funzioni in C++ (parte 1)

Funzioni in C. Architetture multi-componente

Il blocco che costituisce il corpo di una funzione/procedura può contenere dichiarazioni di variabili. Esempio:

Strategie di programmazione

10. Visibilità e tempo di vita delle variabili. Andrea Marongiu Paolo Valente

Transcript:

Programmi con argomenti passati da linea di comando Parametri del main() Quando compiliamo un programma viene generato un file eseguibile (estensione.exe nei sistemi Windows). I programmi possono prendere degli argomenti dalla riga di comando con la quale vengono eseguiti. Esempio: copy file1 file2 I programmi visti finora non prendevano argomenti. La funzione main non prendeva parametri: int main(void) {... Fondamenti di Informatica 2 1

Parametri del main() Per poter usare gli argomenti con cui il programma è stato lanciato, la definizione di main deve diventare: int main(int argc, char *argv[]) {... argc... numero di argomenti con cui il programma è stato lanciato più 1 argv... vettore di argc stringhe che compongono la riga di comando argv[0] è il nome del programma stesso argv[1],, argv[argc-1] sono gli argomenti (separati da spazio) ogni argv[i] è una stringa (terminata da \0 ) argc e argv vengono inizializzati dal sistema operativo (le stringhe di argv sono allocate dinamicamente) Fondamenti di Informatica 3 Parametri del main(): esempio 1 Stampa del numero di argomenti ricevuti da linea di comando /* File: argnum.c */ #include <stdio.h> int main(int argc, char *argv[]) { printf("ho ricevuto %d argomenti\n", argc-1); return 0; Compilando si ottiene argnum.exe, che può essere eseguito: > argnum primo secondo terzo > Ho ricevuto 3 argomenti Fondamenti di Informatica 4 2

Parametri del main(): esempio 2 Stampa degli argomenti ricevuti da linea di comando /* File: argprint.c */ #include <stdio.h> int main(int argc, char* argv[]) { int i; printf("ho ricevuto %d argomenti\n", argc-1); printf("questi argomenti sono:\n"); for (i = 1; i <= argc-1; i++) printf("%s\n", argv[i]); return 0; Compilando si ottiene argprint.exe, che può essere eseguito: > argprint primo secondo terzo > Ho ricevuto 3 argomenti > Questi argomenti sono: > primo > secondo > terzo Fondamenti di Informatica 5 Precompilazione 3

Precompilatore Il preprocessore C modifica il codice sorgente in base a "direttive delpreprocessore" inserite nel codice le direttive del preprocessore iniziano con il carattere '#' il preprocessore crea un nuovo "codice sorgente" che è il testo che viene effettivamente compilato questo "codice intermedio" normalmente non viene mandato in output è possibile forzare il compilatore a dare in output questo codice per vedere cosa produce Fondamenti di Informatica 7 Precompilazione La direttiva #include prevede due varianti: #include <nomefile> #include nomefile tale direttiva include il contenuto di un file il file incluso può contenere a sua volte direttive #include nella variante <nomefile> ricerca il file solo negli include delle librerie standard (/usr/include) nella variante nomefile il file nella directory corrente e quindi negli altri path. è possibile specificare path di ricerca aggiuntivi per gli include file tramite opzioni di compilazione Fondamenti di Informatica 8 4

Precompilazione La direttiva #define può essere usata per definire macro sostituzioni. #define text1 text2 chiede al preprocessore di trovare tutte le occorrenze di text1 e di sostituirle con text2. Esempio: #define MAX 1000 Si può usare per macro più complesse (con parametri): #define square(x) ((x)*(x)) La direttiva #undef rimuove la definizione di una certa macro. Fondamenti di Informatica 9 Precompilazione Le direttive #if, #elif, #else, #endif informano il preprocessore di compilare solo alcune parti del codice, al verificarsi o meno di opportune condizioni; possono essere utilizzate per creare codice più efficiente e più portabile: #if condition_1 source_block_1 #elif condition_2 source_block_2... #elif condition_n source_block_n #else default_source_block #endif Fondamenti di Informatica 10 5

Precompilazione E' possibile testare il valore di macro definite con #define Esempio #define ENGLAND 0 #define ITALY 1 #if ENGLAND # include "england.h" #elif ITALY # include "italy.h" #else # include "default.h" #endif Fondamenti di Informatica 11 Precompilazione E' possibile testare l esistenza, a prescindere dal suo valore di una macro con la direttiva #ifdef(macroname) / #ifndef(macroname) #ifdef(debug) some useful debug code #endif oppure con l espressione #if defined(macroname) #if defined(debug) some useful debug code #endif Fondamenti di Informatica 12 6

Precompilazione Uso tipico negli header files per prevenire la doppia inclusione, ad esempio nell header file myheader.h si può scrivere: #if!defined(_myheader_h_included_) #define _myheader_h_included_ contenuto dell header file.. #endif Fondamenti di Informatica 13 Struttura completa di un programma C Ambienti, Variabili globali, Variabili statiche, Dichiarazione e definizioni, Compilazione su più file 7

Struttura di un programma File: prova.c #include <stdio.h>... int m; int f(int); int g(int x){... /* ambiente locale a g */ main(){... /* ambiente locale del main */ int f(int x){... /* ambiente locale a f */ Direttive del preprocessore Dichiarazioni variabili globali e dichiarazioni funzioni (prototipi) Definizione di funzioni Definizione main Definizione di funzioni Fondamenti di Informatica 15 Struttura di un programma Il main è l unica parte obbligatoria Le direttive sono gestite dal preprocessore Le variabili globali sono visibili in tutti gli ambienti del programma Fondamenti di Informatica 16 8

Ambienti Esistono delle regole di visibilità per gli identificatori (nomi di variabili, di funzioni, costanti) che definiscono in quali parti del programma tali identificatori possono essere usati In un programma esistono diversi ambienti: Area globale Main Ogni singola funzione Ogni blocco (delimitato da { e ) Fondamenti di Informatica 17 Ambienti Ambiente globale Dichiarazioni e definizioni che compaiono a livello esterno ( livello di file ), cioè fuori da qualunque funzione. Ambiente locale Dichiarazioni e definizioni che compaiono all interno di una funzione (compresa la sua intestazione) Ambiente di un blocco Dichiarazioni e definizioni che compaiono in un blocco Le definizioni di funzioni non possono essere innestate in altre funzioni o blocchi. E invece possibile inserire dichiarazioni dentro a funzioni o blocchi. Fondamenti di Informatica 18 9

Regole di visibilità (richiami) Un identificatore non è visibile prima della sua dichiarazione Un identificatore definito in un ambiente è visibile in tutti gli ambienti in esso contenuti Se in un ambiente sono visibili due definizioni dello stesso identificatore, la definizione valida è quella dell ambiente più vicino al punto di utilizzo In ambienti diversi si può definire lo stesso identificatore per denotare due oggetti diversi In ciascun ambiente un identificatore può essere definito una sola volta Fondamenti di Informatica 19 Visibilità variabili: considerazioni In C, le variabili della funzione main vivono quanto la funzione main ma non sono visibili in qualunque procedura o funzione, perché il main è una funzione come le altre visibilità delle variabili limitata al blocco in cui sono definite necessità di passarle sempre come parametro alle funzioni che devono usarle Fondamenti di Informatica 20 10

Variabili globali: considerazioni Il C consente di definire delle VARIABILI GLOBALI, ossia delle entità definite fuori da qualunque funzione ( a livello di file ) Esempio: int k; /* VARIABILE GLOBALE */ void modify(void){ k++; /* k è visibile qui... */ main(){ modify(); k *= 5; /*...e anche qui! */ Il C si appoggia al concetto di FILE (fornito dal sistema operativo) come contenitore su cui definire le visibilità k è visibile nel file dove è definita, dal punto in cui è definita in avanti (non sopra!) Fondamenti di Informatica 21 Variabili globali e visibilità int k = 5; /* VARIABILE GLOBALE */ int getvalue(void); main(){ ++k; /* ora k vale 6 */ k = getvalue(); /* valore finale di k = 8 */ int n = 8; /* VARIABILE GLOBALE */ int getvalue(void){ return n; la variabile globale n non è visibile nel main solo getvalue può operare su di essa protezione tuttavia, k e n hanno lo stesso tempo di vita, pari a quello dell intero programma Fondamenti di Informatica 22 11

Variabili globali e visibilità a differenza delle variabili locali alle funzioni (main inclusa!), le variabili globali sono inizializzate automaticamente a zero, se non diversamente specificato int k; /* VARIABILE GLOBALE = 0 */ ma le inizializzazioni implicite non sono leggibili! preferire sempre le inizializzazioni esplicite! int k = 0; /* VARIABILE GLOBALE */ tanto, le inizializzazioni di variabili globali sono calcolate a compile time nessuna inefficienza! Fondamenti di Informatica 23 Variabili globali e visibilità Una variabile globale può essere nascosta da una variabile locale omonima int k = 5; /* VARIABILE GLOBALE */ int getvalue(void); main(){ ++k; /* ora k vale 6 */ k = getvalue(); /* valore finale di k = 8 */ int n = 7; /* VARIABILE GLOBALE */ int getvalue(void){ int k = 1; return k+n; /* è la variabile k locale */ la variabile k definita entro getvalue nasconde quella globale con lo stesso nome dentro getvalue diventa impossibile accedere alla variabile k globale NB: ovviamente, questa getvalue potrebbe evitare di definire k, per l uso che ne fa... Fondamenti di Informatica 24 12

Visibilità variabili locali e globali Riassumendo: Variabili locali e parametri formali sono visibili SOLO all'interno della funzione di cui fanno parte Viceversa, le variabili globali sono visibili ANCHE dentro le funzioni scritte fisicamente di seguito alla definizione della variabile globale stessa, a meno che non siano mascherate da variabili locali omonime Fondamenti di Informatica 25 Variabili globali vs. passaggio dei parametri Le variabili globali rappresentano un altro modo (oltre al classico meccanismo di passaggio dei parametri) con cui far interagire tra loro diversi componenti software: Permettono di restituire in modo diretto i risultati al chiamante. Evitano lunghe liste di parametri (da copiare se passati per valore). ma Fondamenti di Informatica 26 13

Variabili globali vs. passaggio dei parametri ma Il componente non è più autonomo: il suo funzionamento dipende dall esistenza, FUORI DA ESSO, di certi simboli con un certo nome Generalità, riusabilità e portabilità diminuiscono Interazione tra i diversi componenti meno chiara Il componente presenta effetti collaterali Si chiama effetto collaterale (side effect) provocato dalla attivazione di una funzione una qualunque modifica delle variabili non locali a tale funzione Se una funzione ha effetti collaterali, non è più tale in senso matematico. L uso di variabili globali rappresenta dunque una scelta di progetto, legata alla rappresentazione del dominio applicativo Fondamenti di Informatica 27 Tempo di vita delle variabili È legato al luogo di definizione della variabile. Variabili globali: sono allocate all'inizio del programma e vengono distrutte quando il programma termina. Variabili locali e parametri formali delle funzioni: sono allocati ogni volta che si invoca la funzione e distrutti al termine della funzione Non c'è correlazione tra i valori che variabili locali e parametri formali di una funzione assumono nelle diverse attivazioni della funzione stessa. Il loro tempo di vita è quindi pari alla durata dell attivazione della funzione in cui compare la definizione della variabile. Fondamenti di Informatica 28 14

Ancora sulle variabili globali Le variabili globali possono servire anche per costruire componenti software dotati di stato (vedremo più avanti un modo più sicuro per tale realizzazione) Esempio Si vuole costruire una funzione int prossimodispari(void) che restituisca via via il "successivo" dispari Per fare questo, tale componente deve tenere memoria al suo interno dell'ultimo valore fornito Dunque, non è una funzione in senso matematico, perché, interrogata più volte, dà ogni volta una risposta diversa Fondamenti di Informatica 29 Esempio Si utilizza una variabile globale per mantenere lo stato: int ultimovalore = 0; int prossimodispari(void){ return 1 + 2 * ultimovalore++; /* (sfrutta il fatto che i dispari hanno la forma 2k+1) */ int main(){ int i, a; for (i=0; i<30; i++){ a = prossimodispari(); printf( numero dispari: %d\n, a); Fondamenti di Informatica 30 15

Ambiente globale e protezione Il fatto che le variabili globali in C siano potenzialmente visibili in tutti i file dell applicazione pone dei problemi di protezione: Cosa succede se un componente dell'applicazione altera una variabile globale essenziale? Nel nostro esempio: cosa succede se qualcuno altera ultimovalore? Fondamenti di Informatica 31 Ambiente globale e protezione Potrebbe essere utile avere variabili: globali nel senso di permanenti come tempo di vita (per poter costruire componenti dotati di stato)... ma anche protette, nel senso che non tutti possano accedervi Variabili statiche Fondamenti di Informatica 32 16

Variabili statiche (static) In C, una variabile può essere dichiarata static: è permanente come tempo di vita ma è protetta, in quanto è visibile solo entro il suo scope di definizione Nel caso di una variabile statica globale, ogni tentativo di accedervi da altri file, tramite dichiarazioni extern, sarà impedito dal compilatore Fondamenti di Informatica 33 Esempio rivisitato Realizzazione alternativa del componente precedente static int ultimovalore = 0; int prossimodispari(void){ return 1 + 2 * ultimovalore++; /* (sfrutta il fatto che i dispari hanno la forma 2k+1) */ int main(){ int i, a; for (i=0; i<30; i++){ a = prossimodispari(); printf( numero dispari: %d\n, a); Fondamenti di Informatica 34 17

Esempio rivisitato In che senso la variabile static è "protetta"? La variabile ultimovalore èora inaccessibile dall'esterno di questo file: l unico modo di accedervi è tramite prossimodispari() Ma in questo esempio, essendo ultimovalore anche variabile globale, è ancora modificabile dalle altre funzioni Fondamenti di Informatica 35 Variabili statiche dentro a funzioni Una variabile statica può essere definita anche dentro a una funzione. Così: è comunque protetta, in quanto visibile solo dentro alla funzione (come ogni variabile locale) ma è anche permanente, in quanto il suo tempo di vita diventa quello dell intero programma Consente di costruire componenti (funzioni) dotati di stato, ma indipendenti dall'esterno Fondamenti di Informatica 36 18

Esempio rivisitato (2) Ulteriore realizzazione alternativa del componente int prossimodispari(void){ static int ultimovalore = 0; return 1 + 2 * ultimovalore++; /* (sfrutta il fatto che i dispari hanno la forma 2k+1) */ int main(){ int i, a; for (i=0; i<30; i++){ a = prossimodispari(); printf( numero dispari: %d\n, a); Fondamenti di Informatica 37 Variabili statiche: conclusioni Quindi, la parola chiave static ha sempre e comunque due effetti rende l oggetto permanente rende l oggetto protetto (invisibile fuori dal suo scope di definizione) ma se ne vede sempre uno solo per volta una variabile definita in una funzione, che è comunque protetta, viene resa permanente una variabile globale, già di per sé permanente, viene resa protetta Fondamenti di Informatica 38 19

Funzioni come componenti software Una funzione è un componente software (servitore) riutilizzabile: costituisce una unità di traduzione: può essere definita in un unico file e compilata per proprio conto pronta per essere usata da chiunque Fondamenti di Informatica 39 Funzioni come componenti software Per usare tale componente software, il cliente: Non ha bisogno di sapere come è fatto (cioè di conoscerne la definizione) Deve conoscerne solo l interfaccia: Nome Numero e tipo dei parametri Tipo del risultato Fondamenti di Informatica 40 20

Dichiarazione di funzione La dichiarazione (o prototipo) di una funzione è costituita dalla sola interfaccia, senza corpo (sostituito da un ;) <dichiarazione-di-funzione> ::= <tipovalore> <nome>(<parametri>) ; Fondamenti di Informatica 41 Dichiarazione di funzione Dunque, per usare una funzione non occorre conoscere tutta la definizione basta conoscere la dichiarazione, perché essa specifica proprio il contratto di servizio Fondamenti di Informatica 42 21

Dichiarazione di funzione La definizione di una funzione costituisce l effettiva realizzazione del componente: dice come è fatto il componente La dichiarazione specifica il contratto di servizio fra cliente e servitore, esprimendo le proprietà essenziali della funzione. dice come si usa il componente Per usare una funzione non e necessario sapere come è fatta, anzi è controproducente Fondamenti di Informatica 43 Dichiarazione di funzione La dichiarazione specifica: il nome della funzione numero e tipo dei parametri (non necessariamente il nome) il tipo del risultato interfaccia Il nome avrebbe significato solo nell environment della funzione che qui non c è Fondamenti di Informatica 44 22

Dichiarazione vs. Definizione La definizione di una funzione costituisce l effettiva realizzazione del componente: Non può essere duplicata Ogni applicazione deve contenere una e una sola definizione per ogni funzione utilizzata La compilazione della definizione genera il codice macchina che verrà eseguito ogni volta che la funzione verrà chiamata. Fondamenti di Informatica 45 Dichiarazione vs. Definizione La dichiarazione di una funzione costituisce solo una specifica delle proprietà del componente: Può essere duplicata senza danni Una applicazione può contenerne più di una La compilazione di una dichiarazione non genera codice macchina Fondamenti di Informatica 46 23

Dichiarazione vs. Definizione La definizione è molto più di una dichiarazione definizione = dichiarazione + corpo La definizione funge anche da dichiarazione (ma non viceversa) Fondamenti di Informatica 47 Funzioni e file Un programma C è, in prima battuta, una collezione di funzioni una delle quali è il main Il testo del programma deve essere scritto in uno o più file di testo il file è un concetto del sistema operativo, non del linguaggio C Quali regole osservare? Fondamenti di Informatica 48 24

Funzioni e file Il main può essere scritto dove si vuole nel file viene chiamato dal sistema operativo, il quale sa come identificarlo Una funzione, invece, deve rispettare una regola fondamentale di visibilità prima che qualcuno possa chiamarla, la funzione deve essere stata dichiarata altrimenti, si ha errore di compilazione. Fondamenti di Informatica 49 Esempio scorretto (singolo file) File max.c int main() { int m; m = max(5, 8); NOTA: All atto della chiamata, max non è ancora stata definita Errore di compilazione int max (int x, int y ){ if (x>y) return x ; else return y; Fondamenti di Informatica 50 25

Esempio corretto (singolo file) File max.c int max (int x, int y ){ if (x>y) return x ; else return y; NOTA: Prima definisco max poi la uso int main() { int m; m = max(5, 8); Fondamenti di Informatica 51 Esempio corretto (singolo file) File max.c int max (int, int); int main() { int m; m = max(5, 8); prototipo OPPURE: Prima dichiaro max tramite un prototipo, poi la uso e dopo la definisco int max (int x, int y ){ if (x>y) return x ; else return y; Fondamenti di Informatica 52 26

Altro esempio scorretto File prova.c int f(int x){ if (x > 0) return g(x); else return x; ATTENZIONE: f chiama g e g chiama f Quale definisco prima? int g(int x) { return f(x-2); int main() { int y = f(3); Fondamenti di Informatica 53 Esempio corretto (utilità dei prototipi) int g(int); /* prototipo di g */ int f(int x){ if (x > 0) return g(x); else return x; int g(int x) { return f(x-2); int main() { int y = f(3); Fondamenti di Informatica 54 27

Funzioni e file Regola di visibilità prima che qualcuno possa chiamarla, la funzione deve essere stata dichiarata altrimenti, si ha errore di compilazione. Caso particolare: se la definizione funge anche da dichiarazione, la regola è rispettata se la definizione appare prima della chiamata Fondamenti di Informatica 55 Progetti su più file Una applicazione complessa non può essere sviluppata in un unico file: sarebbe ingestibile! Deve necessariamente essere strutturata su più file sorgente compilabili separatamente da fondere poi insieme per costruire l applicazione Fondamenti di Informatica 56 28

Progetti su più file Per strutturare una applicazione su più file sorgente, occorre che ogni file possa essere compilato separatamente dagli altri Poi, i singoli componenti così ottenuti saranno legati (dal linker) per costruire l applicazione Affinchè un file possa essere compilato singolarmente, tutte le funzioni usate devono essere dichiarate prima dell uso - non necessariamente definite! Fondamenti di Informatica 57 Esempio su due file File prog.c int max (int, int); int main() { int m; m = max(5, 8); File max.c Dichiarazione della funzione Chiamata della funzione Definizione della funzione int max (int x, int y ){ if (x>y) return x ; else return y; Fondamenti di Informatica 58 29

Costruzione di una applicazione a partire da più file 1) Compilare i singoli file che costituiscono l applicazione File sorgente: estensione.c File oggetto: estensione.o o.obj f1.c compilatore f1.obj f2.c compilatore f2.obj f3.c compilatore f3.obj Fondamenti di Informatica 59 Costruzione di una applicazione a partire da più file 2) Collegare i file oggetto fra loro e con le librerie di sistema: File oggetto: estensione.o o.obj File eseguibile: estensione.exe o nessuna f1.obj f2.obj linker prog.exe f3.obj Fondamenti di Informatica 60 30

Compilazione di una applicazione Perché la costruzione vada a buon fine: ogni funzione deve essere definita una e una sola volta in uno e uno solo dei file sorgente se la definizione manca, si ha errore di linking ogni cliente che usa una funzione deve incorporare la dichiarazione opportuna se la dichiarazione manca, si ha errore di compilazione nel file del cliente (..forse...!!) Fondamenti di Informatica 61 Header file Per automatizzare la gestione delle dichiarazioni, si introduce il concetto di header file (file di intestazione) contenente tutte le dichiarazioni relative alle funzioni definite nel componente software medesimo scopo: evitare ai clienti di dover trascrivere riga per riga le dichiarazioni necessarie basterà quindi includere l header file tramite una direttiva #include Fondamenti di Informatica 62 31

Header file Il file di intestazione (header) ha estensione.h ha (per convenzione) nome uguale al file.c di cui fornisce le dichiarazioni Ad esempio: se la funzione max è definita nel file max.c il corrispondente header file, che i clienti potranno includere per usare la funzione max, dovrebbe chiamarsi max.h Fondamenti di Informatica 63 Esempio (singolo file) Singolo file int max (int x, int y ){ if (x>y) return x ; else return y; int main() { int m; m = max(5, 8); Fondamenti di Informatica 64 32

Esempio (due file separati) File prog.c (cliente) int max (int, int); int main() { int m; m = max(5, 8); File max.c (servitore) int max (int x, int y ){ if (x>y) return x ; else return y; Fondamenti di Informatica 65 Esempio (due file separati + header) Per includere automaticamente la dichiarazione occorre introdurre un file header File prog.c (cliente) #include max.h int main() { int m; m = max(5, 8); File max.h (header) int max(int, int); Il file max.c rimane invariato! Fondamenti di Informatica 66 33

Riassumendo Convenzione: Se un componente è definito in xyz.c Il file header che lo dichiara, che i clienti dovranno includere, si chiama xyz.h Fondamenti di Informatica 67 Riassumendo struttura dell esempio Struttura finale dell applicazione: un main definito in prog.c una funzione definita in max.c un file header max.h incluso da prog.c max.h prog.c max.c Fondamenti di Informatica 68 34

File header Esistono due formati per l inclusione degli header: #include <libreria.h> include l header di una libreria di sistema il sistema sa già dove trovarlo #include "miofile.h" include uno header scritto da noi occorre indicare dove reperirlo (attenzione al formato dei percorsi..!!) Fondamenti di Informatica 69 35