Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira FONDAMENTI di INFORMATICA Prof. Lorenzo Mezzalira Appunti del corso 4 Introduzione alla programmazione in linguaggio C Indice 1. Sviluppo del software 2. Sistema operativo 3. Linguaggi di basso livello (LLL) 4. Linguaggi di alto livello (HLL) 5. Generazione di un programma eseguibile 6. Gli elementi del linguaggio C 7. La struttura di un programma in C 4 – Introduzione alla programmazione in linguaggio C - 1 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira SVILUPPO DEL SOFTWARE SI parte dalle specifiche (descrizione dei requisiti) per arrivare ai programmi eseguibili (prodotti) Programmazione: • analisi del problema • scomposizione funzionale • definizione degli algoritmi • codifica degli algoritmi e del programma: descrizione in un linguaggio di programmazione I programmi eseguibili in linguaggio macchina (binario) sono estremamente scomodi e macchinosi da scrivere per l’uomo. Per venire incontro alle attitudini umane sono stati introdotti i linguaggi di programmazione ad alto livello. Consentono formulazioni rigorose ma con costrutti e formalismi simili a quelli abituali per l’uomo. Un calcolatore corredato di compilatore e di sistema operativo si presenta al programmatore come una macchina virtuale in grado di eseguire programmi scritti con un linguaggio ad alto livello. Il compilatore provvede a tradurre in codice macchina Il sistema operativo si fa carico di eseguire funzioni complicate, attivate mediante la semplice invocazione di funzioni da parte del programma. 4 – Introduzione alla programmazione in linguaggio C - 2 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira IL SISTEMA OPERATIVO Il Sistema Operativo è un insieme organico di programmi che svolgono funzioni di servizio nel calcolatore. Il sistema operativo fa parte del cosiddetto software di base (o di sistema) in quanto esso non svolge funzioni applicative, ma ne costituisce un supporto. Lo scopo del sistema operativo è quello di: • fornire servizi utili all’operatore umano, • mettere a disposizione dei programmi applicativi un insieme di servizi di sistema (detti anche primitive), facendosi carico delle complesse operazioni necessarie per una corretta gestione delle risorse del sistema di calcolo. FUNZIONI DEL SISTEMA OPERATIVO • Gestione del calcolatore • Gestione delle unità periferiche • Gestione dei file • Gestione dell’esecuzione dei programmi • Gestione dell’interfaccia con l’utente Nei calcolatori collegati in rete tramite un sistema di comunicazione è necessario un ulteriore insieme di programmi di sistema, che costituiscono un’estensione del sistema operativo per operazioni di: • Gestione delle comunicazioni in rete 4 – Introduzione alla programmazione in linguaggio C - 3 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira BOOTSTRAP (avviamento) All’accensione del calcolatore parte l’esecuzione di una piccola parte del Sistema Operativo residente in ROM (porzione non volatile della memoria di lavoro), che esegue le seguenti operazioni: • verifica del funzionamento di parti del calcolatore, in particolare della RAM • caricamento da memoria di massa a memoria di lavoro delle altre parti componenti del Sistema Operativo • salto all’esecuzione della parte (interprete comandi) che gestisce l’interazione con l’utente. A questo punto l’interprete comandi emette su video il prompt (o la videata detta “desktop” con la freccina del mouse) indicando all’utente di essere pronto a ricevere ed eseguire comandi. 4 – Introduzione alla programmazione in linguaggio C - 4 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira Linguaggi di programmazione di basso livello I linguaggi di basso livello sono il linguaggio macchina e la corrispondente forma simbolica, detta linguaggio Assemblatore, specifici per ogni tipo di processore, essendo legati alla sua architettura interna. Con questi linguaggi il programmatore ha una visione dei dettagli architetturali del calcolatore: • Celle della memoria di lavoro • Registri della CPU • Registri delle porte di I/O • Operazioni elementari a due operandi della ALU • Salti ad istruzioni specificandone l’indirizzo Quindi l’uso dei linguaggi di basso livello consente al programmatore il completo controllo di tutte le operazioni su tutte le risorse, ma al prezzo di dover conoscere e tener conto esplicitamente di tutti i relativi dettagli. Parte del software di sistema (sistema operativo, librerie di funzioni) deve essere scritto con linguaggio Assemblatore. 4 – Introduzione alla programmazione in linguaggio C - 5 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira Linguaggi di programmazione di alto livello (HLL) • FORTRAN (FORmula TRANslator) - seconda metà anni 50, versioni successive FORTRAN 70 ... • COBOL (Common Business Oriented Language) - anni 60 • PASCAL e Modula 2 • C e C++ • ADA • Java • linguaggi basati su altri paradigmi di programmazione Linguaggio C sviluppato negli anni 70 (poi diventato C standard ANSI). Molto diffuso e adatto ad un ampio spettro di applicazioni • scientifiche • gestionali • industriali: acquisizione dati, controllo di processo. • informatiche: software di base (SO Unix), strumenti (CAD), pacchetti 4 – Introduzione alla programmazione in linguaggio C - 6 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira I linguaggi artificiali di alto livello (HLL) Sono caratterizzati da: elementi: alfabeto o vocabolario del linguaggio sintassi: insieme di regole tramite le quali si compongono gli elementi per costruire frasi eseguibili (= istruzioni) semantica: significato degli elementi, delle istruzioni, del programma Regole sintattiche: devono essere prive di ambiguità sulla composizione delle frasi. ⇒ si deve poter stabilire con certezza e in modo automatico se una frase è sintatticamente corretta, Correttezza sintattica: il rispetto delle regole sintattiche è condizione necessaria per l’eseguibilità del programma (è necessaria per rendere possibile la traduzione da parte del compilatore). 4 – Introduzione alla programmazione in linguaggio C - 7 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira I linguaggi artificiali di alto livello (HLL) Errori di un programma: sintattici: sono violate regole sintattiche sono errori di struttura, rilevati al tempo di compilazione (compile-time) Impediscono la traduzione in linguaggio macchina eseguibile. di esecuzione: sono indicate operazioni non possibili con l’attuale valore degli operandi sono errori di comportamento, rilevati al tempo di esecuzione (run-time) Arrestano l’esecuzione del programma logici: l’algoritmo non rispetta le specifiche sono errori di comportamento, rilevati in sede di collaudo (debug) Producono risultati che non rappresentano una corretta soluzione del problema dato. 4 – Introduzione alla programmazione in linguaggio C - 8 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira GENERAZIONE DI UN PROGRAMMA ESEGUIBILE - 1 Partendo da Un algoritmo descritto con un linguaggio simbolico, cioè un PROGRAMMA SORGENTE produce un algoritmo (semanticamente) equivalente rappresentato in codice macchina, cioè un PROGRAMMA ESEGUIBILE I linguaggi usati per i programmi sorgenti possono essere di basso livello (Assembler) o di alto livello (come C, Fortran, ecc.). Il programmatore viene spesso indicato come utente del linguaggio di programmazione Da non confondere con l’utente del programma eseguibile, che potrebbe benissimo non saper programmare. Le operazioni necessarie per produrre un programma eseguibile utilizzano nelle varie fasi come strumenti molto utili, e praticamente indispensabili, appositi programmi eseguiti dallo stesso (o da un altro) calcolatore. Il programmatore è quindi utente di questi programmi. 4 – Introduzione alla programmazione in linguaggio C - 9 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira GENERAZIONE DI UN PROGRAMMA ESEGUIBILE - 2 Algoritmo codifica su tastiera File programma sorgente File programma oggetto EDITOR Traduttore Assembler Compilatore LINKER File librerie File programma eseguibile messaggi diagnostici di errori sintattici messaggi diagnostici di errori di collegamento LOADER Programma in esecuzione nella memoria di lavoro Sistema Operativo messaggi di errori di esecuzione 4 – Introduzione alla programmazione in linguaggio C - 10 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira GENERAZIONE DI UN PROGRAMMA ESEGUIBILE - 3 FASE DI EDITING Programma in esecuzione ⇒ EDITOR Ingresso ⇒ Caratteri da tastiera che vengono memorizzati in memoria centrale. L’Editor consente all’operatore di comporre e modificare un testo, composto da qualunque sequenza di caratteri. Uscita (salvataggio) ⇒ File Programma Sorgente memorizzato in memoria di massa. Il file sorgente è un file di testo (caratteri ASCII) di nome: XXXX.ASM programmi in assembler XXXX.C programmi in C XXXX.CPP programmi in C++ FASE DI TRADUZIONE: di assemblaggio (linguaggio assembler) o di compilazione (linguaggi di alto livello) Programma in esecuzione ⇒ COMPILATORE Ingresso ⇒ File Programma Sorgente Il compilatore riconosce i simboli, le parole e i costrutti del programma e, se questi rispettano la sintassi del linguaggio, produce la forma binaria del codice macchina corrispondente. Uscita ⇒ File Programma Oggetto è un file binario di nome XXXX.OBJ Uscite ausiliarie ⇒ Eventuali messaggi diagnostici che segnalano gli eventuali errori sintattici che il compilatore ha rilevato nell’analisi del programma sorgente. Gli errori sintattici, cioè le violazioni delle regole della sintassi del linguaggio, rendono il programma non correttamente associabile ad un significato e quindi ne rendono impossibile la traduzione. 4 – Introduzione alla programmazione in linguaggio C - 11 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira GENERAZIONE DI UN PROGRAMMA ESEGUIBILE - 4 FASE DI LINKING (o collegamento) Programma in esecuzione ⇒ LINKER Ingressi ⇒ File programmi oggetto ⇒ File di Librerie Il linker collega tra loro i file oggetto e le funzioni richieste, estraendole dalle Librerie, sistemando i riferimenti ad indirizzi dei vari elementi collegati. Uscita ⇒ File Programma Eseguibile Il file programma eseguibile è un file binario che contiene il codice macchina del programma eseguibile completo, ed ha nome XXXX.EXE. Il programma sarà effettivamente eseguibile solo dopo che il contenuto del file sia stato caricato nella memoria operativa del calcolatore. Uscite ausiliarie ⇒ Eventuali messaggi diagnostici di errori nel citare i nomi delle funzioni da collegare. FASE DI CARICAMENTO (loading) Programma in esecuzione ⇒ LOADER (caricatore) Ingresso ⇒ File Programma Eseguibile Il Loader è quella parte del Sistema Operativo che si incarica di individuare una porzione libera della memoria operativa, vi copia il contenuto del file programma eseguibile (codice macchina) e ne attiva l’esecuzione della prima istruzione. Uscita ⇒ Eventuale segnalazione di spazio di memoria insufficiente. 4 – Introduzione alla programmazione in linguaggio C - 12 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira ESECUZIONE DEL PROGRAMMA Programma in esecuzione ⇒ Il programma applicativo lanciato dal sistema operativo Ingressi ⇒ I dati richiesti dal programma applicativo Il programma svolge le funzioni corrispondenti all’algoritmo descritto dal codice macchina, che equivale a quello descritto dal programma sorgente. L’uso di funzioni di libreria può di fatto richiamare funzioni del Sistema Operativo, in particolare nell’uso dei file (memoria di massa) e delle unità periferiche (tastiera, video, stampante, ecc.). Uscite ⇒ I risultati previsti in uscita dal programma applicativo, su video o file o stampante. ERRORI in esecuzione (run-time) possono essere: • Calcoli con risultati scorretti ⇒ Ad es. Overflow • Calcoli impossibili ⇒ Divisione per zero, logaritmo di numero negativo, radice quadrata di un negativo, arcoseno di valore > 1 (o < -1), ecc. rilevati e segnalati dalle funzioni di Libreria e dal Sistema Operativo. • Errori di Algoritmo ⇒ L’algoritmo non fa quello che era richiesto, cioè non risolve il problema dato. Non possono essere rilevati da nessuno strumento ed è responsabilità del programmatore individuarli (con opportune prove) e correggerli (modificando i programmi sorgenti). Le prove per la verifica di correttezza e le eventuali correzioni di errori sono dette operazioni di debug, e devono essere eseguite dal programmatore. 4 – Introduzione alla programmazione in linguaggio C - 13 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira Considerazioni sui linguaggi HLL e confronti con i LLL Un linguaggio HLL rispetto al linguaggio LLL consente significative astrazioni da molti dettagli, soprattutto per i seguenti aspetti. • Variabili di vari tipi, in particolare anche aggregati, con verifica di corretto uso dei tipi (type checking) LLL solo byte e word senza verifiche nè limitazioni • Costrutti di controllo strutturati ed espliciti (selezione e iterazione) LLL solo salti condizionati o non (jump = goto) • Espressioni logiche e aritmetiche, combinabili con ricchezza di operatori e uso di parentesi, per esprimere in modo compatto ed usuale calcoli anche complicati, lasciando implicita la sequenza di operazioni e la gestione dei risultati intermedi LLL solo istruzioni con singole operazioni da concatenare in lunghe sequenze e con attento uso dei registri • Funzioni come astrazione di valore, utilizzabili come operandi in espressioni • Procedure come astrazione di operazioni 4 – Introduzione alla programmazione in linguaggio C - 14 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira Considerazioni sui linguaggi HLL e confronti con i LLL (segue) • Per funzioni e procedure HLL si fa carico dei meccanismi di passaggio parametri LLL richiedono esplicita (e consistente) gestione dei parametri tramite registri o stack • Conversioni da sequenze di cifre decimali a codifiche binarie cpl2 e floating point. LLL richiedono l’uso di espliciti algoritmi di conversione (eventualmente in librerie). • Funzioni disponibili in librerie che a loro volta invocano servizi forniti dal sistema operativo (chiamabili anche da LLL) • Allocazione automatica di aree di memoria • Gestione di unità periferiche “classiche” (ingresso di caratteri da tastiera, uscita di caratteri su video e su stampante). La gestione del mouse e del video a finestre richiede apposite librerie più complesse. • Gestione dell’organizzazione a file della memoria di massa. 4 – Introduzione alla programmazione in linguaggio C - 15 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira ELEMENTI LESSICALI DEL LINGUAGGIO C parole chiave (riservate) ⇒ proprie del linguaggio • sono le istruzioni oppure hanno un significato particolare predefinito identificatori ⇒ costituiti da sequenze di lettere ... • rappresentano nomi di variabili, costanti, (tipi nuovi), funzioni, procedure • sono definiti dal programmatore applicativo oppure dal programmatore “di sistema” (di libreria) valori costanti (numerici o caratteri) operatori (unari: un operando, o binari: due operandi) • di assegnamento = • aritmetici +-*/ • relazionali (confronto) > < <= == ... • logici ! (not) && || • di chiamata di funzione/procedura () • di referenziazione & • altri separatori (delimitatori) • di identificatori di variabili e costanti • di istruzioni • commento • di blocco di istruzioni • in espressioni , /* {} () ; */ 4 – Introduzione alla programmazione in linguaggio C - 16 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira Il preprocessore del linguaggio C Il programma sorgente, prima di essere passato in ingresso al compilatore vero e proprio, viene modificato e arricchito da una parte del compilatore detta preprocessore, che interviene nei punti in cui sono indicate con #, e specificate con apposite parole chiave, le direttive al preprocessore. direttive al preprocessore C • #include <nome file> inserisce in quel punto il file (di testo) citato, in modo da renderlo parte integrante del programma sorgente da tradurre • #define <nome simbolico> <costante> sostituisce il valore costante in tutte le occorrenze del nome simbolico 4 – Introduzione alla programmazione in linguaggio C - 17 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira Operandi Sono entità cui è associato un valore Variabili e costanti e funzioni Variabili e dichiarazione di variabili Le variabili sono contenitori di informazioni (cioè di valori) • hanno un nome simbolico che rappresenta in modo univoco una locazione di memoria di lavoro • hanno un tipo che denota il tipo di codifica usato per rappresentare i valori, quali valori possono assumere, quali operazioni sono lecite e come agiscono tali operazioni La dichiarazione di una variabile serve a dire che un identificatore corrisponde ad una variabile e come questa verrà utilizzata dal programma. • definisce l’identificatore simbolico (nome) • definisce il tipo (codifica) adatto ai valori da contenere • alloca la quantità di memoria adeguata a contenere il tipo • associa in modo univoco l’indirizzo di memoria al nome • consente di rilevare errori sull’uso “improprio” della variabile nel programma in compilazione Rappresentazione in memoria della variabile di nome A indirizzo di A A (nome) valore di A L’indirizzo di A è quello del primo (ed eventualmente unico) byte della porzione di memoria che ne contiene il valore. 4 – Introduzione alla programmazione in linguaggio C - 18 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira Uso delle variabili E’ importante distinguere i due diversi ruoli svolti dalle variabili: • per assegnare loro un valore (istruzione di assegnamento). il nome di una variabile a sinistra del simbolo “=“ indica dove memorizzare il valore che è descritto a destra del simbolo “=“. In questo caso il nome è associato all’indirizzo Scrittura di un valore nella variabile • come operandi in espressioni. il nome di una variabile in un’espressione indica che se ne deve usare il valore contenuto in quel momento. In questo caso il nome è associato al contenuto Lettura del valore contenuto nella variabile Visibilità delle variabili (scope) Non tutte le variabili (ed in generale gli identificatori) sono visibili, cioè usabili, in tutte le parti di un programma. Esistono precise regole di visibilità. Vita delle variabili Alcune variabili, all’interno di sottoprogrammi, restano in vigore solo fino a quando è in esecuzione il sottoprogramma stesso. 4 – Introduzione alla programmazione in linguaggio C - 19 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira I TIPI (type) - 1 Il tipo di una variabile rappresenta il modello astratto dei dati associato alla variabile Un tipo identifica • la codifica e la classe dei valori ammissibili, • le operazioni lecite, e • la modalità con cui agiscono le operazioni Tipi predefiniti (built-in) : sono i tipi già disponbili nel linguaggio Tipi definiti dal programmatore (user defined): è possibile definire dei “nuovi tipi” • basati su quelli built-in • tramite dei costruttori di tipo. Un costruttore di tipo è una parola chiave del linguaggio I nuovi tipi saranno caratterizzati da • classe di valori ammissibili • operazioni lecite • operazioni associate al costruttore 4 – Introduzione alla programmazione in linguaggio C - 20 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira I TIPI -2 TIPI SEMPLICI: scalari, elementari, non strutturati. • una variabile di tipo semplice è caratterizzata da un valore “atomico”, l’informazione associata al tipo è indivisibile • un tipo semplice può essere predefinito oppure definito dal programmatore sulla base dei tipi predefiniti TIPI STRUTTURATI (aggregati): sono composti da elementi • una variabile di tipo strutturato è costituita da un insieme di elementi. • per definire un tipo strutturato si usa il costruttore di tipo strutturato: (che definisce il “tipo” della variabile) • un costruttore definisce come sono “composti” gli elementi: in sede di uso sono necessari degli operatori per accedere ai singoli elementi della variabile • ad ogni elemento è associato un tipo (tipo dell’elemento) che può essere semplice o, a sua volta, strutturato • ad ogni elemento è associato un valore (l’informazione associata alla variabile è quindi composta dal gruppo dei valori dei singoli elementi) Compatibilità tra i tipi: determina la legalità delle operazioni (operatori) e delle istruzioni che agiscono sugli identificatori di variabili. • operazioni (espressioni) • istruzioni di assegnamento Il tipo di un’espressione deve essere compatibile con quello della variabile cui viene assegnato il suo risultato. 4 – Introduzione alla programmazione in linguaggio C - 21 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira TIPI SEMPLICI PREDEFINITI DEL C I nomi di questi tipi sono delle parole chiave del linguaggio: • char: (8 bit - 1 byte) Valori da 0 a 255 che rappresentano la codifica ASCII estesa del carattere corrispondente • int (16bit - 2 byte) Rappresentano gli interi relativi. Valori in complemento a 2 da - 32768 a + 32767 • float (32 bit - 4 byte). Rappresentano i razionali espressi in virgola mobile (buona approssimazione dei reali). Valori espressi tramite mantissa e esponente (standard IEEE). Intervallo di valori rappresentabili: circa da -1038 a + 1038) • double (8 byte). Sono float in doppia precisione. Indirizzo di una variabile • operatore: & ….. &nome_var • valori assunti: interi >= 0 (unsigned) &nome_var rappresenta l’indirizzo di memoria del primo byte allocato per la variabile di nome nome_var. 4 – Introduzione alla programmazione in linguaggio C - 22 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira TIPI ENUMERATIVI Sono tipi semplici user-defined che implicano l’enumerazione esplicita dei valori che la variabile potrà assumere. Sintassi C enum {v1, v2, v3, ... vn} nome_var; v1, v2, ...vn sono tutti e soli i valori che la variabile potrà assumere, elencati in ordine crescente di valore. • i valori sono espressi tramite nomi simbolici • l’ordine di enumerazione definisce le relazioni di ordinamento tra i valori (v1 < v2 < v3 ....< vn) • ad ogni valore enumerativo viene automaticamente associato in sede di compilazione un valore di tipo integral enum {lu, ma, me, gi, ve, sa, do} giorno; enum {verde, giallo, rosso} semaforo; 4 – Introduzione alla programmazione in linguaggio C - 23 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira COSTANTI E DICHIARAZIONE DI COSTANTI Costanti esplicite esprimono direttamente dei valori 23 3.1416 ‘A’ costante di tipo int costante di tipo double costante di tipo char Costanti simboliche • sono nomi simbolici che il programmatore adotta convenzionalmente per indicare dei valori prefissati • hanno un tipo espresso implicitamente dal valore La dichiarazione di una costante simbolica • definisce il nome • associa un valore (e tipo implicito) In C la “dichiarazione” (definizione) di costante viene fatta tramite direttiva al preprocessore C #define nmaxp #define vmax #define FALSE #define TRUE 10 150.0 0 1 In fase di compilazione, viene effettuata dal preprocessore una sostituzione letterale del nome simbolico con il valore associato. Note Le costanti non hanno memoria allocata e possono essere usate solo in espressioni. La definizione e l’uso di costanti simboliche, invece che esplicite, migliorano notevolmente la qualità dei programmi, facilitando • Leggibilità • Modificabilità 4 – Introduzione alla programmazione in linguaggio C - 24 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira ESPRESSIONI E OPERATORI Un’espressione contiene identificatori (di variabili, di costanti, di funzioni), costanti esplicite, operatori e parentesi ( ) Semantica Un’espressione descrive il modo con cui ottenere dal valore degli operandi e dall’applicazione degli operatori (operazioni) il valore dell’espressione. Nelle espressioni complesse la sequenza di esecuzione delle operazioni è dettata dalla • Precedenza e associatività predefinita degli operatori • forzatura mediante l’uso delle parentesi tonde L’ordine con cui sono eseguite le operazioni può influire sulla esistenza e sulla precisione dei risultati: ricordare la limitazione del supporto fisico circuitale delle operazioni Esistenza del risultato evitando overflow su interi (e float) Esempio (A, B, C siano int semplice precisione - 16 bit) Se A=20000, B=20000, C=10000 A+B-C dà overflow (A+B > 32767) A-C+B risulta correttamente in 30000 Precisione del risultato per operazioni floating point (e troncamenti per divisione di interi) Esempio (A, B siano float semplice precisione – 32 bit) Se A=20 000 000.0, B=20 000 000.0 A+1-B risulta pari a 0 A-B+1 risulta correttamente pari a 1 4 – Introduzione alla programmazione in linguaggio C - 25 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira Problema Scrivere un programma che cerca e stampa il massimo valore di tipo float (su 32 bit) che non può più essere incrementato di una sola unità. #include <stdio.h> main () { float x, p; char ca; x=0.0; p=1.0; while (p!=x) //finquando succ. è diverso { x=p; p=p+1.0; } printf("max = %f",p);//stampa valore max scanf("%c",&ca);//aspetta prima di terminare } Il risultato stampato dal programma è: max = 16777216.00 Quindi il valore 16 777 217 è il primo (cioè minimo) valore intero non rappresentabile con la codifica float su 32 bit. 4 – Introduzione alla programmazione in linguaggio C - 26 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira Operatori Sono indicatori di operazioni da eseguire sugli operandi TIPI DI OPERATORI • unari • binari si applicano ad un solo operando si applicano a due operandi Operatori aritmetici (+ - * / %) • operandi aritmetici e risultato aritmetico • le operazioni sono eseguite in dipendenza del tipo degli operandi (overloading). Operatori di confronto ( < <= > >= == (eguale) != (diverso)) • operandi entrambi dello stesso tipo qualsiasi • risultato valore logico Valori logici: in C non esiste un tipo “logico” che assuma solo i valori False e True, ma per tale scopo viene usato il tipo int • il valore FALSE (falso) è associato al valore zero • il valore TRUE (vero) è associato ad ogni valore diverso da zero Operatori logici • operandi logici e risultato logico && (AND) || (OR) ! (NOT) operatore unario (con un solo operando) Esempio (num > valmin) && (num <= valmax) Questa espressione logica vale TRUE solo se il valore di num è compreso tra valmin (escluso) e valmax (compreso). Operatori orientati ai bit Operatori di referenziazione (indirizzamento o accesso) 4 – Introduzione alla programmazione in linguaggio C - 27 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira ISTRUZIONI DI ASSEGNAMENTO Indicano l’operazione che assegna un valore ad una variabile Sintassi C: <nome_variabile> = <espressione>; • <nome_variabile> indica il nome della variabile cui si vuole assegnare un valore, in sostituzione di quello precedentemente contenuto in essa •= è il simbolo di assegnamento • <espressione> descrive come ottenere il valore da assegnare alla variabile Significato (semantica): si eseguono prima le operazioni descritte in <espressione> utilizzando i valori degli operandi, il valore ottenuto viene poi inserito nella posizione di memoria indicata dal nome della variabile a sinistra del simbolo di assegnamento. Compatibilità tra i tipi: il compilatore controlla la compatibilità tra tipi. In alcune situazioni, risolve la non compatibilità adottando delle regole di conversione implicita e automatica tra tipi. 4 – Introduzione alla programmazione in linguaggio C - 28 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira STRUTTURA DI UN PROGRAMMA C - 1 programma sorgente C parte dichiarativa globale programma principale funzione main ( ) funzione f1 ( ) funzione f2 ( ) Stile di scrittura di un programma ⇒ leggibilità Ottenuta con: • scelta significativa degli identificatori (mnemonici) • indentazione: “struttura topologica” che rispecchia la struttura logica • uso appropriato dei commenti 4 – Introduzione alla programmazione in linguaggio C - 29 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira STRUTTURA DI UN PROGRAMMA C - 2 Parte dichiarativa globale: contiene • servizi (funzioni) importate da altri moduli (file), cioè definite e codificate in altri file • “oggetti” (tipi di dati, variabili, costanti simboliche, prototipi di funzioni) visibili (utilizzabili) da tutto il programma, cioè da main e dalle altre funzioni. Programma principale: parola riservata (identificatore di funzione) appare una e una sola volta nel programma definisce l’inizio dell’esecuzione è (formalmente) una funzione main ( ) { parte dichiarativa locale parte esecutiva definisce l’insieme di “oggetti” usati dal programma principale per l’esecuzione. sono oggetti visibili (locali) a main. insieme di istruzioni che costituiscono il programma principale } 4 – Introduzione alla programmazione in linguaggio C - 30 Fondamenti di Informatica – Corso di Laurea Prof. L. Mezzalira STRUTTURA DI UN PROGRAMMA C - 3 Parte dichiarativa locale 1.dichiarazione di costanti 2.definizione di “nuovi” tipi definiti dall’utente (o eventuale ridenominazione di tipi già definiti) 3.dichiarazione di variabili 4.prototipi di funzioni Regole sintattiche sulle dichiarazioni sia locali che globali: • ogni identificatore usato deve essere prima definito • ogni variabile usata deve essere prima dichiarata Parte esecutiva: istruzioni (qui elencate per tipologia) • istruzioni di assegnamento ed espressioni • istruzioni composte (sono racchiuse tra { } ) • costrutti di (modifica del flusso di) controllo (costrutti di selezione, costrutti ciclici) • chiamate di sottoprogrammi (procedure) • “istruzioni” di ingresso e uscita (funzioni e procedure di sistema) 4 – Introduzione alla programmazione in linguaggio C - 31