1 / 36

Unità Didattica 1 Linguaggio C

Unità Didattica 1 Linguaggio C. Fondamenti. Struttura di un programma. La storia del Linguaggio C. UNIX (1969) - DEC PDP-7 Assembly Language

waseem
Télécharger la présentation

Unità Didattica 1 Linguaggio C

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  2. La storia del Linguaggio C • UNIX (1969) - DEC PDP-7 Assembly Language • BCPL - un OS facilmente accessibile che fornisce potenti strumenti di sviluppo prodotti a partire da BCPL. Si tratta di un assemblatore noioso, lungo ed incline agli errori • Un nuovo linguaggio "B" come secondo tentativo (1970) • Un linguaggio "C" totalmente nuovo come successore di "B" (1971) • Dal 1973 UNIX OS, quasi totalmente scritto in C.

  3. La storia del Linguaggio C • E’ stato utilizzato per sviluppare il sistema operativo UNIX, viene comunemente usato per scrivere sistemi operativi • Indipendente dall’hardware (portabile) • Standardizzazione: • inizialmente sono state definite molte piccole varianti del C, incompatibili tra loro; • ANSI (American National Standards Institute) si è occupato della sua standardizzazione, nel 1989, standard aggiornato nel 1999.

  4. Caratteristiche del C • Linguaggio a medio/alto livello. Basso livello di controllodegli errori nella fase di compilazione. • Variabili tipizzate, con notevoli possibilità di conversione mediante il type casting, che permette di forzare una variabile a cambiare tipo; • Abbina ad un medio-alto livello di astrazione,un buon controllo delle operazioni a basso livello.

  5. Fasi di traduzione ed esecuzione di unprogramma C • Traduzione: • Preprocessing: il preprocessore si occupa di includere altri file (es: librerie standard) e sostituisce simboli speciali che seguono particolari direttive (es: costanti simboliche); • Compilazione: traduzione del programma in codiceoggetto (linguaggio macchina (*.obj)); • Linking: risoluzione dei riferimenti a funzioni e variabilidefinite altrove (es. in librerie standard o definitedall’utente), producendo una immagine eseguibile (progr.exe); • Esecuzione: • Loading: caricamento in memoria il codice eseguibile; • Esecuzione delle istruzioni;

  6. Primo programma in C #include <stdio.h> /*# = Preprocessore C precede le direttive che il compilatore valuta prima di iniziare la traduzione effettiva del programma (in questo caso l’inclusione della libreria delle funzioni standard di I/O (stdio.h)) */ main() /* Funzione principale, l’esecuzione di un programma C consiste nella esecuzione del main */ { printf(“Hello world\n”); /* Visualizza sullo standard output (monitor) la frase fra “ ” \n rappresenta un a capo */ }

  7. Esecuzione • Ogni programma comincia la sua esecuzionecon la funzione main. • I commenti sono inseriti tra i caratteri /* e */ (oppure // per commentare un’intera riga) evengono ignorati in fase di compilazione. • In int main (void), la sintassi indica che il programma non ha argomenti di ingresso e che restituisce un valore intero (che indica la terminazione con successo).

  8. Istruzioni e Librerie • Il set di istruzioni del C è molto limitato: leprimitive più comunemente utilizzate (es. I/O,matematiche) sono contenute nelle libreriestandard del C sotto forma di funzioni. • Se si utilizzano delle funzioni contenute in una certa libreria, questa deve essere inclusa mediante la direttiva #include del preprocessore. • Es: • la funzione dioutput printf() è contenuta della libreria standardstdio.h; • Per usare la funzione deve essere presente la direttiva diinclusione: • #include <stdio.h>

  9. Preprocessore • # è il simbolo con cui iniziano i comandi del preprocessore. • Tali comandi nonsono terminati da “;” • Attraverso il preprocessore si esprimono direttive al compilatore; • Principali direttive: • Definizione delle costanti simboliche e dellemacro; • Compilazione condizionale del codice.

  10. Preprocessore: #include • La direttiva #include: consente di includere inla copia di un file specificato. • Esistonodue forme: • #include <nome_file>viene utilizzata per includere file di intestazione (header file) della libreria standard, che sonomemorizzati in directory standard (dipendentidall’implementazione del compilatore); • #include “nome_file” cerca il file nella directory corrente, altrimenti in directory standard (perciò è utilizzata per includere header file definiti dal programmatore).

  11. Preprocessore: #define • La direttiva #define è utilizzata per definirecostanti simboliche e macro. • Il formato è: • #define [identificatore][testo_di_sostituzione] • All’interno del file in cui è presentetutte le successive occorrenze dell’identificatoresaranno automaticamente sostituite dal testo_di_sostituzione, prima della compilazione.

  12. Preprocessore: #define(per definizione di costanti simboliche) • #define PI 3.14159 sostituirà tutte le occorrenze della costantesimbolica PI con quella numerica 3.14159

  13. Preprocessore: #define(per definizione di macro) • Le macropossono essere definite con o senza argomenti. • Una macro senza argomenti viene elaboratacome una costante simbolica. • In una macro con argomenti, essi sarannorimpiazzati all’interno del testo di sostituzionee solo in seguito sarà espansa la macro: ovvero, il testo di sostituzione rimpiazzeràla lista degli identificatori e degli argomenti all’interno del programma. • Esempio: • #define AREA_CERCHIO(x) ( PI * (x) * (x) ) ogni volta che nel programma appare AREA_CERCHIO(r) ilvalore di r sarà usato al posto di x, la costante PI sarà rimpiazzata dal suo valore (definito precedentemente) e la macro verrà espansa all’interno del programma.

  14. Preprocessore: #define(per definizione di macro) • Esempio 1: • area = AREA_CERCHIO(4) sarà espanso in • area = ( 3.14159 * (4) * (4) ); • Esempio 2: • area = AREA_CERCHIO(c+2) sarà espanso in • area = ( 3.14159 * (c+2) * (c+2) ); • Vantaggi nell’uso delle macro: • risparmio nella definizione di una funzione; • miglioramento nella leggibilità del programma.

  15. Preprocessore:Compilazione condizionale • Consente alprogrammatore di controllare la compilazione delcodice del programma. • Le direttive condizionalidel preprocessore vengono valutate come espressioni costanti intere. • Esempio: #define DEBUG #ifdef DEBUG printf(“Variabile x = %d\n”, x ); #endif l’istruzione printf viene compilata (ed eseguita) solo nel caso in cui la variabile DEBUG sia definita.

  16. Variabili • In C ogni variabile è caratterizzata dai seguenti aspetti: • Tipo; • Classe di memoria. • Assegnare un tipo ad una variabile significa assegnarle il dominio dal quale assume i valori; • La classe di memoria determina la durata della vita (ciclo di vita) e l’ambito di visibilità (scope) delle variabili.

  17. Tipi di dati • Tipi di base – char: carattere – int: intero – float: virgola mobile, singola precisione – double: virgola mobile, doppia precisione – void: indica che il dominio della variabile è l’insieme vuoto • Qualificatori: – unsigned: (es: unsigned int, unsigned char) – short: (es: short int) – long: (es: long int, long double)

  18. Dichiarazione di Variabili • [tipo_var] var0, var1, …; • E' possibile inizializzare una variabile al momento della dichiarazione: • Esempi: int i, j, k=1; float x=2.6, y; char a;

  19. Dichiarazione di Costanti • La definizione di identificatori per le costanti, oltreche con il comando di preprocessore #define, può avvenire usando il modificatore const: const tipo nome_costante = valore ; • Esempi: const double e = 2.71828182845905;

  20. Funzioni • Generalizzazione del concetto di funzione algebrica: • legge che associa a valori delle variabili in ingresso valori della variabili in uscita o, più in generale, azioni. • Raggruppano operazioni che possono essere riutilizzate usando il nome della funzione e i suoi parametri (chiamata della funzione), senza preoccuparsi dell’aspetto implementativo; • I programmi in C combinano funzioni definite dal programmatore con funzioni di libreria standard; • Una funzione deve essere definita (definizione) e dichiarata (prototipo), prima della definizione, relativamente al nome e ai tipi dei parametri in ingresso e in uscita.

  21. Parametri alle funzioni • Una funzione può avere dei parametri in ingresso e un parametro di uscita (tale fatto non rappresenta una limitazione perché si può restituire anche una struttura dati complessa); • Se non si vuol restituire alcun valore da una funzione èsufficiente dichiararla di tipo void ed omettere o meno il return; • E’ obbligatorio mettere le parentesi () (oppure (void)) dopo il nome della funzione anche se non ci sono parametri in ingresso. • void funz(void) oppure: void funz()

  22. Parametri alle funzioni • In C i parametri alle funzioni sono sempre passati per valore; • Al momento della chiamata, le funzioni allocano (riservano) memoria per le variabili d’ingresso; • In ciascuna variabile viene copiato il valore che le viene passato al momento della chiamata.

  23. Definizione e prototipo e chiamata di una funzione #include <stdio.h> [tipoUscita] nomeFunzione([tipo0],[tipo1]); //Prototipo void main() { [tipoUscita] a; [tipo0] x; [tipo1] y; … a = nomeFunzione(x, y); //Chiamata } [tipoUscita] nomeFunzione([tipo0] var0, [tipo1] var1) { //Definizione … }

  24. Esempio di passaggio di parametri:Calcolo della potenza di un numero #include <stdio.h> int potenza(int, int); //Prototipo void main() { int x, y, z; x = 2; y = 3; z = potenza(x, y); //Chiamata } //Definizione int potenza(int base, int n) { int i, p = 1; for(i = 0; i < n; i++) p = p * base; return (p); } x y 3 2 Passaggio al momento della chiamata base n 3 2

  25. Esempio di passaggio di parametri in funzioni ricorsive #include <stdio.h> long int fattoriale(int); //Prototipo void main() { long int fatt; int n; scanf(“%d”, &n); fatt = fattoriale(n); } long int fattoriale(int n) { if (n == 0) return 1; return (n * fattoriale(n-1)); }

  26. Struttura di un programma C /* commenti: nome programma, descrizione, etc. */ #istruzioni per il preprocessore dichiarazione di tipi, variabili, costanti; prototipi delle funzioni; tipo_di_ritorno main (lista_argomenti) { dichiarazione variabili locali sequenza di istruzioni } tipo_di_ritorno funzione_1 (lista_argomenti) { dichiarazione variabili locali sequenza di istruzioni } tipo_di_ritorno funzione_n (lista_argomenti) { … }

  27. Scrittura di un programma C su più moduli (file) • Quando si scrivono programmi di grosse dimensioni è consigliabilesuddividere i programmi in moduli separati. La funzione main() sarà contenuta in un solo file (es: “mioprogr.c”); • E’ buona norma concentrare inclusioni di librerie standard, dichiarazioni e prototipi necessari ad un modulo, in un unico file (header file) da includere in tale modulo (es: #include “mioprogr.h”); • Esiste un compromesso fra il desiderio che ogni modulo acceda solo alle informazioni di cui ha bisogno (N moduli => N header file) e la realtà pratica secondo la quale è difficile gestire molti header file; • Per programmi di dimensioni ridotte è meglio avere un unico header file contenente le informazioni da condividere fra due punti qualunque del programma scritto su più moduli e includere in essi l’unico header file creato;

  28. Scrittura di un programma C su più moduli e un unico header file #include <mioprogr.h> void main() { … } #include <mioprogr.h> [tipo1] funz3([tipo0] var0) { … } [tipo5] funz2([tipo3] var1) { … } #include <mioprogr.h> [tipo0]funz0([tipo0] var0) { … } [tipo3]funz1([tipo0] var7) { … } mioprogr.c #include <stdio.h> #define … Variabili globali; Prototipi funzioni; mod1.c mod2.c Header file: file, da includere in ogni modulo,contenente inclusione di librerie,dichiarazioni e prototipi. mioprogr.h

  29. Classi di Memorizzazione delle Variabili • Variabili locali (automatiche); • Variabili globali (esterne);

  30. Variabili Locali (o automatiche) • Parola chiave auto o nessuna dichiarazione; • Sono interne ad un blocco individuato da … (es: interne ad una funzione); • Scope (ambito di visibilità): visibili (accessibili) solo all’interno del blocco di definizione; • Ciclo di vita: create al momento della dichiarazione, cessano di esistere quando si esce dal blocco; • Sono inizializzate con valori casuali.

  31. Esempi di dichiarazione di variabili automatiche #include <stdio.h> void main(void)  int i, j; … funz();  void funz()  int i, j; //Sono variabili automatiche,ovvero //locali alla funzione. Fuori dalla //funz non sono più accessibili, cessano //di esistere (per esempio le due //variabili “i, j” definite nel “main” //sono del tutto scorrelate da queste). 

  32. Modifica del ciclo di vita di variabili locali • E’ possibile modificare il ciclo di vita di una variabile locale in modo che conservi il suo valore fra l’uscita e il successivo rientro nella funzione o nel blocco nel quale è stata dichiarata; • Tale modifica si ottiene anteponendo alle variabili locali la parola chiave static: void funz()  static int i, j; //Sono variabili automatiche, ovvero //locali alla funzione. Fuori dalla //funz non sono più accessibili ma al //rientro nella funzione riacquistano //il valore che avevano al momento //dell’uscita dalla funzione stessa. 

  33. Variabili Globali (o esterne) • Sono dichiarate una sola volta esternamente a qualsiasi blocco; • Devono essere rese note alle funzioni o ad altri moduli tramite la parola chiave extern (eccetto il caso in cui la dichiarazione preceda la funzione o il blocco in uno stesso modulo (es: all’inizio di un modulo, come avviene nella pratica)). • Scope (ambito di visibilità): • Se rese note ad un blocco con l’uso di extern: ovunque, anche in moduli diversi; • Se rese note ad un blocco senza l’uso di extern: ovunque, nello stesso modulo, a partire dalla loro dichiarazione in avanti; • Ciclo di vita: Esistono e conservano il loro valore ovunque siano visibili all’interno del programma (es: uscita e successivo rientro da funzioni o blocchi);

  34. Variabili globali in un unico modulo #include <stdio.h> int i, j; //variabili globali inizializzate a 0 void main(void)  extern int i, j; //in questo caso la //dichiarazione viene //generalmente omessa int x; i = 2; j = 3; x = i + j; 

  35. Variabile globale condivisa in più moduli #include <stdio.h> extern int i; void funz(void); void funz(void)  int j; j = i+1; …  #include <stdio.h> int i; void main(void)  funz();  mioprogr.c mod1.c i è globale per entrambi i moduli

  36. Variabile globale condivisa in più moduli con uso di header file #include <stdio.h> int i; void funz(void); … mioprogr.h #include “mioprog.h” void funz()  int j; j = i+1; …  #include “mioprog.h” void main(void)  funz();  i è globale perentrambi i moduli (mioprogr.c, mod1.c) mioprogr.c mod1.c

More Related