Laboratorio di linguaggi
Progetti
Struttura di un programma
#include<stdio.h> Direttive
#define MAX 10
int x; Dichiarazioni globali
int f(int); e prototipi di funzioni int g(int x) Dichiarazioni di funzioni {
... Ambiente locale a g
}
Struttura di un programma
int main(void) Dichiarazione del main {
... Ambiente locale a main
}
int f(int a) Dichiarazioni di funzioni {
... Ambiente locale a f
}
Progetti
Laboratorio di Linguaggi 3 7-06-2004
Andr´as Horv´ath
Struttura di un programma
• il main `e l’unica parte obbligatoria
• le variabili globali sono visibili in tutti gli ambienti
• altre variabile sono visibili nel ambiente in cui vengono dichiarati
• gli ambienti – area globale
– le funzioni (anche il main `e una funzione) – blocchi
Struttura di un programma Regole di visibilit`a:
• variabile non `e visibile prima della sua dichiarazione
• variabile definita in un ambiente `e visibile in tutti gli ambienti in esso contenuti
• in ambienti diversi si po`u definire due variabili con lo stesso identificatore
• in un ambiente non si po`u usare lo stesso identificatore due volte
• se due inteficicatori sono visibili nello stesso ambiente, viene considerato la dichiarazione pi`u vicina (ma `e meglio evitare questo caso)
Progetti
Laboratorio di Linguaggi 5 7-06-2004
Andr´as Horv´ath
Struttura di un programma
• scorretto:
int f(int) {
int a=b+10;
int b=20;
}
• corretto:
int f(int) {
int b=20;
int a=b+10;
}
Struttura di un programma Regole di visibilit`a:
double b=1.4; // variabile globale void main(void)
{
int a,b=5; // variabili locali di main a=b;
...
}
Nella funzione main b `e un intero, e quindi a vale 5.
Progetti
Laboratorio di Linguaggi 7 7-06-2004
Andr´as Horv´ath
Struttura di un programma Regole di visibilit`a:
int x,y;
{
int z;
z=4;
}
printf(" %d\n",z);
→ errore di compilazione: ’z’ undecleared
Struttura di un programma Regole di visibilit`a:
int x=1;
while(x++<=5) {
int z=x;
printf("%d ",z);
}
produce: 2 3 4 5 6
Progetti
Laboratorio di Linguaggi 9 7-06-2004
Andr´as Horv´ath
Struttura di un programma Visibilit`a di funzioni:
• prima che qualcuno possa chiamare la funzione, la sua interfaccia deve essere conosciuta
• interfaccia (prototipo):
– tipo restituito – nome della funzione
– elenco dei tipi dei parametri
• due soluzioni:
– l’intera funzione (interfaccia+corpo) `e prima della chiamata – viene fornito il prototipo (interfaccia) della funzione prima
della chiamata
Struttura di un programma Scorretto:
void main(void) {
printf("%f\n",f(3));
}
double f(int a) {
return 2.0*a*a+5.0*a+10.0;
}
Progetti
Laboratorio di Linguaggi 11 7-06-2004
Andr´as Horv´ath
Struttura di un programma Corretto:
double f(int a) {
return 2.0*a*a+5.0*a+10.0;
}
void main(void) {
printf("%f\n",f(3));
}
Struttura di un programma Corretto:
double f(int a);
void main(void) {
printf("%f\n",f(3));
}
double f(int a) {
return 2.0*a*a+5.0*a+10.0;
}
Progetti
Laboratorio di Linguaggi 13 7-06-2004
Andr´as Horv´ath
Programmazione con pi`u file di sorgente
• progetto complesso non po`u essere sviluppato in un unico file (sarebbe ingestibile)
• deve essere strutturata su pi`u file sorgenti
• vengono compilati separatamente
• poi vengono “combinati” (dal linker) per costruire l’applicazione
• funzioni sono riutilizzabili da altri applicazioni
• permette di lavorare in gruppi
Compilazione
• occore che ogni file posse essere compilato separatmente dagli altri
• per compilare un file: ogni volta quando una funzione `e chiamata, la sua interfaccia (prototipo) deve essere conosciuta
• il “corpo” della funzione chiamata non deve essere presente
Progetti
Laboratorio di Linguaggi 15 7-06-2004
Andr´as Horv´ath
Compilazione
Un file (main.c) con le seguente righe po`u essere compilato.
#include<stdio.h>
double f(int a);
void main(void) {
printf("%f\n",f(3));
}
Per compilarlo: gcc -c main.c. Viene generato il file oggetto main.o.
Compilazione In un altro file (f.c) `e realizzata la funzione f:
double f(int a) {
return 2.0*a*a+5.0*a+10.0;
}
Compilando anche questo: gcc -c f.c viene generato il file oggetto f.o .
Progetti
Laboratorio di Linguaggi 17 7-06-2004
Andr´as Horv´ath
Collegare i file oggetto Per poter collegare i file un un singolo applicazione
• ogni funzione chiamata deve essere implementata una a una volta in uno e uno file
• bisogna avere una funzione main Esempio precedente:
gcc f.c main.c -o prova.exe e viene generato il file prova.exe .
I file di intestazione (header file) Serve per rendere automatico la gestione dei prototipi:
• contiene il prototipi di tutte le funzioni che possono essere chiamate
• il suo scopo `e quello di evitare i prototipi riga per riga
• basta includere il file header con #include
Progetti
Laboratorio di Linguaggi 19 7-06-2004
Andr´as Horv´ath
I file di intestazione (header file) Contenuto del file read.c:
#include<stdio.h>
int read_int(char *s) {
int i;
printf("%s\n",s);
scanf("%d",&i);
return i;
}
I file di intestazione (header file) float read_float(char *s)
{
float f;
printf("%s\n",s);
scanf("%f",&f);
return f;
}
Progetti
Laboratorio di Linguaggi 21 7-06-2004
Andr´as Horv´ath
I file di intestazione (header file) Contenuto del file read.h:
int read_int(char *s);
float read_float(char *s);
I file di intestazione (header file) Contenuto del file main.c:
#include<stdio.h>
#include"read.h"
void main(void) {
int i;
i=read_int("Ho bisogno di un numero intero:");
printf("%d\n",i);
}
Progetti
Laboratorio di Linguaggi 23 7-06-2004
Andr´as Horv´ath
I file di intestazione (header file)
Header file nasconda funzioni che non possono essere chiamati.
Aggiungiamo le seguente righe al file read.c . int **alloc_matrix(int r, int c)
{
int **m;
// alloca memoria per una matrice r*c ...
return m;
}
I file di intestazione (header file) int ** read_matrix(int r, int c)
{
int **m;
m=alloc_matrix(r,c);
// legge il contenuto della matrice dal utente ...
return m;
}
Progetti
Laboratorio di Linguaggi 25 7-06-2004
Andr´as Horv´ath
I file di intestazione (header file) Contenuto del file read.h:
int read_int(char *s);
float read_float(char *s);
int ** read_matrix(int r, int c);
La funzione alloc_matrix `e nascosto.
I file di intestazione (header file) Due formati:
• #include<libreria.h>:
– include una libreria di sistema – `e gi`a compilato
– il compilatore sa dove trovarlo
• #include"libreria.h":
– include una libreria mia – devo compilarla
– devo far’ sapere al compilatore dove si trova
Progetti
Laboratorio di Linguaggi 27 7-06-2004
Andr´as Horv´ath
Comunicazione fra i moduli Due modi per comunicare dati da un modulo al altro:
• tramite argomenti passati e restituiti dalle funzioni
• tramite variabili extern Le variabili extern
• extern indica che la variabile `e gi`a dichiarata altrove
• lo spazio per la variabile `e allocato altrove
• nel modulo in cui la variabile `e dichiarata “normalmente”
(cio`e senza extern), la variabile deve essere globale
Comunicazione fra i moduli Contenuto del file main.c:
#include<stdio.h>
void change_x(void);
int x=5;
void main(void) {
printf("%d",x);
change_x();
printf("%d\n",x);
}
Progetti
Laboratorio di Linguaggi 29 7-06-2004
Andr´as Horv´ath
Comunicazione fra i moduli Contenuto del file change.c:
void change_x(void) {
extern int x;
x=10;
}
Compilando tutto:
gcc -c main.c gcc -c change.c
gcc main.o change.o -o main.exe main.exeproduce: 5 10