Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni BCOR Ingegneria Elettronica BELR Domenico Daniele Bloisi
Docenti Parte I prof. Silvio Salza salza@dis.uniroma1.it http://www.dis.uniroma1.it/~salza/fondamenti.htm Parte II ing. Domenico Daniele Bloisi, PhD bloisi@dis.uniroma1.it http://www.dis.uniroma1.it/~bloisi/didattica/fondinf1112.html Nota: %7E corrisponde alla tilde ~ Pagina 2
Informazioni Generali ing. Domenico Daniele Bloisi, PhD Dipartimento di Informatica e Sistemistica Via Ariosto 25 (adiacente Piazza Dante, A fermate Manzoni, Vittorio Emanuele, Tram 3 fermata via Labicana) mailto:bloisi@dis.uniroma1.it http://www.dis.uniroma1.it/~bloisi Pagina 3
Ricevimento Su appuntamento. Inviare una email per conferma. DIS, via Ariosto 25 II piano, stanza B211 Si consiglia di controllare la bacheca degli avvisi http://www.dis.uniroma1.it/~bloisi/didattica/fondinf1112.html#avvisi Pagina 4
Programma Preliminare Parte II - Programmazione Concetti introduttivi. Algoritmo, variabili, identificatori simbolici, parole chiave, standard input e standard output, esecuzione di programmi C su macchine reali, compilazione, ambiente gcc. Struttura sintattica di un programma C. Istruzione di assegnamento, istruzioni di ingresso/uscita, istruzioni composte, condizioni, strutture iterative (for, while, do...while). Parte dichiarativa, dichiarazione di variabili, dichiarazione di costanti, direttive del preprocessore, istruzioni printf e scanf con relative specifiche di conversione. Tipo di dato. Tipi semplici predefiniti del C, tipo int, tipo float, tipo char, valutazione delle espressioni booleane. Puntatori, aritmetica dei puntatori, operatori aritmetici, operatori logici, operatori di incremento/decremento. Funzioni. Il concetto di sottoprogramma, definizione delle funzioni, parametri formali, passaggio di parametri per valore e per riferimento, i blocchi, visibilità (scope) degli identificatori, ciclo di vita delle variabili, passaggio di parametri di tipo array. Strutture dati dinamiche. Allocazione e cancellazione della memoria: malloc, e free, allocazione dinamica di array Gestione dei File in C. Apertura di un file in C, lettura e scrittura formattata su file (fprintf,fscanf), lettura e scrittura di caratteri e righe su file, chiusura di un file, gestione degli errori e fine file. Pagina 5
Unità didattiche Parte II - Programmazione 9 unità didattiche : introduzione al linguaggio C e funzione main Unità 2: variabili e tipi di dato Unità 3: istruzioni condizionali Unità 4: istruzioni di ciclo Unità 5: funzioni e ricorsione Unità 6: puntatori Unità 7: array e matrici Unità 8: stringhe e file Unità 9: direttive del preprocessore Pagina 6
Obiettivi del corso Imparare i concetti di algoritmo e programma Imparare a risolvere problemi in modo algoritmico Imparare a tradurre un algoritmo in programma Imparare a scrivere programmi in linguaggio C Pagina 7
Sommario : Introduzione Architettura dei calcolatori Linguaggi di programmazione Programmi = dati + operazioni Primo programma C Scrittura, compilazione, esecuzione di un programma Errori nei programmi Invocazione di funzioni Pagina 8
Come è fatto un calcolatore? Hardware Processore Memoria Periferiche Funzionamento Esegue istruzioni elementari Esegue istruzioni molto velocemente Deve essere programmato: il software, cioè i programmi, caratterizzano il compito che esso svolge Pagina 9
Componenti di un calcolatore Pagina 10
Schema di un calcolatore Tastiera Mouse Stampante Modem Porte I/O Controller dischi Hard disk CD/ROM DVD CPU Scheda video Monitor Memoria Scheda audio Casse Microfono bus Scheda rete Altro PC Internet Pagina 11
Linguaggi di programmazione Linguaggio macchina 21 40 16 100 163 240 Linguaggio assemblativo (Assembler) iload intrate bipush 100 if icmpgt interror Linguaggi ad alto livello if (intrate > 100)... Pagina 12
Gerarchia di astrazioni 6 programma applicativo 5 linguaggio di programmazione 4 Linguaggio assembly (assemblativo) 3 Nucleo di sistema operativo 2 Linguaggio macchina 1 microprogramma alto livello 0 Logica digitale basso Pagina 13
Linguaggio di Programmazione È dotato di un insieme di istruzioni che indicano al calcolatore cosa fare. Le istruzioni hanno una sintassi e una semantica ben determinata. Sintassi: insieme di regole su come usare le istruzioni e scrivere un programma. Semantica: attribuzione del significato alle istruzioni e alla loro concatenazione. Esempi sono il C (studiato in questo corso), il Pascal, il Java, etc. La traduzione verso il basso avviene tramite un compilatore. Pagina 14
Programma I programmi caratterizzano il compito che il calcolatore svolge. Un programma (indipendentemente dal linguaggio in cui è scritto) è costituito da due aspetti fondamentali: rappresentazione delle informazioni relative al dominio di interesse: DATI manipolazioni della rappresentazione che realizzano le funzionalità richieste: OPERAZIONI Per scrivere un programma si devono affrontare entrambi gli aspetti. Pagina 15
Rappresentazione delle informazioni Le informazioni si rappresentano mediante tipi di dato. Un tipo di dato raccoglie informazioni dello stesso tipo (ad esempio, i numeri interi, i caratteri, le stringhe, ecc.). Nei linguaggi di programmazione ad alto livello esistono tipi di dato predefiniti ed è possibile definire tipi per rappresentare informazioni di interesse specifiche per un applicazione (esempio, autovetture, persone, ecc.). Pagina 16
Classi di Dati Possono essere distinte due classi di dati 1. Semplici o primitivi Es. numeri interi, numeri reali, caratteri, Dipendono dal linguaggio 2. Complessi, definiti a partire dai dati primitivi Es. numeri immaginari, matrici, Possono sia dipendere dal linguaggio sia essere creati dal programmatore Pagina 17
Realizzazione delle operazioni In genere, si realizza un operazione quando deve essere risolto un problema. Problema (Specifica): dato un nominativo, trovare il corrispondente numero telefonico su un elenco telefonico. Per delegare ad un calcolatore la soluzione di un problema è necessario individuare un algoritmo che risolve il problema. Pagina 18
Algoritmo: definizione Algoritmo Procedimento risolutivo attraverso il quale otteniamo la soluzione ad un problema, ovvero un insieme di passi che, eseguiti in ordine, permettono di calcolare i risultati a partire dalle informazioni date in ingresso. Informazioni in ingresso INPUT Sequenza ordinata di passi ALGORITMO Risultati OUTPUT Pagina 19
Algoritmo: proprietà Un algoritmo è caratterizzato da: non ambiguità: le istruzioni devono essere univocamente interpretabili dall esecutore eseguibilità: ogni istruzione deve poter essere eseguita (in tempo finito) con le risorse a disposizione finitezza: l esecuzione dell algoritmo deve terminare in tempo finito per ogni insieme di dati in ingresso Pagina 20
Algoritmo: esempio Problema (Specifica): dato un nominativo, trovare il corrispondente numero telefonico su un elenco telefonico. Algoritmo: scandire sequenzialmente i nominativi presenti nell elenco fino a che non si trovi quello cercato, quindi restituire il numero di telefono associato al nominativo. Esistono altri algoritmi per risolvere lo stesso problema? Pagina 21
Codifica Una volta individuato l algoritmo, questo va codificato nel linguaggio di programmazione prescelto. Pagina 22
Compilazione Un compilatore è un programma traduttore, impiegato per produrre codice oggetto (in linguaggio macchina) a partire da codice sorgente scritto in un dato linguaggio di programmazione di livello più alto. Questo processo si chiama compilazione. Una volta prodotto il codice oggetto (cioè un file eseguibile) risulta estremamente difficoltoso risalire al sorgente. Questa procedura viene chiamata reversing. Pagina 23
Paradigmi di Programmazione (1/2) Esistono differenti paradigmi di programmazione che si distinguono per l enfasi che pongono sui due aspetti fondamentali: dati (oggetti) e operazioni. I paradigmi di programmazione principali sono: 1. IMPERATIVO: enfasi sulle operazioni intese come azioni, comandi, istruzioni che cambiano lo stato dell elaborazione; gli oggetti sono funzionali alla elaborazione 2. FUNZIONALE: enfasi sulle operazioni intese come funzioni che calcolano risultati; gli oggetti sono funzionali alla elaborazione 3. ORIENTATO AGLI OGGETTI: enfasi sugli oggetti che complessivamente rappresentano il dominio di interesse; le operazioni sono funzionali alla rappresentazione Pagina 24
Paradigmi di Programmazione (2/2) In genere, in un programma sono utilizzati più paradigmi di programmazione. Quindi i linguaggi di programmazione forniscono supporto (in misura diversa) per i vari paradigmi. Pagina 25
Il linguaggio C Il C è un linguaggio di programmazione ad alto livello, che supporta i paradigmi imperativo e funzionale. Assembler C Lisp Lisp puro Linguaggio imperativo puro Linguaggio funzionale puro Pagina 26
Mini storia del C Il C nasce dall'idea di avere un linguaggio ad alto livello che permettesse di scrivere in modo efficiente un sistema operativo Ken Thompson nel 1969 si ispirò a due linguaggi esistenti CPL e BCPL e creò il linguaggio "B", ancora troppo poco efficiente per scrivere un sistema operativo Un suo collaboratore, Dennis Ritchie, nel 1972, migliorò il "B tramite vari passaggi, arrivando ad una nuova versione: "C, con il quale fu quasi interamente riscritto il sistema operativo UNIX per il PDP-11, con tempi inaspettatamente brevi Il successo ottenuto spinse Thompson, Ritchie e Kernighan ad utilizzare il C per scrivere il sistema operativo di altre macchine Da quel momento C ed UNIX rimangono legati indissolubilmente Il C subisce un lungo processo di standardizzazione che si concretizza nello standard: ISO/IEC 9899-1990 Pagina 27
C come Cautela Il principale inconveniente del linguaggio C è quello di avere un metodo scadente per l'identificazione degli errori, che può escluderne l'utilizzo ai principianti. Tuttavia, ciò permette di violare le regole del C non appena si sono imparate (non molti linguaggi lo permettono). Nel caso in cui venga fatto correttamente e con attenzione, questo porta a sfruttare le potenzialità della programmazione C. Pagina 28
Perché il C? Molto vicino alla struttura di un calcolatore Può maneggiare attività di basso livello (Esplicita manipolazione di byte ed indirizzi) Ha strutture di alto livello Punto di partenza per linguaggi più "alla moda", quali C++ e Java Produce programmi efficienti Pagina 29
Iniziamo a programmare Cosa occorre: Carta e Penna Un Editor di Testo Un compilatore Ambiente di Sviluppo Integrato IDE Pagina 30
Supportati durante il corso Editor di Testo (per Windows) Notepad++ http://notepad-plus-plus.org/ Compilatore gcc http://gcc.gnu.org/ Istruzioni per l installazione http://www.dis.uniroma1.it/~bloisi/didattica/fondinf1112.html#software Pagina 31
Il primo programma C Esempio di programma in C #include <stdio.h> int main() { printf("il mio primo programma C."); return 0; } Pagina 32
Istruzioni del programma (1/2) Il programma è costituito da una serie di istruzioni o direttive per il compilatore. Le istruzioni hanno il seguente significato: #include <stdio.h> direttiva per includere la definizione di funzioni e variabili predefiniti nel linguaggio relativi all input/output. int main() {... } definizione della funzione main che racchiude il programma principale. Ogni programma C deve contenere una e una sola funzione main(). Pagina 33
Istruzioni del programma (1/2) printf("il mio primo programma C."); istruzione di stampa su video della frase Il mio primo programma C. L'istruzione printf è una funzione C che visualizza a schermo ciò che viene passato ad essa come argomento. return 0; istruzione che termina l esecuzione della funzione main e restituisce il risultato 0. Nota: il C è case-sensitive, cioè distingue tra caratteri minuscoli e caratteri maiuscoli. es. printf è diverso da Printf Pagina 34
Secondo Programma in C Ecco un altro programma in C #include <stdio.h> int main() { printf("il mio secondo programma C\n"); printf("... e ne seguiranno molti.\n"); return 0; } La sequenza di due istruzioni comporta l esecuzione delle due istruzioni nell ordine in cui sono scritte. \n indica di andare a capo (new line). Pagina 35
Scrivere, compilare ed eseguire un programma C 1. preparazione del testo del programma 2. compilazione del programma 3. esecuzione del programma compilato Pagina 36
Scrittura del programma La preparazione del testo di un programma comporta la scrittura di un file contenente il programma. Per un programma C il nome del file deve essere: nome.c dove: nome è il nome del file contenente il testo del programma c è l estensione che indica che il file contiene un programma C. Es. primo.c Nota: La scrittura di un programma può essere effettuata con qualsiasi programma che consenta la scrittura di un testo (editor). Es. Edit, Notepad, Vim, Notepad++, Emacs,... Pagina 37
Compilazione del Programma (1/2) La compilazione del programma serve a tradurre il programma in una sequenza di comandi direttamente eseguibili dal calcolatore. Esistono diversi compilatori C. Uno dei più usati è gcc (GNU Compiler Collection, in origine GNU C Compiler), disponibile per diversi sistemi operativi (http://gcc.gnu.org) Per usarlo occorre eseguire il seguente comando: gcc -o NomeEseguibile NomeFile.c Esempio: per compilare il programma primo.c, si può usare il comando gcc -o primo primo.c Pagina 38
Compilazione del Programma (2/2) La compilazione produce come risultato un file chiamato NomeEseguibile.exe in Windows, oppure NomeEseguibile in Unix/Linux/Mac, che contiene i comandi direttamente eseguibili dal calcolatore. Esempio: >gcc -o primo primo.cpp > Crea un file primo.exe in Windows Nota: se il processo di compilazione è corretto, il compilatore non stampa alcuna informazione, altrimenti stampa dei messaggi di errore. Pagina 39
Esecuzione del programma compilato L esecuzione di un programma si può effettuare solo dopo la compilazione, cioè quando si ha il file NomeEseguibile.exe (oppure NomeEseguibile) L esecuzione del programma avviene scrivendo il nome del file eseguibile al prompt di sistema. Ad esempio, per eseguire il programma primo.c si può usare il comando primo Il risultato dell esecuzione del programma è quindi la visualizzazione di Il mio primo programma C. Pagina 40
Esempio di Compilazione ed Esecuzione tramite prompt Pagina 41
Il ciclo Edita-Compila-Verifica SI begin Scrittura programma SI Errori di esecuzione? Compilazione programma Verifica programma Errori di compilazione? NO NO end Pagina 42
Errori Il seguente programma contiene diversi errori. #include <stdio.h> int main () { printf("i miei primi errori in C...\n") Printf("...e non saranno gli ultm!!!\n"); return 0; } Tipi di errori: sintassi, semantica, logica. Pagina 43
Errori di Sintassi errori dovuti alla violazione delle regole sintattiche del linguaggio. Esempio: printf("i miei primi errori in C...\n") manca il ; Questi errori sono individuati dal compilatore. >gcc -o errori errori.c errori.c: In function 'main': errori.c:18:4: error: expected ';' before 'Printf' > Pagina 44
Errori Semantici errori dovuti alla impossibilità di assegnare un significato ad un istruzione. Esempio: Printf("...e non saranno gli ultm!!!\n"); errori di ortografia nella funzione printf Questi errori a volte sono individuati dal compilatore (errori di semantica statica), altre volte sono individuati a tempo di esecuzione (errori di semantica dinamica). >gcc -o errori errori.c >errori.c: undefined reference to Printf > Pagina 45
Errori Logici errori relativi alle funzionalità realizzate dal programma (differenti da quelle desiderate). Esempio: "...e non saranno gli ultm!!!", la stringa da stampare non è corretta. Questi errori possono essere individuati solo analizzando o eseguendo test di verifica del programma. >gcc -o errori errori.c >errori I miei primi errori in C......e non saranno gli ultm!!! > Pagina 46
Programma Corretto #include <stdio.h> int main () { printf("i miei primi errori in C...\n"); printf("...e non saranno gli ultimi!!!\n"); return 0; } Pagina 47
Struttura di un Programma C Un programma C ha la seguente forma: 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 Pagina 48
Formato del Programma Le parole in un programma C sono separate da spazi. Es. int main Si possono lasciare un numero di spazi (e/o di linee vuote) a piacere. Andare a capo equivale a separare due elementi del programma (come uno spazio). L indentazione non ha alcun effetto sull esecuzione del programma, essa è comunque molto importante perché rende i programmi più leggibili. Pagina 49
Indentazione L indentazione è l inserimento di una certa quantità di spazio vuoto all inizio di una riga di codice. Ogni riga viene indentata di un certo numero di spazi che dipende dalla sua posizione all interno della struttura logica del programma int main () { printf("non indentato"); return 0; } int main () { printf("indentato"); return 0; } L istruzione printf è logicamente inclusa nella funzione main Pagina 50
Commenti E possibile annotare il testo del programma con dei commenti. Il C dispone di due tipi di commento: // denota l inizio di un commento che si estende solo fino alla fine della riga /*... */ delimita un commento che può occupare più righe. Nota: I commenti non hanno alcun effetto sull esecuzione del programma, sono usati per rendere il programma più leggibile. Pagina 51