PROGETTI STRUTTURATI SU PIÙ FILE

Slides:



Advertisements
Presentazioni simili
Una applicazione complessa non può essere sviluppata in un unico file: sarebbe ingestibile! Deve necessariamente essere strutturata su più file sorgente.
Advertisements

Code::Blocks Ambiente di sviluppo.
7) Creazione di un programma eseguibile
Creazione di un programma eseguibile. Laboratorio di Calcolo AA2005/062 Livelli di programmazione Si può programmare a diversi livelli utilizzando linguaggi.
Espressioni condizionali
Per costruire unapplicazione occorre compilare il file (o i file se più duno) che contengono il testo del programma (file sorgente) Il risultato sono uno.
Scrivere e compilare programmi
Compilazione separata
La dichiarazione di una funzione è costituita dalla sola interfaccia, senza corpo (sostituito da un ; ) ::= ( ) ; DICHIARAZIONI DI FUNZIONE.
Table View. Problemi ricorrenti Una situazione ricorrente è quella in cui il controller potrebbe avere un’altezza superiore a quella dello schermo. In.
Fondamenti di Informatica - D. Talia - UNICAL 1 Fondamenti di Informatica FONDAMENTI DI INFORMATICA Domenico Talia
1 Elementi DI INFORMATICA Università degli Studi di Cagliari Corso di Laurea in Ingegneria Elettronica Linguaggio C A.A. 2011/2012
Gestione delle configurazioni Configuration management (CM) E` un processo che controlla le modifiche fatte a un sistema e gestisce le diverse versioni.
Gestione dei Software in GNU/Linux HackLab Catanzaro Installazione software da sorgente 8° Lezione GNU/Linux Base
1 Come cercare le fonti di informazione scientifica Operatori e wildcards a cura della Biblioteca di Agraria.
PGDay 2009 FSGateway Ing. Torello Querci Resp. Architetture SW - Negens S.r.l. 4 Dicembre 2009, Pisa.
.  I tipi di dati non primitivi sono gli array, le struct e le union.  Gli array sono degli aggregati di variabili dello stesso tipo.  La dichiarazione.
Fondamenti di Informatica - D. Talia - UNICAL 1 Fondamenti di Informatica PROBLEMI E ALGORITMI LINGUAGGIO MACCHINA.
CONTROLLO DELLA CONCORRENZA
La chimica della vita Ogni organismo vivente è una macchina sofisticata, risultato di un complesso insieme di reazioni chimiche. La costruzione e il funzionamento.
Ereditarietà Uno dei principi della programmazione orientata agli oggetti (OOP) è il riuso Le classi dovrebbero essere progettate come componenti riutilizzabili.
Corso per Webmaster base
IL SOFTWARE (FPwin 6.0).
© 2007 SEI-Società Editrice Internazionale, Apogeo
VISUAL BASIC.
Indagine sulla produzione libraria nel 2015
Introduzione al linguaggio C
Dal problema al processo risolutivo
Gli array Moreno Marzolla
Programmazione per la Musica | Adriano Baratè
Dal problema al processo risolutivo
Progetto n°1 con il Pannello operatore
I comandi.
L’AMBIENTE CODE BLOCKS E L’IO
I FILES AD ACCESSO SEQUENZIALE
Qt by Examples LINUX DAY
PROGRAMMAZIONE BASH – ISTRUZIONE IF
I tag essenziali.
istalliamo l’ambiente di sviluppo - ide
Programmazione e Laboratorio di Programmazione
Basi di dati - Fondamenti
Programmare.
suggerimenti Alma (solo per uso interno)
Secondo Programma in C.
Struttura di un programma
Questionari on line GOOGLE DRIVE.
Struttura di un programma
SQL per la modifica di basi di dati
ADO Per gestire i database con tecnologia ASP si utilizzano strumenti ADO (ActiveX Data Objects): un'architettura che fornisce oggetti.
Richiesta Accreditamento dei Soggetti Attuatori
© 2007 SEI-Società Editrice Internazionale, Apogeo
Sviluppo di un programma
Definizione di linguaggio di programmazione
APPUNTI SUL LINGUAGGIO C
Programmazione e Laboratorio di Programmazione
Fondamenti di Informatica
La struttura dei primi programma in C
Fogli elettronici e videoscrittura
Processi decisionali e funzioni di controllo
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Unità 1 Programmi base.
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Array e Stringhe Linguaggio C.
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione Procedurale
Transcript della presentazione:

PROGETTI STRUTTURATI 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.

FUNZIONI COME COMPONENTI SW Una funzione è un componente software (servitore) riutilizzabile che costituisce una unità di traduzione: può essere definita in un file a sé stante e compilata per proprio conto pronta per essere usata da chiunque

FUNZIONI COME COMPONENTI SW Per usare tale componente software, il cliente: non ha bisogno di sapere come è fatto (cioè, di conoscerne la definizione) deve conoscerne solo l’interfaccia, ossia la dichiarazione.

DALL’ESEMPIO SU UN SOLO FILE... File prova1.c int fact(int); main() { int y = fact(3); } int fact(int n) { return (n<=1) : 1 : n*fact(n-1);

... ALL’ESEMPIO SU DUE FILE File main.c Dichiarazione della funzione int fact(int); main() { int y = fact(3); } Uso (chiamata) File fact.c Definizione della funzione int fact(int n) { return (n<=1) : 1 : n*fact(n-1); }

COMPILAZIONE DI UN’APPLICAZIONE 1) Compilare i singoli file che costituiscono l’applicazione File sorgente: estensione .c File oggetto: estensione .o o .obj f1.c f2.c f3.c f1.obj f2.obj f3.obj compilatore

COLLEGAMENTO DI UN’APPLICAZIONE 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 prog.exe f1.obj f2.obj f3.obj linker

COSTRUZIONE DI UN’APPLICAZIONE Perché la costruzione vada a buon fine: ogni funzione deve essere definita una e una sola volta in uno dei file sorgente se la definizione manca, si ha errore di linking ogni cliente che usi una funzione deve incorporare la dichiarazione opportuna se la dichiarazione manca, si ha errore di compilazione nel file del cliente (..forse...!!)

IL RUOLO DEL LINKER Perché, esattamente, serve il linker? Il compilatore deve “lasciare in bianco” i riferimenti alle chiamate di funzione che non sono definite nel medesimo file Compito del linker è risolvere tali riferi-menti, riempiendo gli “spazi bianchi” con l’indirizzo effettivo del codice della funzione.

COSTRUZIONE “MANUALE” Attivare il compilatore su ogni singolo file sorgente C:\TMP> gcc -c fact.c C:\TMP> gcc -c main.c Attivare il linker per unire i rispettivi file oggetto e le librerie di sistema C:\TMP> ld -o prog.exe fact.obj main.obj –lc ... un lavoraccio!

COSTRUZIONE NEGLI AMBIENTI INTEGRATI Negli ambienti integrati, tutto ciò viene automatizzato Si predispone un progetto che contenga tutti i file sorgente (.c) necessari Si costruisce l’applicazione normalmente (Make / F9)

PROGETTI SU PIÙ FILE IN DJGPP/RHide Dalla finestra Add item che appare si selezionano tutti i file sorgente (.c) da inserire nel progetto.

PROGETTI SU PIÙ FILE IN TURBO C Dalla finestra Add to Project List si selezionano tutti i file sorgente (.c) da inserire nel progetto.

VARIABILI GLOBALI come COMPONENTI SW Anche una variabile globale è un componente software in particolare, un componente che fornisce dati (non comportamenti) come tale, costituisce una unità di traduzione: può essere definita in un file a sé stante e compilata per proprio conto pronta per essere usata da chiunque

VARIABILI GLOBALI come COMPONENTI SW Il cliente deve incorporare la dichia- razione della variabile globale che intende usare extern int trentadue; Uno dei file sorgente nel progetto dovrà contenere la definizione (ed eventualmente l’inizializzazione) della variabile globale int trentadue = 10;

DALL’ESEMPIO SU UN SOLO FILE... File prova4.c float fahrToCelsius(float f); main() { float c = fahrToCelsius(86); } extern int trentadue; float fahrToCelsius(float f) { return 5.0/9 * (f-trentadue); int trentadue = 32;

... ALL’ESEMPIO SU TRE FILE File main.c float fahrToCelsius(float f); main() { float c = fahrToCelsius(86); } File f2c.c extern int trentadue; float fahrToCelsius(float f) { return 5.0/9 * (f-trentadue); } File 32.c int trentadue = 32;

ARCHITETTURA DELL’APPLICAZIONE Chi usa cosa Il main usa la funzione fahrToCelsius La funzione fahrToCelsius usa la variabile globale trentadue File main.c File f2c.c usa File 32.c usa

GESTIRE PROGETTI COMPLESSI Perché queste architetture funzionino, ogni cliente deve contenere le dichiara- zioni di tutte le funzioni (e le variabili globali) che usa In una applicazione complessa, fatta di decine di file, non è pensabile che questo venga fatto a mano, mediante copia & incolla “file per file”: OCCORRE UN AUTOMATISMO

IL PRE-PROCESSORE C Quando si compila un programma C, il compilatore non riceve esattamente il testo del programma da noi fornito riceve una versione "riveduta e corretta" da "qualcuno" che si interpone tra noi e il compilatore vero e proprio: il PRE-PROCESSORE C File sorgente .c File modificato al compi-latore C preproc.

IL PRE-PROCESSORE C Il pre-processore modifica il testo del programma prima che esso raggiunga il compilatore C vero e proprio. Così, può svolgere alcune utili funzioni di manipolazione del testo al nostro posto File sorgente .c File modificato al compi-latore C preproc. un testo un altro testo

Il pre-processore non è un compilatore C non conosce il linguaggio C IL PRE-PROCESSORE C Il pre-processore non è un compilatore C non conosce il linguaggio C non può interpretare le istruzioni C, né controllarne la correttezza non sa cosa fa: è solo un automa che agisce sul testo del programma potrebbe manipolare qualunque testo, non solo programmi C programmi Pascal, poesie, lettere commerciali, lettere d’amore...

IL PRE-PROCESSORE C Cosa può fare? includere altre porzioni di testo, prese da altri file effettuare ricerche e sostituzioni (più o meno sofisticate) sul testo inserire o sopprimere parti del testo a seconda del verificarsi di certe condizioni da noi specificate.

IL PRE-PROCESSORE C Come si controlla il suo funzionamento? mediante direttive inserite nel testo. Attenzione: le direttive non sono istruzioni C non ne hanno neanche la sintassi! infatti, non sono destinate al compilatore, che non le vedrà mai vengono soppresse dal pre-processore dopo essere state da esso interpretate.

DIRETTIVE AL PRE-PROCESSORE C Principali direttive includere altre porzioni di testo #include nomefile effettuare ricerche e sostituzioni #define testo1 testo2 inserire o sopprimere parti del testo #ifdef condizione …testo... #endif

LA DIRETTIVA #include Sintassi: #include <libreria.h> #include “miofile.h” Effetto: include il contenuto del file specificato esattamente nella posizione in cui si trova la direttiva stessa.

float fahrToCelsius(float f); ESEMPIO Situazione iniziale: File main.c #include "f2c.h" main() { float c = fahrToCelsius(86); } File f2c.h float fahrToCelsius(float f);

Situazione dopo il pre-processing: ESEMPIO Situazione dopo il pre-processing: File main.c modificato dal pre-processore float fahrToCelsius(float f); main() { float c = fahrToCelsius(86); } Dopo che il pre-processing è avvenuto, il file .h non serve più.

...il pre-processing si può vedere: SE SIETE CURIOSI... ...il pre-processing si può vedere: C:\TMP> gcc -E main.c -E effettua solo il pre-processing C:\TMP> gcc -C -P -E main.c -P non numera le righe (che di solito vengono numerate) -C non toglie i commenti (che di solito vengono tolti)

SE SIETE ANCORA PIÙ CURIOSI... ... si può vedere perfino il programma tradotto in linguaggio macchina: C:\TMP> gcc -S main.c -S crea un file main.S con il testo in linguaggio macchina che sarà generato _main: pushl %ebp call _fahrToCelsius movl %esp,%ebp addl $4,%esp subl $4,%esp fstps -4(%ebp) call ___main leave pushl $0x42ac0000 ret

FILE HEADER Per automatizzare l’incorporazione delle dichiarazioni necessarie, si usa predisporre uno o più file di intestazione (header) estensione .h destinati a essere inclusi dai clienti (file .c) mediante direttive #include. File f2c.h float fahrToCelsius(float f);

se un componente è definito in xxx.c FILE HEADER Convenzione: se un componente è definito in xxx.c il file header corrispondente, che i clienti dovranno includere, si chiama xxx.h File main.c (cliente) #include "f2c.h" main() { float c = fahrToCelsius(86);} File f2c.c (servitore) float fahrToCelsius(float f){...}

FILE HEADER Attenzione: Due formati: i file header non sono parte del progetto sono usati dai file sorgente Due formati: #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

FILE HEADER - CAUTELE D’USO Un file header deve contenere solo dichiarazioni ! Se contiene anche solo una definizione possono crearsi situazioni di errore (rischio di definizioni duplicate).

FILE HEADER - CAUTELE D’USO Esempio un main usa le funzioni f1 e f2 sia f1 sia f2 usano la funzione f lo header di f contiene la definizione invece della dichiarazione È un falso header ! main.c f1.c f2.c f.h #include “f1.h” #include “f2.h” ... #include “f.h” ... #include “f.h” ... int f(int x) { return … ; }

FILE HEADER - CAUTELE D’USO La compilazione fila liscia: f1.c e f2.c si compilano senza problemi Attenzione !! - ognuno include una definizione di f il main si compila senza problemi... main.c f1.c f2.c #include “f1.h” #include “f2.h” ... #include “f.h” ... #include “f.h” ... gcc gcc gcc

FILE HEADER - CAUTELE D’USO Ma il linker dà errore in fase di collegamento Infatti, la definizione di f risulta due volte il relativo codice è duplicato!! main.o f1.o f2.o link