Sei sulla pagina 1di 45

ELEMENTI DI INFORMATICA

Introduzione. Linformatica pu essere definita come la scienza della rappresentazione e dellelaborazione dellinformazione o come la disciplina che studia in modo sistematico gli algoritmi che descrivono e trasformano linformazione: la loro teoria, analisi progetto, efficienza, realizzazione e applicazione. Il principale oggetto di studio dellinformatica sono quindi gli algoritmi mentre i calcolatori sono i principali strumenti dellinformatica. Storia. Labaco uno dei primi strumenti manuali di calcolo realizzati dalluomo, per trovare le prime macchine calcolatrici meccaniche bisogna aspettare il XVII secolo quando fu inventata la Pascalina (dal nome del suo inventore: Blaise Pascal) capace di addizionare e sottrarre numeri interi, che, successivamente, venne superata da unaltra macchina, creata da G. W. Leibniz, capace di eseguire le 4 operazioni fondamentali. Un passo fondamentale verso i moderni calcolatori fu possibile grazie ai risultati teorici nel campo della logica matematica ottenuti a partire dal 1920. Il risultato teorico pi importante quello di Alan Turing: possibile realizzare una macchina universale in grado di eseguire qualsiasi procedimento di calcolo ben definito, cio un algoritmo. Dagli anni 30 la tecnologia elettromeccanica ed elettronica consente la realizzazione di macchine in grado di eseguire elaborazioni sempre pi complesse. Anche queste macchine elettromeccaniche per erano in grado di eseguire un solo tipo di calcolo (esempio: risoluzione di sistemi di equazioni lineari e tabelle di tiro per lartiglieria). Per i moderni calcolatori elettronici bisogna aspettare gli anni 40 dove viene concretizzata lidea di macchina universale. Un contributo fondamentale lo diede John von Neumann: con l'espressione architettura di von Neumann (o macchina di von Neumann) ci si riferisce a uno schema di progettazione di calcolatori elettronici. Questo costituito da: ununit di lavoro (CPU), che si divide a sua volta in unit di controllo e operativa; unit di memoria; unit di input; unit di output.

Dagli anni 40 ad oggi levoluzione della tecnologia elettronica rapida: si incrementa la velocit dellelaborazione e la capacit di memorizzazione mentre si riducono sempre pi il costo e le dimensioni dei calcolatori. 1

Tuttavia, questi ultimi, non hanno cambiato i concetti fondamentali su cui si basa il loro funzionamento, infatti, ancora oggi, lorganizzazione logica della maggior parte dei calcolatori ancora basata sullarchitettura di von Neumann. Nascita dellinformatica. Lintroduzione del concetto di calcolatore universale defin la nascita dellinformatica che venne considerata come disciplina scientifica nel 1953 (1969 in Italia) e gli algoritmi sono loggetto principale di questa nuova disciplina. Con la formazione del concetto di algoritmo e la possibilit concreta di realizzare macchine universali esecutrici di algoritmi linteresse si sposta verso i problemi legati alla formulazione di algoritmi. Le discipline che hanno contribuito principalmente alla nascita dellinformatica e che contribuiscono ancora al suo sviluppo sono la matematica e la logica. Architettura dei calcolatori. Il calcolatore una macchina esecutrice di algoritmi e pu essere considerato come un sistema composto da un numero elevato di componenti. Il suo funzionamento pu essere descritto come un sistema strutturato in modo gerarchico, cio come un insieme di componenti che interagiscono luno con laltro ed ognuno di questi componenti costituito da componenti pi semplici che, a loro volta, possono essere ancora scomposti in componenti pi semplici e cos via sino al raggiungere il livello di dettaglio necessario. Ogni livello consiste in un insieme di componenti caratterizzati dalla loro struttura, ossia dalla loro organizzazione e modo in cui interagiscono, mentre ogni componente contraddistinto da una funzione, cio dalloperazione che svolge nel contesto della struttura. Struttura e funzioni di base dei calcolatori. Le funzioni di base svolte da un calcolatore sono 4: elaborazione di dati, memorizzazione di dati, trasferimento di dati e controllo. I calcolatori sono impiegati per elaborare dati provenienti dallambiente esterno e per fornire allambiente stesso i risultati ottenuti. Le caratteristiche dellelaborazione variano notevolmente in base al tipo di applicazione richiesta e al tipo dei dati da trattare, ad esempio numeri, testi segnali audio, immagini, ecc. La seconda funzione la memorizzazione dei dati che deve essere sia per brevi periodi, come necessario nel corso di unelaborazione per memorizzare i risultati intermedi ottenuti, che per lunghi periodi, al fine di immagazzinare dati che possono essere successivamente estratti o modificati. Il trasferimento dei dati la terza funzione fondamentale. Un calcolatore deve comunicare con lambiente esterno sia per acquisire dati sia per trasferire i risultati memorizzati. Questi compiti vengono svolti normalmente da dei dispositivi detti periferiche con funzione di sorgenti o destinatari dei dati. Lultima funzione serve a controllare le tre funzioni precedenti. Questa deputata allutente del calcolatore che la realizza dando dei comandi allo stesso calcolatore; in ogni caso allinterno di ogni calcolatore presente ununit di controllo che coordina le risorse del calcolatore. Architettura di von Neumann. Larchitettura d von Neumann considerata larchitettura di riferimento in quanto i suoi concetti fondamentali sono rimasti validi al cambiare della tecnologia e, gli attuali calcolatori, sono ancora basati su questa architettura.

Il componente principale lunita di elaborazione centrale (CPU) a cui sono affidate sia le operazioni di controllo e coordinamento che quelle di elaborazione. Ormai le CPU vengono realizzate con tecnologie microelettriche e sono chiamate microprocessori. Un altro componente lunit di memoria che ospita sia i dati necessari per le elaborazioni svolte dalla CPU che i dati trasferiti attraverso le unit di ingresso/uscita (I/O). La memoria organizzata in celle adiacenti ognuna caratterizzata da un proprio identificatore univoco chiamato indirizzo in cui possono essere letti o scritti dati in formato binario. Viene usata la codifica binaria in quanto vi una maggiore semplicit nel progetto e nella realizzazione dei circuiti elettronici, si riducono i costi e si ha una maggiore resistenza a disturbi e guasti. La memoria pu contenere indifferentemente un dato o unistruzione ed accessibile indipendentemente dal contenuto. La struttura standard per il collegamento di queste unit quella basata sui concetti di bus master-slave. Il bus una linea a cui sono contemporaneamente connesse le unit del calcolatore e che consente il trasferimento di dati tra tali unit. Alla CPU viene attribuita la gestione dellintero sistema (ruolo detto master) soprattutto laccesso al bus, mentre viene impedito alle unit periferiche (slave) la possibilit di accederci autonomamente. Il trasferimento dati attraverso il bus avviene sotto la supervisione della CPU che identifica, mediante lindirizzo, la sorgente e la destinazione dei dati e sincronizza i dispositivi che devono colloquiare. In questo modo il bus viene utilizzato evitando qualsiasi collisione fra dati di competenza delle diverse periferiche. Il calcolatore universale. Per realizzare una macchina per lesecuzione di un procedimento di calcolo ci sono due approcci: programma cablato (hard wired) o programma software. Per eseguire un programma possiamo costruire i componenti logici in modo che il risultato sia quello voluto. Questo un modo di costruire il programma cablato, cio in forma hardware che non pu essere modificato. un sistema non flessibile, che pu fare solo quelle operazioni. Abbiamo quindi una configurazione fissa di componenti fisici che realizzano lo specifico procedimento. Per effettuare procedimenti diversi necessario modificare la configurazione fisica della macchina. I calcolatori universali sono basati sul programma software, costituito da componenti in grado di svolgere operazioni elementari. La sequenza di operazioni per un dato procedimento specificata da unopportuna sequenza di segnali di controllo e, al contrario del programma cablato, calcoli diversi non richiedono la modifica della configurazione fisica della macchina ma solo una diversa sequenza di segnali di controllo. Le porte logiche sono degli elementi fondamentali nei circuiti. Esse si possono trovare all'interno di circuiti integrati complessi, come parte integrante dello schema, oppure sempre racchiuse in un circuito integrato, pronte ad essere usate per vari scopi. Le porte logiche sono dei semplici circuiti elettronici che possono venire considerate dei blocchi attraverso i quali poter svolgere delle operazioni logiche. Tali operazioni devono sottostare alla cosiddetta algebra binaria, questa si basa sui vari vero o falso che, in elettronica, corrispondono a passaggio o non passaggio di corrente elettrica e quindi ai cosiddetti livelli logici 0 e 1. Una rete composta da una moltitudine di porte logiche pu eseguire complicate operazioni di controllo o di elaborazione dati. Nella realizzazione fisica dellarchitettura dei calcolatori la tecnologia assume un ruolo fondamentale. Altri fattori importanti che la influenzano sono il compromesso tra costi e prestazioni e il tipo e lo scopo dei calcolatori. Evoluzione della tecnologia dei calcolatori. Possiamo dire che a seguito dellevoluzione tecnologica i calcolatori si possono dividere in cinque diverse generazioni. Nella generazione zero (1942-1945) ci sono calcolatori meccanici capaci di eseguire un solo algoritmo; sono lenti, con alti consumi energetici, bassa affidabilit e scarsa capacit di memoria. Caratterizzati dalla mancanza di linguaggi di alto livello (codice binario) e dallassenza di 3

qualsiasi tipo di supporto alla programmazione ed alla strutturazione di programmi (sistemi operativi, librerie, ecc). Con larrivo della prima generazione (1945-1955) arriva anche la tecnologia elettrica, viene creato il primo calcolatore elettrico i cui componenti sono valvole termoioniche. La seconda generazione (1955-1965) segna larrivo dei transistor pi affidabili e meno costosi delle valvole termoioniche. Si ha lintroduzione di variabili e cicli e ci sono i primi supporti alla programmazione (librerie, compilatori, monitor, ecc). La terza generazione (1965-1980) segna lutilizzo dei circuiti integrati realizzati con tecnologia a semiconduttore. Si ha: lintroduzione del concetto di parallelismo, che aumenta la velocit mentre si riducono di costi e dimensioni; lintroduzione della microprogrammazione semplifica il progetto dellunit di controllo; lintroduzione dei primi sistemi operativi. Il calcolo parallelo l'esecuzione simultanea del codice su pi microprocessori, cio una caratteristica architetturale mirata a far svolgere pi funzioni contemporaneamente allo scopo di aumentare le prestazioni del sistema. Nellultima generazione, la quarta (1980-oggi), si ha la realizzazione della VLSI e ULSI (very/ultra large scale integration). Ci sono i primi microprocessori: aumentano le funzionalit di elaborazione e controllo e la capacit di memorizzare, si potenzia il parallelismo e vengono introdotti linguaggi orientati ad esso. Le conseguenze dellevoluzione tecnologica sono la diminuzione di costo e di dimensione dei calcolatori diventando cos pi accessibili ed estendendo i loro ambiti di applicazioni. Aumenta la velocit di elaborazione, la capacit di memoria e laffidabilit delle connessioni elettriche mentre diminuiscono i consumi energetici e la necessit di raffreddamento. Nel 1965 Moore suppose che le prestazioni dei microprocessori sarebbero raddoppiate ogni 12 mesi. Nel 1975 questa previsione si rivel corretta e prima della fine del decennio i tempi si allungarono a 2 anni, periodo che rimarr valido per tutti gli anni ottanta. La legge viene riformulata alla fine degli anni ottanta ed elaborata nella sua forma definitiva, ovvero che le prestazioni dei processori raddoppiano ogni 18 mesi ed rimasta valida fino ai giorni nostri. Lunit di elaborazione. Lunit di elaborazione si divide in: unit aritmetico-logica, la cui funzione effettuare operazioni di tipo aritmetico e su dati codificati in binario, ogni ALU quindi pu eseguire un certo insieme di operazioni selezionabili tramite un comando ricevuto dallesterno; unit di controllo, coordina le varie unit nellesecuzione dei programmi comandando opportunamente i segnali di controlli dei registri, dellALU e dei bus che interfacciano la memoria; registri, celle di memoria interne alla CPU utilizzate per immagazzinare le informazioni necessarie per lesecuzione delle istruzioni. I registri nei vari CPU variano sia come numero sia come denominazione. Quelli per sempre presenti sono: registri di dati (DR): memorizza i dati trasferiti tra CPU e memoria principale; registri di indirizzo (AR): contengono gli indirizzi della cella di memoria coinvolta dalla CPU in unoperazione di lettura o scrittura; program counter (PC): indica quale sia la prossima istruzione da eseguire; registro di istruzione (IR): contiene l'istruzione da eseguire; registro di stato (SR): contiene informazioni sulle operazioni svolte dalla ALU. Il linguaggio per cui la CPU si comporta da esecutore detto linguaggio macchina (LM). Questo il linguaggio in cui sono scritti i programmi eseguibili per computer quindi linsieme delle operazioni elementari realizzabili da un calcolatore. Il LM basato su un alfabeto detto binario perch comprende due soli simboli: 0 e 1. 4

Il trasferimento di dati tra i componenti di un calcolatore detto funzione elementare. Questo trasferimento avviene grazie ad una struttura elementare composta da un insieme di linee elettriche in grado di trasportare i segnali che codificano i valori logici 1 e 0. Le linee possono essere di 3 tipi: bus dati: utilizzato generalmente per trasferire i dati fra memoria e CPU ma anche fra CPU e interfacce di ingresso/uscita; bus indirizzi: identifica la posizione delle celle di memoria in cui la CPU va a scrivere o leggere; bus di controllo: transitano i segnali di controllo che consentono di volta in volta di selezionare le unit coinvolte in un trasferimento di dati, di definire la direzione dello scambio (lettura o scrittura) e in generale di coordinare il sistema. Le diverse parti della CPU interagiscono fra loro al fine di eseguire le istruzioni di un programma scritte in LM. Le istruzioni sono 4: elaborazione (operazioni logico-matematiche), memorizzazione (lettura/scrittura nella memoria principale), trasferimento I/O (lettura/scrittura verso i dispositivi periferici), controllo (istruzioni di salto che consentono di modificare lordine di esecuzione delle istruzioni). Ogni istruzione codificata come sequenza di bit in una singola parola di memoria. Il ciclo di esecuzione di un programma prevede diverse fasi. 1. Quando alla CPU viene inviato il segnale di inizio, lunit di controllo fornisce alla memoria lindirizzo della cella contenente la prima istruzione da eseguire, la memoria seleziona la cella contenente listruzione e ne invia il contenuto alla CPU che legge listruzione da eseguire e la memorizza. Questa fase detta di fetch o di prelievo ed in poche parole trasferisce listruzione dalla memoria alla CPU. 2. Lunit di controllo incrementa il contenuto del registro PC affinch esso identifichi la successiva istruzione da eseguire. 3. Questa fase detta di decodifica, lunit di controllo esamina listruzione presente nel registro IR e determina le operazioni da svolgere. 4. Le unit interessate allesecuzione dellistruzione vengono opportunamente comandate e i risultati sono trasferiti nei registri o in memoria. In questa fase quindi, chiamata di esecuzione, listruzione viene eseguita dalla CPU. 5. Terminata lesecuzione lelaborazione riprende ciclicamente con la fase di fetch dellistruzione successiva. Nella scelta dellinsieme delle istruzioni sono contrapposte due diverse filosofie di progettazione identificate come CISC e RISC. La progettazione delle CPU CISC basata sullidea di realizzare a livello di hardware funzioni sempre pi complesse, in modo che il calcolatore sia in grado di eseguirle direttamente. Questo si riflette nella scelta di istruzioni macchina complesse, che possono richiedere un elevato numero di cicli di clock per essere eseguite ma riducono il numero di istruzioni richieste per il completamento dellesecuzione di un programma. La CPU RISC esce negli anni 80 ed basato sullidea di rendere molto semplici le istruzioni riconosciute dalla CPU. Si possono cos realizzare CPU capaci di eseguire le istruzioni a velocit molto elevate, riducendo il loro periodo di clock. Nelle CPU RISC si ha quindi riduzione del numero medio di cicli di clock ed unelevata frequenza di clock. Attualmente si stanno utilizzando architetture miste C-RISC con lobbiettivo di bilanciare la complessit dellinsieme delle istruzioni con la velocit di esecuzione, garantendo la completa compatibilit con le versioni precedenti dal punto di vista dellinsieme delle istruzioni eseguibili. Prestazioni di una CPU. Informalmente possiamo dire che per un utente medio un calcolatore pi veloce di un altro quando esegue lo stesso compito in meno tempo. Se prendiamo invece il direttore di un centro di calcolo (esempio) per lui sar pi veloce quello che completa il maggior numero di lavori in un intervallo di tempo definito. Quindi il primo interessato alla riduzione del tempo di risposta 5

mentre il secondo allammontare del lavoro svolto in un dato tempo. Le prestazioni di un calcolatore quindi si valutano in riferimento a durate temporali. Le espressioni pi comuni per calcolare il tempo di CPU (tcpu) sono: tcpu = nc * Tc = nc * fc = CPI * ni * Tc = CPI * ni / fc Dove nc sono numero di cicli di clock necessari per realizzare ni istruzioni e dipende dallarchitettura e dallinsieme delle istruzioni della CPU; Tc il periodo di clock; fc la frequenza di clock (fc = 1 / Tc) e dipende dalla tecnologia adottata e dallarchitettura della CPU; CPI (= nc / ni) il numero medio di cicli di clock per istruzione e anche questa dipende dallarchitettura e dallinsieme delle istruzioni della CPU. I parametri comunemente usati per caratterizzare una CPU sono la frequenza di clock e lampiezza dei registri (bit). Lorologio di sistema (clock) sincronizza le operazioni della CPU ed emette impulsi periodici con frequenza costante (frequenza di clock) attualmente circa 10 GHz. La frequenza di clock legata al massimo tempo di propagazione dei segnali elettrici attraverso i circuiti logici della CPU. Sebbene il tempo di esecuzione sia il parametro che meglio descrive il livello di prestazioni di un calcolatore, non sempre facile riuscire ad utilizzarlo. Pu capitare, infatti, che una CPU sia particolarmente veloce nelleseguire un certo tipo di compiti ma non sia altrettanto veloce quando ne deve eseguire altri diversi. A causa di questi problemi sono stati proposti altri indici per valutare le prestazioni del sistema, anche se, dobbiamo comunque dire, che il miglior parametro rimane il tempo di esecuzione dei programmi. Uno di questi indici il MIPS che si ottiene misurando il numero di istruzioni in LM che la CPU pu eseguire in un secondo. Si calcola dallespressione MIPS = Ni * tcpu * 10-6 = fck / CPI * 10-6. Il valore espresso rappresenta la frequenza di esecuzione delle istruzioni, pi elevato pi veloce in calcolatore. I MIPS sono per poco affidabili, infatti, dipendono dallinsieme delle istruzioni macchina, istruzioni pi semplici corrispondono a valori pi elevati e poi i MIPS misurati per uno stesso calcolatore variano a seconda del programma considerato, cio il numero di istruzioni eseguite in un secondo dipende da quali istruzioni vengono eseguite. Alto indice il MFLOPS che si basa sul numero di operazioni (non istruzioni) in virgola mobile eseguite in un secondo. Si calcola con la formula MFLOPS = nflop / tcpu * 10-6. Dove nflop indica il numero di operazioni in virgola mobile svolte dal processo. Questo indice utile per programmi che eseguono molte operazioni tra numeri reali e, poich si considerano le operazioni in virgola mobile e non le istruzioni, questo indice fornisce risultati pi precisi del MIPS. Parallelismo. Con la programmazione parallela possibile suddividere un programma in pi processi che lavorano su processori differenti (multiprocessori) e che scambiano dati in cooperazione. In questo modo il tempo di esecuzione di una singola istruzione rimane pressoch invariato ma aumenta il numero di istruzioni eseguite nellunit di tempo. Quindi possiamo ridurre il tempo di CPU senza modificare gli altri parametri presenti nella formula ma agendo sullarchitettura della CPU introducendo il parallelismo. Ci sono due approcci: il pipelining e le architetture superscalari. Nel pipelining il processore risulta diviso in 5 stadi specializzati (esempio: prelievo istruzione o fetching, decodifica, esecuzione dellistruzione, attivazione della memoria, scrittura) che eseguono in tempi diversi le parti di unistruzione, ma contemporaneamente parti diverse di istruzioni diverse. Le singole pipeline hanno per un problema legato alla presenza di istruzioni che possono richiedere l'elaborazione di dati non ancora disponibili, cio la dipendenza di un'istruzione a valle da qualche istruzione non ancora eseguita a monte, e il problema legato alla presenza di salti condizionati. Per realizzare CPU con prestazioni migliori col tempo si affermata la strategia di integrare in un unico microprocessore pi pipeline che funzionano in parallelo. Questi microprocessori sono definiti superscalari dato che sono in grado di eseguire pi di un'operazione per ciclo di clock.

Il sistema di memoria. I criteri fondamentali di una memoria sono: il tempo di accesso, con cui si valuta la rapidit della memoria nella realizzazione di operazioni di lettura/scrittura, idealmente non dovrebbe essere superiore al tempo di esecuzione di unistanza da parte della CPU; la capacit, cio il numero di bit che possono essere memorizzati, idealmente la pi alta possibile; il costo per bit, calcolato come il rapporto tra il costo complessivo dellunit di memoria e la sua capacit la volatilit, le memorie volatili mantengono linformazione solo finch vengono alimentate attraverso corrente elettrica. Si tratta di caratteristiche non facilmente conciliabili che impongono un compromesso, per esempio ad un tempo daccesso inferiore corrisponde un maggiore costo di bit. Questo compromesso si basa sulla presenza nel calcolatore di memorie piccole e veloci affiancate ad altre grandi e lente. Allora possiamo classificare cos le memorie: memoria centrale, esterna alla CPU ma interna al calcolatore, contiene programmi in esecuzione e relativi dati, quindi mantiene informazioni non permanenti; memoria di massa, esterna al calcolatore, contiene grandi moli di dati usati non frequentemente, quindi mantiene informazioni in modo permanente; registri, interni alla CPU, ad accesso veloce ma in grado di mantenere solo poca informazione e in modo solo temporaneo. La realizzazione delle unit di memoria si basa su tecnologie differenti e alle memorie elettroniche e magnetiche si sono affiancate anche memorie basate su tecnologia ottica. Le memorie elettroniche sono caratterizzate da unelevata velocit, buona capacit, elevato costo di bit e, nella maggior parte dei casi, volatilit, quindi per evitare di perdere le informazioni devono essere costantemente alimentate. Le memorie centrali e i registri sono elettroniche. Le memorie magnetiche invece sono caratterizzate da bassi costi di bit e dalla non volatilit ma a causa della loro lentezza non possono essere utilizzate come supporto diretto al processore. Le memorie di massa sono magnetiche. Le memorie ottiche hanno caratteristiche simili alle magnetiche ma sono caratterizzate da supporti non riscrivibili. Di conseguenza sono adatte alla distribuzione di grandi quantit dati ma non alla memorizzazione di dati da elaborare direttamente dalla CPU. Di recente sono arrivate sul mercato memorie magneto-ottiche, che consentono di modificare le informazioni memorizzate, ma che richiedono tempi lunghi di scrittura. La memoria centrale pu essere intesa come costituita da una successione ordinata di elementi binari raggruppati in celle costituita da 8, 16, 32 oppure 64 elementi binari. Ogni cella ha un indirizzo che rappresenta la sua posizione rispetto alla prima cella che ha indirizzo 0. Alla memoria centrale si accede tramite due registri e un insieme di segnali del bus di controllo che specificano il tipo di operazione richiesta: lettura o scrittura. Si definisce lettura loperazione che rende disponibile alluscita della memoria sul bus dati la parola presente nella cella desiderata senza modificarla. Si definisce scrittura di una parola loperazione con cui il contenuto della parola viene modificato. Negli anni la velocit delle CPU cresciuta a ritmo maggiore rispetto alla velocit di trasferimento dati tra la memoria centrale e la CPU. Per compensare questo gap sono state create le memorie cache. Queste sono memorie ad accesso casuale e ad alta velocit in cui il sistema conserva le istruzioni e i dati usati pi frequentemente per ridurre i tempi di accesso, cio sono un insieme di dati che vengono memorizzati in una posizione temporanea dalla quale possono essere recuperati velocemente su richiesta. Il tempo di accesso medio al sistema cache + memoria principale : tM = h * tc + (1 h) * (tc + tp) = tc + (1 h) * tp 7

Dove tc il tempo di accesso alla memoria cache ( 1-5 ns), tp il tempo di accesso alla memoria principale ( 10-50 ns) e h la probabilit che il dato richiesto si trovi nella cache. Attualmente si usano due livelli di cache: il primo pi piccolo e pi veloce e si trova nello stesso cip della CPU; il secondo ha capacit maggiore, pi lento ed esterno alla CPU. La memoria di massa ha come caratteristiche la non volatilit e la grande capacit, questo perch deve contenere tutti i programmi che possono servire allutente oltre ai dati che questi programmi utilizzano, mantenendo tali informazioni per un periodo indefinito di tempo anche in assenza di alimentazione. realizzata con componenti meccanici ed il tempo di accesso molto maggiore rispetto alla memoria centrale. Viene realizzata con tecnologia magnetica I dischi magnetici sono costituiti da un supporto ricoperto da un sottile strato di materiale magnetico le cui condizioni di magnetizzazione consentono di memorizzare i dati. Le operazioni di scrittura e lettura vengono effettuate tramite una testina che viene posizionata in prossimit della faccia magnetizzata. Questi dischi sono di forma circolare e il materiale magnetico viene steso su entrambe le facce. Le informazioni sono memorizzate sul disco in cerchi concentrici, chiamati tracce, tutti della stessa larghezza, che corrisponde alle dimensioni della testina, e tutti contenenti lo stesso numero di bit. Le tracce sono suddivise in settori e ogni settore ospita un blocco di dati che rappresenta in genere lunit minima di trasferimento tra disco e memoria centrale. Durante il suo funzionamento il disco ruota a velocit costante. Il tempo di accesso alla memoria (ta) si calcola facendo: ta = ts t dove ts in tempo di posizionamento (seek) della testina sulla traccia richiesta e t il tempo di latenza necessario affinch il settore richiesto si posizioni sotto la testina. La velocit di trasferimento e di circa 101-102 MB/s. Ormai sono ampiamente diffusi anche i dischi ottici. I primi ad essere stati sviluppati non erano riscrivibili (CD-ROM). Si tratta si memorie destinate alla sola lettura che avviene grazie ad un raggio laser che esplora la superficie ed identifica il valore dei bit in base alla riflessione o meno del fascio luminoso. Per privilegiare la capacit rispetto alla velocit nei CD-ROM i dati sono organizzati secondo un unico percorso a spirale che dal centro del disco va alla periferia. Oggi esistono anche dei CD-ROM riscrivibili chiamati CD-RW. In passato sono state usate tecnologie assai diversificate per la realizzazione delle memorie, ora le soluzioni pi impiegate fanno uso di semiconduttori di silicio. La RAM e una tipologia di memoria (centrale) elettronica ad accesso diretto a lettura-scrittura e di tipo volatile dove vengono memorizzati e letti i dati ed i programmi. Esiste anche una memoria sempre a semiconduttori non volatile che viene scritta al momento della sua produzione e che non pu essere cancellata. Questa memoria chiamata ROM e viene utilizzata per contenere informazioni di inizializzazione del calcolatore che vengono usate ad ogni accensione o altre funzioni che devono essere permanentemente utilizzabili. Tipi di calcolatore. I calcolatori possono essere distinti in base alle loro prestazioni e caratteristiche tecniche. Le classi principali sono 5: PC, workstation, minicalcolatore, mainframe e supercalcolatore. I personal computer sono calcolatori dedicati alluso personale. Lidea originaria era quella di rendere disponibile ad un vasto numero di utenti un dispositivo semplice e versatile ad un costo basso. Per rivolgersi ad un mercato il pi ampio possibile i PC sono progettati sulla base di unarchitettura modulare che prevede una versione base, con prestazioni sufficienti da soddisfare lutente medio, e moduli aggiuntivi che ne migliorano le prestazioni. La rapida e continua evoluzione di questo calcolatore lascia intravedere PC sempre pi potenti, leggeri portatili. Le workstation sono dispositivi dedicati allutilizzo professionale, in genere utilizzati per applicazioni scientifiche o ingegneristiche e caratterizzate da una o pi CPU e da un terminale grafico ad elevata risoluzione. Anche se le workstation sono per lo pi utilizzate da un solo utente, hanno un sistema operativo che prevede la possibilit di soddisfare pi utenti contemporaneamente, consentendo da ogni utente di attivare pi processi.

La differenza tra minicalcolatori e workstation il numero maggiore di utenti che le prime possono soddisfare. Sono generalmente impiegati in situazioni in cui e necessario condividere programmi e dati comuni (ad esempio la filiale di una banca) e quindi sono impiegati con vari terminal connessi. I mainframe sono calcolatori con elevate prestazioni che si differenziano dai minicalcolatori per la loro possibilit di gestire un numero elevato di periferiche, compresi dischi per il mantenimento di archivi di grandi dimensioni (si arriva ai TeraByte). Sono impiegati principalmente nellelaborazione di transizione o comunque per elaborazioni batch (modifica di pi dati contemporaneamente), che non richiedono uninterazione frequente con lutente ma coinvolgono enormi basi di dati, come ad esempio gli aggiornamenti di archivi bancari. I supercalcolatori sono stati creati per massimizzare il numero di operazione nellunit di tempo. Sono caratterizzati da una particolare struttura interna progettata per lelaborazione delle operazioni aritmetiche di base e complesse e per lelaborazione parallela di pi operazioni. Con larrivo dei multiprocessori i supercalcolatori sono quasi spariti dal mercato a causa dellelevato rapporto costo/prestazioni, infatti, i primi, hanno prestazioni spesso superiori a costi inferiori. Il sistema operativo (SO). Un SO un insieme di programmi impiegato per controllare altri programmi eseguiti dallo stesso processore e ha la funzione di porsi come interfaccia tra utenti e risorse fisico/logiche di calcolo. Il SO svolge diverse funzioni: esecuzione delle applicazioni (caricamento del programma nella memoria centrale, ecc), accesso ai dispositivi di I/O, archiviazione di dati e programmi, controllo di accesso in sistemi che prevedono la condivisione di risorse da parte di pi utenti o applicazioni, contabilizzazione, gestione dei malfunzionamenti. Evoluzione dei sistemi operativi. Lesigenza dei SO nasce principalmente a causa della difficolt di gestire dei calcolatori per colpa della loro complessit e per poter condividere un calcolatore tra pi utenti. Negli anni 40 arrivano i primi calcolatori elettrici. Questi non erano dotati di SO ed erano difficili da usare, infatti, richiedevano una conoscenza completa di tutti i componenti hardware e non vi era nessuna interazione con lutente, inoltre il loro costo era molto elevato e lefficienza bassa (un singolo utente alla volta). Negli anni 50 vengono inventati i transistor e apparvero i primi programmi di sistema (gli antenati degli attuali SO) per la gestione automatica dei job. Venne adottata una soluzione del sistema a batch (a lotti) dei programmi utente (job). Nei SO degli anni 60 venne implementata la multiprogrammazione che rendeva possibile la presenza di pi programmi in memoria contemporaneamente. Questo rendeva necessaria la presenza di hardware specializzati per proteggere i programmi dalle reciproche interferenze. Nasce il concetto di timesharing: ogni utente ha un dispositivo di ingresso (la tastiera) e uno di uscita (il monitor) che gli permettono di inviare comandi al SO ottenendo subito una risposta. Viene creato il SO unix che permetteva a pi utenti di interagire contemporaneamente con il sistema. Fu negli anni 70-80 che si diffondono le workstation commerciali e nascono i PC. Queste macchine erano piccole, economiche e privilegiavano la facilit duso allefficienza. I primi modelli erano dotati di sistemi operativi monoutente con accesso interattivo. In questi anni nascono e si sviluppano le reti di calcolatori che hanno poi portato allincredibile crescita di internet. Il boom avviene dagli anni 90 in poi dove la diffusione dei PC capillare. Lo sviluppo delle reti calcolatore enorme ed internet entra in tutte le case. Nacquero cos i sistemi operativi di distribuiti che girano su sistemi a pi processori oppure che inviano i processi da elaborare ad altri computer della rete.

Componenti di un sistema operativo. Allinterno di un sistema operativo si trovano: un sistema di gestione del processore che controlla lunit centrale di elaborazione e si occupa di definire quali programmi sono da eseguire e quali compiti sono da assegnare di volta in volta alla CPU oltre che gestire la traduzione dei programmi in un formato direttamente eseguibile dal processore; un sistema di gestione della memoria che controlla lallocazione (lassegnazione) della memoria di lavoro di diversi programmi che possono essere contemporaneamente in esecuzione; un sistema di gestione delle periferiche per garantire laccesso ai dispositivi I/O evitando i conflitti che possono sorgere nel caso che diverse richieste arrivino contemporaneamente; un sistema di gestione dei file (file system) per archiviare e reperire dati sfruttando le periferiche che costituiscono la memoria di massa; un sistema di gestione degli utenti e dei relativi comandi (interprete comandi o interfaccia utente) che si interfacci direttamente con gli utenti permetta loro di accedere in maniera semplice e intuitiva alle funzionalit disponibili. Per esempio se vogliamo far eseguire in programma dovremo prima far partire la richiesta di esecuzione facendo doppio click sullicona del programma (interprete comandi), ci sar il caricamento dalla memoria secondaria a quella principale (gestore delle periferiche), sar assegnata unarea nella memoria principale (gestore della memoria) ed infine si avr lesecuzione da parte della CPU (gestore dei processi). La funzione di un SO, quindi, e di rendere appropriatamente utilizzabili le risorse fisiche presenti nel sistema informatico (CPU, memoria principale, dispositivi I/O). Rappresenta quindi uninfrastruttura software che si pone come interfaccia fra linfrastruttura hardware e lutente e che facilit lutilizzo e la gestione delle varie risorse del sistema. La funzione fondamentale dei SO la gestione dei processi. Il concetto di processo nasce dalla necessit di dover gestire pi programmi in esecuzione contemporaneamente. Il processo non da confondere con il programma. Il primo definisce un insieme formato da un elenco finito di azioni da eseguire in sequenza e dai dati che vengono elaborati dalle stesse azioni, il secondo invece, la descrizione di un algoritmo in un linguaggio adatto a essere eseguito da un computer, cio una sequenza ordinata di operazioni o istruzioni che produce soluzioni per una data classe di problemi. Sistemi operativi multiprogrammati ed a partizione di tempo. Se consideriamo un sistema dotato di un unico processore otteniamo che un solo programma pu essere in esecuzione in ogni istante. Questa limitazione causa un ridotto utilizzo del sistema perch durante le operazioni di I/O il processore rimane pressoch inattivo. Nei sistemi multiprogrammi sono gi presenti in memoria diversi programmi. cos possibile gestire un numero elevato di utenti che eseguono applicazioni differenti tra loro, si eseguono cio pi programmi in parallelo. Quindi, mentre un programma in attesa che si concluda loperazione di I/O richiesta, un altro programma viene mandato in esecuzione. Lo svantaggio di questa soluzione risiede nella complessit del sistema operativo, che deve essere in grado di gestire la memoria, e, contemporaneamente, deve essere estremamente veloce per minimizzare lincidenza del tempo di comunicazione fra i programmi rispetto alla disponibilit del sistema per le elaborazioni richieste delle varie applicazioni. Sebbene luso della multiprogrammazione consenta unefficiente elaborazione batch, spesso si ha lesigenza che un programma interagisca con lutente garantendo dei tempi di risposta pi bassi e la multiprogrammazione non basta. Fu sviluppato allora un sistema a partizione di tempo (timesharing) che simula un quasi parallelismo nellaccesso alle risorse da parte di pi utenti o programmi. Al fine di evitare che la CPU venga utilizzata in modo esclusivo da parte di un solo programma, il tempo viene suddiviso in unit elementari dette quanti da assegnare secondo 10

opportune politiche a tutti i programmi. La soluzione pi semplice di assegnare a rotazione la disponibilit di un quanto di tempo ai vari programmi presenti contemporaneamente in memoria. La gestione dei processi. Il componente in grado di eseguire processi viene chiamato genericamente processore. Il SO gestisce i processi suddividendoli in tre stati: processi in esecuzione, ovvero con il processore a disposizione per lesecuzione del proprio codice; processi pronti, quindi in grado ed in attesa di essere eseguiti non appena il processore sar disponibile. I processi in questo stato vengono messi in una coda gestita tipicamente secondo la politica: primo arrivato primo servito (FIFO); processi in attesa, ovvero non ancora in grado di essere effettivamente eseguiti dal processore poich in attesa del verificarsi di un evento esterno (per esempio la pressione di un tasto sulla tastiera per passare allo stato di pronto). Loperazione di scheduling serve ad eseguire pi programmi contemporaneamente ed a migliorare lutilizzo del processore. Si tratta di politiche ed algoritmi di uno dei processi nello stato di pronto da portare in esecuzione. Ad esempio, quando necessario eseguire un'operazione di I/O, il processore non pu proseguire l'elaborazione del processo attualmente in esecuzione fino al completamento della stessa. Dato che le operazioni di I/O sono pi lente del processore sarebbe un inutile spreco di risorse se il processore rimanesse bloccato fino al completamento delle stesse. Per evitare questo le operazioni di I/O vengono gestite unicamente dal SO che, nel frattempo, assegna l'uso del processore ad un altro processo. In questo modo si massimizza l'uso delle risorse del sistema. Esistono vari algoritmi di scheduling che tengono conto di varie esigenze e che possono essere pi indicati in alcuni contesti piuttosto che in altri. La scelta dell'algoritmo da usare dipende da cinque principali criteri: utilizzo del processore (questo deve essere attivo il pi possibile riducendo al minimo i tempi morti), produttivit (processi completati nellunit di tempo), tempo di completamento (il tempo che intercorre tra linizio e la fine del processo), tempo d'attesa (tempo passato nello stato di pronto), tempo di risposta (il tempo che trascorre tra lavvio del processo e l'ottenimento della prima risposta). Gli algoritmi di scheduling sono: l'algoritmo FCFS (First Come First Served) che di tipo FIFO: esegue i processi nello stesso ordine in cui essi vengono sottomessi al sistema, quindi il primo processo ad essere eseguito quello che per primo richiede l'uso della CPU e quelli successivi vengono serviti non appena questo ha terminato la propria esecuzione. Questo tipo di algoritmo molto semplice da implementare ma solitamente anche poco efficiente, almeno considerando il tempo medio d'attesa; lalgoritmo RR (Round Robin) di tipo preempitive. Esegue i processi nellordine di arrivo come il FCFS ma in pi rispetto a questo esegue la prelazione del processo in esecuzione, cio al processo viene tolto luso del processore dopo il quanto di tempo stabilito, e viene inserito nella coda dei processi in attesa. In pratica ogni processo ha la possibilit di stare in esecuzione per un quanto di tempo. Quest'algoritmo consente a tutti i processi di ottenere il controllo della CPU ed evita quindi il problema dell'attesa indefinita (starvation). inoltre da tenere in considerazione l'impatto dovuto ai frequenti context switch effettuati (cambiamento di processo). necessario quindi calcolare correttamente la durata ottimale del quanto di tempo per far si che l'incidenza dei cambi e i tempi di attesa siano limitati; l'algoritmo SNPF (Shortest Next Process First) prevede che venga eseguito sempre il processo con il tempo di esecuzione pi breve tra quelli in attesa. Nei sistemi operativi reali si usa una combinazione di diversi algoritmi di scheduling, per esempio in windows 2000 si da una priorit maggiore ai processi interattivi tipici dellinterfaccia grafica e si da un quanto di tempo maggiore ai processi in primo piano (cio lapplicazione selezionata sullo schermo) rispetto a quelli sullo sfondo. 11

Competizione tra processi. Lesecuzione di pi processi porta diversi benefici ma anche degli inconvenienti come lo stallo e starvation. Lo starvation un fenomeno che si manifesta quando diversi processi devono accedere alla medesima risorsa ma solo alcuni vi riescono creando cos unattesa indefinita per gli altri programmi con priorit pi bassa. Una situazione di stallo si genera quando un processo rimane fermo dopo aver richiesto una risorsa che non le viene mai assegnata perch la risorsa in questione occupata da un altro processo che non riesce a liberarla, ad esempio perch necessita di unaltra risorsa che in uso proprio dallo stesso processo che ha inoltrato la richiesta. insomma, un insieme di processi in attesa circolare di risorse non condivisibili e non prelazionabili, gi assegnate ad altri processi. I processi in stallo possono passare in esecuzione, rilasciare risorse ed essere riattivati. Perch si generi lo stallo devono verificare contemporaneamente quattro situazioni: mutua esclusione, cio esiste una risorsa non condivisibile e quindi utilizzabile solo da un processo alla volta; possesso e attesa, quando un processo in possesso di almeno una risorsa attende di acquisire altre risorse in possesso di altri processi; impossibilit di prelazione, i processi non possono essere forzati a rilasciare in anticipo le risorse acquisite; attesa circolare, quando esiste un insieme di processi tali che il primo processo in attesa di una risorsa posseduta dal secondo, il quale attende una risorsa posseduta dal terzo e cos via fino allultimo che attende una risorsa posseduta dal primo processo creando unattesa circolare. Per affrontare e gestire gli stalli abbiamo diversi approcci: usare un protocollo per prevenire gli stalli rimuovendo una delle quattro condizioni, evitare lo stallo con specifiche politiche di allocazione, individuare lo stallo ed eseguire il ripristino, ignorare il problema fingendo che lo stallo no esista. Per prevenire gli stalli possiamo agire in pi modi. Evitando di assegnare risorse in modo esclusivo non si verificher la mutua esclusione. Imponendo che un processo prima di andare in esecuzione richieda tutte le risorse di cui ha bisogno evitando cos il possesso e attesa ma rischiando attese lunghe. Esercitando la prelazione su tutte le risorse in possesso di un processo che possiede gi una o pi risorse ed inoltra unaltra richiesta che non pu essere subito soddisfatta evitando cos limpossibilit di prelazione. Mentre per evitare lattesa circolare si fa in modo che quando un processo inoltra la sua prima richiesta di una risorsa pu scegliere quella che vuole, dopo di che potr scegliere solo le risorse che, in ordine, vengono dopo. Per evitare lo stallo si usa lalgoritmo del banchiere. Se si crea un processo, questo deve dichiarare il numero massimo di richieste di ciascun tipo di risorsa di cui necessita. Quando il processo richiede un gruppo di risorse che se assegnate lasciano il sistema in uno stato sicuro (per ogni processo le richieste che lo stesso processo pu ancora fare si possono soddisfare) si procede con lassegnazione, altrimenti si lascia il processo in attesa che si liberi qualche risorsa. Lalgoritmo dello struzzo si utilizza qualora si volesse ignorare lo stallo. Questa soluzione ragionevole se lo stallo capita raramente ed il costo per evitarlo, in termini di memoria e di tempo della CPU, troppo elevato. Lo stallo pu essere eliminato forzando il prerilascio di una risorsa da parte di un processo, salvando periodicamente lo stato dei processi (rollback), terminando i processi. Gestione della memoria. Con la nascita di SO sempre pi sofisticati, per esempio per supportare la multiprogrammazione, cresce il numero di processi che devono risiedere contemporaneamente in memoria, implicando anche la crescita delle dimensioni della memoria centrale necessaria per il 12

corretto funzionamento del sistema. La memoria centrale limitata per motivi di costo, quindi la quantit di memoria non occupata dal SO (quella cio a disposizione per i programmi) pu risultare molto piccola e, di conseguenza, con valori tali da consentire solo a pochi programmi lesecuzione contemporanea. Per superare questa limitazione sono state create varie soluzioni basate sulla combinazione di diverse strategie come: consentire il caricamento di un programma a partire da un indirizzo qualunque della memoria, ridurre la necessit di spazio tenendo in memoria solo una porzione dei programmi e dei dati, condividere parte delle istruzioni tra diversi processi corrispondenti ad uno stesso programma. Queste strategie vengono eseguite dal gestore della memoria. Questo garantisce ai vari processi uno spazio di indirizzo in cui lavorare e mette in atto dei meccanismi di protezione che tutelano la privatezza dello spazio di lavoro assegnato ad ogni processo. La compilazione un processo che ha partire dal programma sorgente consente di ottenere un programma eseguibile. Durante la compilazione i nomi ed i riferimenti sono stati risolti, cio le istruzioni sono in formato macchina e tutti i riferimenti ad istruzioni di memoria sono espressi nella forma di indirizzi. Questo si ottiene collocando le istruzioni in unarea di memoria ideale (spazio logico) che, nel caso pi semplice, un intervallo di celle contigue che partono dallindirizzo 0 e che strutturata in accordo alle esigenze del SO. Questa memoria non coincide per con quella reale (spazio fisico) che lo spazio di memoria in cui risiede effettivamente il codice. Per far funzionare il programma a partire da una posizione arbitraria della memoria bisogna effettuare una rilocazione. Questa consiste nel sommare a tutti gli indirizzi presenti nel programma un valore (spiazzamento o offset) corrispondente alla differenza fra lindirizzo a partire dal quale verr effettivamente caricato il programma (di solito 0) ed il valore a partire dal quale sono stati calcolati gli indirizzi. Il codice pu essere rilocato dal linker (rilocazione statica) oppure direttamente in fase di esecuzione di ogni istruzione (rilocazione dinamica). La rilocazione statica pu essere accettabile nel caso di sistemi uni programmati, quando viene riservata permanentemente una zona di memoria al SO e la parte restante rimane al programma che viene caricato a partire sempre dallo stesso indirizzo. La rilocazione dinamica non una tecnica puramente software in quanto richiede lesistenza di opportuni dispositivi interni alla CPU, per esempio del registro di base che contiene lindirizzo effettivo di caricamento del programma da sommare allindirizzo di ogni istruzione che la CPU deve eseguire. Questa rilocazione necessaria nella multiprogrammazione. La protezione della memoria un sistema che impedisce ad un processo di corrompere la memoria di un altro processo in esecuzione contemporaneamente sullo stesso computer. La paginazione il metodo pi utilizzato per proteggere la memoria. Quando la memoria centrale non ha dimensioni tali da contenere tutti i programmi da eseguire contemporaneamente, il SO potrebbe non poter attivare nuovi processi o dovrebbe forzare la terminazione di processi. Per evitare questi problemi il SO pu effettuare lo swapping, cio il trasferimento del contenuto da unarea della memoria centrale in unaltra area della memoria di massa (area di swap). Questa tecnica, quindi, viene applicata trasferendo sul disco i dati relativi ai processi in stato di attesa o di pronto allesecuzione. Per implementare ulteriormente i meccanismi di protezione della memoria si pu utilizzare la segmentazione. Questa tecnica rende possibile la gestione condivisa di alcune parti del programma suddividendo la memoria fisica disponibile in blocchi detti segmenti: i segmenti di codice contengono solo le istruzioni del programma e potranno essere condivisi tra vari processi; i segmenti di dati contengono sia la parte allocata staticamente, il cui spazio viene riservato durante la compilazione, sia la parte dinamica, che corrisponde alle variabili che vengono create durante lesecuzione del programma. Con questa organizzazione il SO consente a pi processi di condividere lo stesso segmento di codice. Un ulteriore miglioramento nelluso della memoria si ottiene suddividendo il programma in un certo numero di sezioni di dimensioni fisse ed uguali fra loro dette pagine logiche, e, in corrispondenza, organizzando allo stesso modo anche la memoria fisica in pagine fisiche della 13

stessa dimensione delle prime. In questo modo possibile estendere la dimensione di un processo utilizzando zone di memoria non necessariamente contigue e tenere in memoria solo la porzione ridotta del programma che si sta utilizzando. La memoria virtuale usata insieme a paginazione o segmento ed capace di simulare uno spazio di memoria centrale maggiore di quello fisicamente presente. Con questo sistema si tiene nella memoria principale solo una parte di ciascun programma in esecuzione e la parte restante va nella memoria secondaria. Se dovesse capitare che nella memoria fisica non sono presenti pagine o segmenti liberi necessario sostituire una di quelle presenti. Il tempo di accesso alla memoria si calcola con la formula: Tm = (1 h) * Tp + h * (Ts + Tp) dove Tp il tempo di accesso alla memoria principale, Ts il tempo di gestione dellassenza di pagina o segmento ed maggiore di Tp perch richiede laccesso alla memoria secondaria e h la probabilit che si verifichi unassenza di pagina o segmento. Lobbiettivo della memoria virtuale minimizzare Tm e renderlo idealmente uguale a Tp (ovviamente Tm > Tp). Il parametro critico che incide in questa formula h, quando questo molto inferiore a 1 (h<<1) Tm circa uguale a Tp (Tm Tp). File system. Il file system un componente del SO destinato a gestire la memoria di massa, con lobbiettivo di presentare allutente nel modo pi semplice possibile lorganizzazione logica dei dati e le operazioni che possibile compiere su di essi. Informalmente possiamo dire che un file system un meccanismo con il quale i file sono immagazzinati e organizzati su un dispositivo di archiviazione secondaria o terziaria. Le operazioni di base di un file system sono: recupero di dati precedentemente memorizzati, eliminazione di dati obsoleti, modifica o aggiornamento di dati preesistenti, la copia di dati. I file system sono basati su concetti di file e directory. I file sono dei contenitori logici identificati mediante un nome composto da due parti separate da un punto: il nome vero e proprio dato dallutente e lestensione. Questultima associata al programma che ha generato il file e identifica la tipologia dei dati contenuti nel file. Per esempio i file eseguibili hanno estensione exe, i file di testo generici txt, file multimediali avi o mpg e altri ancora. Ad ogni file sono associati dati come la lunghezza del file e la data e lora di creazione o di ultima modifica pi altre informazioni utilizzate dal sistema operativo e non immediatamente visibili allutente come quelle riguardanti la protezione e il posizionamento nella memoria secondaria. La directory un contenitore logico dove vengono raccolti tutti i file di una partizione. La sua struttura pu essere di tre tipi: a livello singolo, a due livelli, ad albero. Nella struttura a livello singolo (utilizzata per i primi SO) si ha una directory per tutti i file, quindi, in sistemi usati da pi utenti, si ha una condivisione dello spazio di memorizzazione logico che pu causare conflitti nel caso vengano utilizzati per diversi file nomi uguali. Questo problema venne risolto in parte con la struttura a due livelli che prevedeva una directory principale (o master directory) ed unaltra directory per tutti gli utenti. Come detto il problema fu risolto in parte in quanto i nomi dei file di diversi utenti potevano avere nome uguale, quindi eliminava i conflitti di nome tra utenti diversi, ma non eliminava i conflitti di nome tra i file di uno stesso utente che quindi dovevano essere tutti diversi. Nel terzo tipo file vengono divisi in directory organizzati secondo una struttura ad albero. Il file system contiene una directory, detta radice dellalbero (root), che pu contenere dei file ma anche dei riferimenti ad altre directory (subdirectory) ognuna delle quali, a sua volta, pu contenere file o riferimenti ad altre directory e cos via. Con questo sistema possiamo considerare ogni file come una foglia di un albero di directory. Ciascun file viene quindi individuato dal suo nome completo (percorso assoluto), cio dalla sequenza dei nomi delle directory (nodi) che si incontrano a partire dalla radice, intervallati da un carattere di separazione (\ in windows e MS-DOS). Il file pu essere identificato anche dal suo percorso relativo alla directory, spesso pi breve del percorso completo. In ogni istante, infatti, durante le operazioni di gestione del file system,

14

definita una directory system che individua la posizione attuale del contesto in cui lutente sta lavorando. Gestore delle periferiche I/O. Le periferiche consentono di effettuare operazioni di lettura e scrittura mediante comandi indipendenti dalla struttura hardware delle periferiche in questione. Il gestore delle risorse deve garantire la comunicazione tra CPU e dispositivi esterni, deve quindi gestire anche laccesso contemporaneo al calcolatore da parte di diverse periferiche. Ogni periferica viene gestita da due entit cooperanti, i controller ed i driver. I controller sono dei dispositivi hardware che colloquiano direttamente con la periferica e che servono ad effettuare a livello fisico le operazioni di trasferimento dei dati con le periferiche. Dipendono dalle caratteristiche fisiche delle periferiche che gestiscono, infatti, per esempio, linterfaccia per la gestione del mouse diversa da quella utilizzata per controllare il funzionamento del lettore CD-ROM. I driver sono dei programmi software che fanno parte del sistema operativo, conoscono le caratteristiche specifiche della periferica e colloquiano con il controller. Sono quindi finalizzati alla gestione delle periferiche. I driver hanno lo scopo di mascherare le caratteristiche specifiche dei controller, fornendo un insieme di primitive di alto livello per la gestione delle operazioni di I/O utilizzabili dai programmi applicativi e dagli utenti. In questo modo si svincola il funzionamento dei programmi dai dettagli del sottosistema I/O, migliorandone la portabilit su diversi calcolatori e facilitandone le operazioni di manutenzione e aggiornamento. Quando si installa un nuovo driver bisogna fornirgli delle informazioni a basso livello per permettergli di colloquiare correttamente con il resto del sistema (configurazione), per esempio stabilire quali linee del bus utilizzare per inviare uninterruzione. Solitamente il driver sviluppato da chi costruisce la periferica e non da chi costruisce il sistema operativo. I SO pi recenti sono dotati di funzioni plug&play (PnP) che permettono la configurazione automatica dei driver. Allattivazione del SO tutte le periferiche collegate al sistema vengono esaminate, queste si fanno riconoscere specificando quali driver servono e il SO installer quelli opportuni per la loro gestione. Un sistema PnP consente quindi di aggiungere (plug) nuove periferiche al sistema che possono essere utilizzate (play) senza necessit di intervento da parte dellutente per la selezione dei driver. Un aspetto interessante legato alla possibilit di render possibile la presenza di pi periferiche non condivisibili. Questo avviene tramite la tecnica dello spooling. Possiamo fare un esempio nella gestione della stampante: quando un processo desidera stampare un file, non lo invia alla stampante ma al driver che lo accoda in unopportuna directory di spooling, in attesa del suo turno per utilizzare la periferica. Quindi i compiti del driver in questo caso sono: accodare file fa stampare nella directory di spooling, stampare uno alla volta i file contenuti nella directory, e rimanere in memoria in attesa che un processo cerchi di stampare qualora la coda termini. Lo spooling una soluzione molto efficiente perch permette di disaccoppiare il programma che deve stampare e la periferica e rende possibile luso della stampante da parte di molti processi senza attese inutili. Il processo di spooling pu essere anche un processo remoto (cio che risiede su unaltra macchina accessibile da una rete) che ha accesso ad una o pi stampanti. Nei vari SO le operazioni di I/O sono gestite come usuali operazioni di lettura e scrittura su file speciali che corrispondono alle periferiche selezionate. Se, per esempio, scriviamo sul file speciale lp1 (line printer), stiamo inviando i caratteri da stampare al driver associato alla periferica di stampa lp1. In questo modo si svincola in funzionamento di un programma dalla natura delle operazioni di I/O, che possono avvenire tramite file, oppure da e verso periferiche fisiche (file speciali), oppure anche collegando direttamente luscita di un programma allingresso dellaltro. Protezione e sicurezza.

15

I SO, soprattutto quelli multiutente, possiedono dei meccanismi di identificazione degli accessi al sistema. Questi meccanismi sono: oggetti fisici (tessere e chiavi), conoscenza di informazione (password), caratteristiche biometriche dellutente (impronte digitali, firma). Il metodo pi semplice e comune consiste nellassociare ad ogni utente un account ed una password. Tutte le volte che un utente accede al sistema deve sottostare alla procedura di identificazione (login) che consiste nel specificare laccount ed inserire la password. Ogni specifica categoria di utenti avr necessit operative differenti, cos, per esempio, lamministratore di sistema avr la necessit di interagire con il sistema operativo in modo approfondito per poterlo configurare e amministrare nel migliore dei modi, mentre, un utente occasionale, sar pi interessato allaccesso ad un certo insieme di periferiche ed ad un certo tipo di applicazioni che servono allo svolgimento del suo lavoro oltre alla garanzia che i suoi dati siano protetti. Queste protezioni possono essere abilitate anche dallutente oltre che dallamministratore. Lamministratore del SO viene chiamato utente root o administrator e, generalmente, non abilit nessun altro utente ad accedere alla parte del file system dove memorizzato il sistema operativo. Egli possiede i diritti di accesso dei dati di tutti gli utenti e la possibilit di modificare i loro diritti di utilizzo delle risorse. Negli ultimi anni stato semplificato il compito delladministrator fornendo interfacce grafiche per lo svolgimento delle operazioni pi comuni come la definizione dei diritti di accesso alle risorse del sistema per i vari utenti. Gli strumenti moderni di amministrazione del sistema permettono di automatizzare molte operazioni, consentendo la loro applicazione su gruppi di utenti ordinati in base alla loro tipologia, evitando cos anche possibili errori delladministrator. Codifica binaria dellinformazione. Come abbiamo detto linformatica la scienza della rappresentazione e dellelaborazione dellinformazione. Questultima sempre portata da, trasmessa su, memorizzata in o contenuta in un supporto fisico. Informazione e supporto fisico. Linformazione non esiste senza un supporto, chiaro per che non ogni supporto risulta adatto come base per ogni tipo di informazione. Si ottiene informazione quando dalla lettura del supporto alcune di queste vengono selezionate ed altre eliminate. Condizione necessaria perch un supporto sia i grado di portare informazione perci che esso possa assumere configurazioni differenti, ad ognuna delle quali viene associata una differente entit di informazione. Un supporto che si presenta sempre in un unico modo non pu portare informazione. Per interpretare le differenti configurazioni del supporto in termini di informazione necessario un codice convenzionale che ad ogni configurazione ammessa nel supporto associa unentit di informazione. La definizione di un codice comporta perci che siano identificati in modo non ambiguo linsieme delle possibili entit di informazione a cui ci si vuole riferire. Generalmente si adottano supporti fisici le cui configurazioni sono costituite da liste di sottoconfigurazioni. Il codice definisce: linsieme delle configurazioni fisiche del supporto, in quanto questo assume in ogni istante una configurazione scelta allinterno dellinsieme delle possibili configurazioni; linsieme delle diverse entit di formazione che possono essere associate alle configurazioni del supporto fisico, le entit di informazione sono chiamate comunemente messaggi; la relazione tra configurazioni del supporto ed entit di informazione. Sintassi e semantica. Come detto il concetto di informazione riferito a due livelli distinti: un livello fisico e un livello logico. Questi due livelli possono essere caratterizzati come segue: 16

si tratta di informazione quando ci si chiede se un certo supporto fisico in grado, in base alle configurazioni che pu assumere, di costituire la base su cui un certo messaggio pu essere scritto; ci si pone dunque un problema di relazione tra i segni, cio tra configurazioni del supporto fisico. A questo livello si parler di informazione sintattica; si tratta di informazione quando ci si chiede quale significato sia da attribuire ad una certa configurazione del supporto fisico; ci si pone dunque il problema di relazioni tra segni e significati. A questo livello si parla di informazione semantica. In alte parole la sintassi definisce il sottoinsieme di tutte le possibili sequenze di simboli che possono essere usate per codificare linformazione e la semantica, invece, definisce il significato attribuito ai vari livelli di configurazioni del supporto fisico (simboli, sequenze di simboli, ecc). I calcolatori possono essere visti come macchine che elaborano meccanicamente simboli che rappresentano informazioni codificate. Lelaborazione avviene solo a livello sintattico, infatti il calcolatore non conosce il significato dei simboli che elabora. Sono i progettisti dei calcolatori e programmatori che devono assicurare la correttezza della corrispondenza tra i simboli, le loro trasformazione e il loro significato. Anche la teoria della codifica e della trasformazione dellinformazione alla base della tecnologia informatica e delle comunicazioni considera solo il livello sintattico. Codifica analogica e codifica digitale. Linformazione pu essere classificatoria o pi che classificatoria. La prima si basa sul concetto: questo ma poteva essere questaltro. fondata quindi sulla possibilit di distinzione ed utile per discriminare tra elementi compresi in un insieme finito. Al supporto, quindi, chiesto solamente di essere in grado di mantenere distinte le configurazioni che identificano entit di informazioni diverse. Linformazione pi che classificatoria, invece, consente non soltanto di riconoscere le distinzioni, ma anche di stabilire una relazione dordine (questo maggiore di questaltro) o una metrica (questo distante un certo valore da questaltro). Linsieme delle entit di informazione ha una struttura. La struttura dice cosa si pu fare con le entit di informazione dellinsieme, in termini di operazioni di combinazione e di confronto. Si tratta di informazione su informazione (meta-informazione) in presenza della quale linsieme delle entit di informazione diventa un sistema: un insieme con struttura. Come gi detto, nessuna operazione su entit di informazione pu essere compiuta a prescindere da un supporto fisico. Il problema quindi come rendere possibile che le configurazioni del supporto siano in grado di portare non solo informazione ma anche meta-informazione, per poter portare informazione di identificazione, ordine, metrica, ecc. Per risolvere questo problema possiamo utilizzare un supporto in grado di portare esplicitamente la meta-informazione oppure rappresentare implicitamente la meta-informazione nella regola di codifica. Nella meta-informazione esplicita nel supporto, il supporto ha una struttura corrispondente a quella presente tra entit di informazione. In questo modo ogni configurazione del supporto non solo codifica unentit di informazione, ma anche risulta immersa in una struttura relazionale che corrisponde a quella presente tra entit di informazione. Per esempio, per indicare il voto conseguito da uno studente si utilizza un rettangolo la cui superficie proporzionale al voto: tra le dimensioni dei rettangoli stabilita una relazione di ordine analoga alla relazione dordine che esiste tra i voti. Nella seconda strategia, meta-informazione implicita nella regola di codifica, al supporto si richiede di avere configurazioni molteplici e distinguibili luna dallaltra e per portare la metainformazione, si utilizza una regola di codifica definita in modo estensionale, specificando per ogni configurazione lentit di informazione associata. Per esempio, per indicare il voto ottenuto da uno studente si usa una configurazione convenzionalmente scelta in un insieme, per esempio {, , , , , } se i voti diversi da comunicare fossero al massimo 6. Se per esempio aggiungiamo i mezzi punti, cio modifichiamo linsieme delle entit di informazione, la prima soluzione applicabile senza variazioni, un rettangolo di 5,5 quadretti 17

codifica il voto 5; la seconda soluzione invece richiede di aumentare il numero di oggetti con cui si codificano i voti estendendo in conseguenza la regola di codifica. Ora possiamo definire le due strategie di codifica: analogica e digitale. La codifica analogica quando stabilisce una relazione di analogia tra struttura delle configurazioni e struttura delle entit di informazione, tale quindi che la meta-informazione rappresentata dal supporto. La codifica invece digitale quando la meta-informazione rappresentata solo implicitamente della codifica. Possiamo confrontare cinque parametri di queste codifiche: modalit di definizione della codifica: la definizione dellanalogico intensionale, mentre il digitale, dovendo elencare esplicitamente le corrispondenze tra configurazioni ed entit di informazioni, basato su definizioni estensionali; ridefinizione della codifica al variare dellinsieme delle entit di informazione: lanalogico non ha nessuna ridefinizione non imponendo nessun intervento sulla regola di codifica e quindi pi flessibile del digitale che richiede una ridefinizione della regola stessa; applicabilit in funzione della cardinalit dellinsieme delle entit di informazione: grazie alla definizione intensionale lanalogico applicabile pi ampiamente del digitale visto che pu essere impiegato anche quando le entit di informazione non siano stabilite; il digitale invece, a causa della definizione estensionale, applicabile solo per cardinalit finita e con entit note a priori; applicabilit in funzione della struttura dellinsieme delle entit di informazione: questa la differenza pi evidente tra analogico e digitale in quanto il primo va solo se sullinsieme delle entit di informazione c una struttura, se questa non c la strategia per consentire ad un sistema fisico di fungere da supporto il digitale; condizioni del supporto: lapplicabilit dellanalogico dipende dalla disponibilit di un supporto in grado di ricreare tra le sue configurazioni una struttura corrispondente a quella presente sullinsieme di entit di informazione; per il digitale, invece, sufficiente che la cardinalit dellinsieme delle configurazioni sia sufficiente a codificare tutte le entit di informazione (molteplicit). Codifica di dati numerici. Quasi tutti i sistemi basati sulla codifica numerica usano la codifica binaria. Lalfabeto che viene usato in questa codifica costituito da due simboli, indicati convenzionalmente 0 e 1, detti bit. Se consideriamo una successione di bit utilizzando un alfabeto di 2 simboli con k bit possiamo ottenere 2k successioni diverse. Ad una successione di 8 bit si d il nome di byte i cui multipli sono il kilo, mega, giga, tera che nel caso binario sono definiti in termini di potenze di 2 quindi: kbyte = 210 byte, Mbyte = 220 byte, Gbyte = 230 byte, ecc. Le entit di informazione vengono codificate con sequenza di bit di lunghezza predefinita, in particolare i numeri sono codificati con un numero di bit finito e determinato in fase di progetto del calcolatore. I calcolatori, quindi, possono elaborare solo numeri in precisione finita. Questo pone dei limiti sullinsieme di numeri che possono essere codificati in un calcolatore, e sulla precisione delle operazioni eseguite da essi. Facciamo un esempio: con tre cifre decimali possibile rappresentare i numeri interi dellinsieme A {0, 1, , 998, 999}. Il risultato di alcune operazioni tra numeri di questo insieme possono non far parte dellinsieme stesso, cio non sono rappresentabile con le tre cifre decimali. Per esempio 600+600 = 1200 (overflow, cio il risultato pi grande di 999); 5-7 = -2 (underflow, cio il risultato pi piccolo di 0); 3/2 = 1,5 (il risultato compreso tra 0 e 999 ma non fa parte dellinsieme A). Questi problemi si riscontrano anche nellassociativit della somma: prendiamo a=700, b=400 e c=300 loperazione a+(b-c) in teoria pu essere scritta anche (a+b)-c ma nel calcolo in precisione finita, come nel nostro esempio, no perch il risultato pu dipendere dallordine delle operazioni infatti: a+(b-c) = 700+(100) mentre (a+b)-c = (1100)-300 quindi produce in overflow. 18

Per comprendere le tecniche di codifica dei numeri in un calcolatore utile far riferimento alla notazione decimale che si adotta abitualmente. Un sistema di numerazione si dice posizionale se i simboli (cifre) usati per scrivere i numeri assumono valori diversi a seconda della posizione che occupano nella notazione. Ad esempio nel sistema di numerazione arabo, quello pi comunemente usato oggi al mondo, la prima cifra da destra esprime il numero delle unit, la seconda quello delle decine, la terza quello delle centinaia, la quarta quello delle migliaia, e cos via. Per esempio il numero 555 si legge: 5 centinaia, 5 decine, 5 unit quindi 5*10 + 5*101+ 5*100. Per un generico numero intero composto da n cifre e in base b>1 abbiamo: an-1*bn-1 + an-2*bn-2 + + a1*b1 + a0*b0 + a-1*b-1 + = p=- ap*bp Grazie a questa formula possiamo trasformare in base 10 un numero rappresentato in una qualsiasi altra base. Alcuni esempi: -3014otto = -(3*8 + 0*8 + 1*81 + 4*80) = -1549dieci 102,02tre = (1*3 + 0*31 + 2*30 + 0*3-1 + 2*3-2)tre = 11,2dieci Potremo utilizzare lo stesso metodo anche per convertire dalla base 10 ad unaltra base ma questa operazione complessa e quindi non conveniente. Per esempio convertiamo 565dieci in base 2: 565dieci = 5dieci*10dieci + 6dieci*101dieci + 5dieci*100dieci = 101due*10102due + 110due*10101due + 101due*10100due = 103141301 Per la sua complessit si pu adottare un metodo diverso. Le cifre della rappresentazione in una qualsiasi base diversa da dieci di un qualsiasi numero possono essere ottenute attraverso due procedimenti distinti, uno per la parte intera e uno per la parte frazionaria, che richiedono solo operazioni tra numeri espressi in base dieci. Possiamo operare con divisioni successive e in particolare dobbiamo tenere in considerazione di quozienti (q) e resti (R) di ogni divisione. Per esempio per rappresentare -1548dieci in base otto dobbiamo dividere: -1548/8=-193 R0=4; 193/8=-24 R1=1; -24/8=-3 R2=0; 3/8=0 R3=3 quindi -1548dieci = -3014otto. Per la parte frazionata possiamo procedere con delle moltiplicazioni successive tenendo conto della parte intera (c) e della parte frazionata (F) della moltiplicazione. Ad esempio per rappresentare 0,3dieci in base due: 0,3*2=0,6 c-1=0; 0,6*2=1,2 c-2=1; 0,2*2=0,4 c-3=0; 0,4*2=0,8 c4=0; 0,8*2=1,6 c-5=1; 0,6*2=1,2 c-6=1 ritorna al punto 2 quindi otteniamo:0,3dieci = 0,01001due. Un esempio con una frazione rappresentiamo -1/9dieci in base tre: -1/9*3=-1/3 c-1=0; -1/3*3= -1,0 c-2=0 quindi -1/9dieci = -0,01tre. A causa del minor numero di simboli dellalfabeto binario rispetto a quello decimale, un numero codificato in notazione binaria richiede pi cifre rispetto a quelle impiegate in notazione decimale. Per rendere pi sintetica la rappresentazione dei numeri elaborati dai calcolatori si utilizzano basi maggiori di 10, spesso la base 16 (notazione esadecimale). Nellalfabeto di questa base questa base ai numeri dall1 al 9 vengono affiancate le lettere dalla A alla F. Poich 16=24 questa notazione gode della propriet che ciascuna cifra esadecimale corrisponde ad un gruppo di quattro cifre binarie rendendo semplice la conversione dai numeri binari a quelli esadecimale. Il procedimento per effettuare operazioni su numeri in base diversa da dieci uguale a quello per le operazioni sui numeri decimali. Facciamo lesempio di unaddizione in base due, considerando che 1due+1due=10due e 1due+1due+1due=11due se eseguiamo laddizione 11001011due+11011010due otteniamo 110100101due. Codifica binaria dei numeri. Esistono quattro codifiche principali: per i numeri interi codifica in modulo e segno e codifica in complemento a due (attualmente utilizzata nei calcolatori), mentre per i numeri reali codifica in virgola fissa e codifica in virgola mobile (attualmente utilizzata nei calcolatori). La codifica in modulo e segno il modo pi semplice per rappresentare e distinguere numeri positivi e negativi: al numero binario vero e proprio viene anteposto un bit che assume il valore 0 19 1 0 1 0

se il numero positivo ed assume il valore 1 se il numero negativo. Il grande difetto di questa rappresentazione quello di avere due modi per scrivere il numero 0: 00000000 e 10000000 significano +0 e -0. Esempio con n=4 (bit) -2dieci in base due otteniamo -010due dove il primo dei quattro bit 1 perch il numero negativo. La codifica in complemento a due il metodo pi diffuso per la rappresentazione dei numeri negativi in informatica. Lo 0 indica sempre il segno pi e l1 il segno meno e la codifica dei numeri positivi coincide con quella in modulo e segno. Ai numeri viene anteposto un bit di valore zero; se poi il numero negativo necessario convertirlo in complemento a 2. Per rappresentare l'inverso di un numero binario in complemento a due di un numero binario se ne invertono, o negano, i singoli bit: si applica cio l'operazione logica NOT. Si aggiunge infine 1 al valore del numero trovato. Per esempio se vogliamo codificare -2dieci in base due con n=4 dobbiamo considerare il numero positivo |-2|dieci = +2dieci = +010due quindi 0010 complementando abbiamo 1101due aggiungendo 1due otteniamo 1110due. Per verificare facciamo -1*23 + 1*22+ 1*21 +0*20 = -8+4+2 = -2. il vantaggio di questo metodo lunica rappresentazione dello 0 e le operazioni di somma e differenza sono facilitate in quanto si riducono alla sola operazione di somma. Prendiamo per esempio 510 1010: 510 + ( 10)10 = 01012 10102 = 00101CA2 + 10110CA2 = 11011CA2 = 001012 = 510. La codifica in virgola fissa analoga alla codifica in modulo e segno degli interi. Dato che in un bit non rappresentabile la virgola il metodo pi semplice per rappresentare numeri frazionari quello di scegliere arbitrariamente la posizione della virgola. Per esempio con n=8 p=4 (parte intera) e q=3 (parte frazionata) +6,25dieci = +110,01due = +0110,010due 0 0110 010. La parte frazionata, se contiene pi cifre di q, viene approssimata, ad esempio: -7,5625dieci = -111,1001due 1 0111 100. La codifica in virgola fissa costringe a memorizzare molte delle cifre meno significative e limita lintervallo dei numeri codificabili indipendentemente dalla posizione delle cifre significative. La codifica in virgola mobile consente di codificare solo le cifre pi significative ed ha un intervallo di valori rappresentabili molto maggiore della virgola fissa. Un generico numero reale pu essere rappresentato come X=M*BE M = mantissa (n reale), B = base, E = esponente (n intero). Esistono innumerevoli modi per rappresentare numeri in virgola mobile ma il sistema pi utilizzato lo standard IEEE P754 (1985), in questo metodo ogni numero identificato dal segno, da una mantissa di p bit (1,xxxxx) e dall'esponente di q bit (nyyyyy). Per esempio proviamo a codificare -12,625dieci con B=2, n=16, p=10, q=5: prima convertiamo in binario -1100,101due; normalizziamo cio dividiamo per 2dieci quindi 10due -0,1100101*10100due (elevato 100due = 4dieci cio quanto ho spostato la virgola per ottenere un numero tipo 0,xxx); eliminazione del numero iniziale (0,) e codifica della mantissa (p=10 bit) 1001010000; codifica dellesponente (q=5 bit) 00100; la codifica richiesta quindi 1 1001010000 00100. Codifica dei caratteri. Per determinare una codifica binaria per dei documenti scritti in linguaggio naturale, per esempio italiano, dobbiamo prima stabilire quanti sono i simboli da codificare: le lettere dellalfabeto se consideriamo maiuscole e minuscole sono 52; le cifre decimali 10; una trentina di simboli per caratteri di uso corrente (+ * % ecc) e punteggiatura; alcuni caratteri speciali associati a funzioni di controllo (INVIO, ESC, ecc). Avremo quindi in totale circa 120 simboli diversi per la cui codifica servono 7 bit (27 = 128). Il sistema di codifica per pi diffuso per rappresentare i caratteri , infatti, quello ASCII che nella sua versione originaria prevede una successione di 7 bit. Esistono anche delle versioni estese del codice ASCII basate sulla successione di 8 bit che rappresentano 256 caratteri. Simile a questa versione di ASCII il codice EBCDIC, sviluppato da IBM e basato sempre su successioni di 8 bit. Tuttavia se consideriamo tutti i caratteri presenti nei vari alfabeti presenti nel mondo (greco, arabo, ecc) 8 bit non bastano stato definito il codice UNICODE basato su successioni di 16 bit (216 = 65535 caratteri). Per facilitare il passaggio da ASCII ad UNICODE i primi 128 caratteri del 20

codice UNICODE sono gli stessi del codice ASCII. Purtroppo per neanche questultimo codice riesce a coprire tutti i simboli utilizzati da tutte le lingue del mondo (circa 200000). Codifica delle immagini. Nella codifica delle immagini limmagine viene digitalizzata, viene cio suddivisa tramite una griglia ed ogni quadratino (punto) ottenuto corrisponde ad un pixel codificabile in binario. Per ricostruire limmagine a partire dalla sequenza di bit bisogna conoscere la base e laltezza (espressa in pixel) dellimmagine stessa. La risoluzione di unimmagine determinata dal numero di punti per pollice (cio pixel per unit di misura) e dal numero di colori o livelli di grigio (fissato dal numero di bit con cui si codifica tale caratteristica). Per il bianco e nero necessario un bit per pixel (21 = 2), per esempio possiamo usare 0 per il nero ed 1 per il bianco. In caso invece di un numero n livelli di grigio avremo bisogno di n bit per pixel, quindi lo 0 sar sempre uguale al nero mentre il bianco sar 2 n-1. La codifica di colori pi diffusa la RGB (red green blue), dove ogni colore una tripla (x, y, z) di numeri esadecimali: x lintensit del rosso, y lintensit del verde e z lintensit del blu. Algoritmi. Molte azioni che si compiono possono essere interpretate come finalizzate alla soluzione di problemi. I problemi che interessano linformatica sono quelli che consistono nellelaborazione dellinformazione; ognuno di questi problemi caratterizzato da un insieme di dati di partenza, da un procedimento di risoluzione (algoritmo) che manipola i dati di partenza e da un risultato ricercato. La conoscenza di come si risolve un problema e la capacit di risolverlo si riferiscono a competenze distinte e non sempre conseguenti luna allaltra. Per esempio si pu conoscere la ricetta di una torta ma non si possiede un forno. Descrizione degli algoritmi. Con una definizione informale possiamo dire che lalgoritmo una sequenza di passi definiti con precisione che portano alla realizzazione di un dato compito o alla risoluzione di un dato problema. Pu capitare che un soggetto affronta un problema la cui soluzione deve essere eseguita da un esecutore. Il procedimento di soluzione del problema realizzato in fasi distinte: analisi del problema e identificazione di una soluzione da parte del primo soggetto; descrizione della soluzione da parte del primo soggetto in termini comprensibili per lesecutore; interpretazione della soluzione da parte dellesecutore; attuazione della soluzione da parte dellesecutore. Lesecutore, quindi, deve essere in grado di eseguire un insieme predefinito di operazioni e di capire il linguaggio in cui descritta la sequenza di tali operazioni. Detto questo possiamo dare allalgoritmo unaltra definizione: lalgoritmo la descrizione del procedimento per la risoluzione di un dato problema espressa in modo non ambiguo, in un linguaggio comprensibile allesecutore e in termini di una sequenza finita di istruzioni che lesecutore sia in grado di eseguire. Prendendo come esempio una ricetta da cucina: se chiediamo di aggiungere un pizzico di sale siamo ambigui perch un pizzico non quantificabile esattamente; se esponiamo la ricetta in inglese e lesecutore parla solo italiano non siamo comprensibili; se chiediamo di usare il frullatore ma lesecutore non lo ha egli non potr eseguire il comando. Normalmente un algoritmo non risolve un singolo problema ma unintera classe di problemi strutturalmente equivalenti, ovvero tutte le istanze di un dato problema. Per esempio il procedimento per eseguire unaddizione consente di calcolare la somma di qualsiasi coppia di numeri e non di una sola coppia. Il calcolatore lesecutore di riferimento per i problemi affrontati nellinformatica, essenzialmente esso un esecutore automatico di algoritmi. Il calcolatore comprende solo il linguaggio macchina (LM) che permette di esprimere le istruzioni logico-aritmetiche che il 21

calcolatore stesso deve eseguire. Gli algoritmi espressi in un linguaggio comprensibile al calcolatore sono detti programmi. Uno dei problemi principali dellinformatica la formulazione di algoritmi e la loro codifica in programmi. Linguaggi per la rappresentazione degli algoritmi. Come abbiamo detto un algoritmo inutilizzabile dal calcolatore se il suo linguaggio non comprensibile, non ambiguo e composto da istruzioni eseguibili. Queste caratteristiche sono proprie dei linguaggi formali, la cui sintassi e semantica sono ben definite, utilizzabili per il controllo di un calcolatore. La sintassi studia le regole che stabiliscono il posto che le parole occupano allinterno di una frase, definiscono quindi le frasi corrette del linguaggio, cio le frasi alle quali sia possibile attribuire un significato. La semantica, invece, definisce il significato delle frasi corrette, cio lazione che viene compiuta quando listruzione viene eseguita. Come esempio di linguaggio formale possiamo prendere il linguaggio matematico, mentre non un linguaggio formale quello naturale utilizzato normalmente dalle persone in quanto una frase pu assumere significati diversi a seconda del contesto quindi ambiguo. Il LM, adoperato dai calcolatori, difficile da usare per luomo quindi, per consentire uno sviluppo rapido e il pi possibile facilitato delle applicazioni informatiche, sono stati definiti i linguaggi di alto livello che consentono al programmatore di esprimere gli algoritmi secondo una logica pi vicina a quella di un essere umano e ad un livello di astrazione pi alto rispetto al LM. I linguaggi ad alto livello permettono di descrivere sia lalgoritmo che le componenti operative di unapplicazione informatica in un formalismo che fa uso di pochi termini linguistici per formare istruzioni dal significato non equivocabile. Un programma una successione di queste istruzioni che possono essere trasformate in LM e quindi eseguite dal calcolatore. Nel corso degli anni sono stati ideati cari linguaggi di programmazione: FORTRAN un linguaggio compilato (cio traduce le istruzioni) e imperativo, utilizzato per il calcolo scientifico e numerico; Lisp un linguaggio di programmazione con implementazioni sia compilate che interpretate (cio i programmi vengono eseguiti da un interprete) usato nei progetti di intelligenza artificiale; COBOL un linguaggio operativo utilizzato nelle applicazioni commerciali; il linguaggio C un linguaggio imperativo utilizzato per programmi di sistema, calcoli scientifici e numerici con una sintassi libera e flessibile permettendo di scrivere istruzioni complesse in poche righe di codice; il linguaggio C++ deriva dal linguaggio C ed orientato agli oggetti; Java deriva dal linguaggio C++ ed anchesso orientato agli oggetti ed indipendente dalla piattaforma e viene utilizzato per le applicazioni internet. Per pseudolinguaggio si intende un linguaggio di programmazione fittizio, cio non direttamente compilabile o interpretabile da un programma compilatore o interprete, il cui scopo quello di rappresentare algoritmi. Sono quindi dei linguaggi formali per la descrizione di algoritmi simili a quelli di alto livello ma pi semplici e intuitivi. I pseudolinguaggi sono usati per facilitare la formulazione di algoritmi in quanto consentono di esprimerne le idee fondamentali senza vincolarsi ai dettagli di specifici linguaggi. La sintassi e la semantica sono proprie di ogni pseudolinguaggio ma si basano sulla struttura della maggior parte dei linguaggi di alto livello, tenderanno quindi ad essere meno rigorose rispetto ad un vero linguaggio in modo da rendere pi intuitiva linterpretazione del pseudo linguaggio. Il pseudolinguaggio del corso. Adotteremo un pseudo linguaggio di tipo imperativo in quanto il paradigma di programmazione tradizionale, le sue strutture semantiche sono presenti anche in altri linguaggi basati su paradigmi diversi, alla base del linguaggio C che uno dei pi diffusi. Il paradigma di programmazione uno stile fondamentale di programmazione, ovvero un insieme di strumenti concettuali forniti da un linguaggio di programmazione per la stesura di programmi, e definisce/determina il modo in cui il programmatore concepisce e percepisce il programma. 22

Definiremo il nostro pseudolinguaggio con riferimento ad un esecutore meccanico astratto, cio un calcolatore semplificato basato sullarchitettura di von Neumann. Il nostro esecutore sar composto da: una memoria suddivisa in celle che possono contenere un dato ciascuna e sono identificate da un nome simbolico; una periferica di ingresso e una di uscita; una unit di elaborazione in grado di eseguire semplici operazioni logico-aritmetiche, modificare i valori delle celle di memoria e inviare o ricevere dati dalle periferiche. Le istruzioni che lesecutore pu eseguire sono: di assegnamento, di lettura scrittura o I/O, composte. Queste ultime si dividono a loro volta in istruzione condizionale e istruzione iterativa. Le istruzioni di assegnamento consentono di assegnare un valore in una cella di memoria. Queste vengono anche chiamate variabili in quanto il valore assegnatogli pu essere modificato durante lesecuzione dellalgoritmo dalle istruzioni di assegnamento. Il valore un risultato di unespressione composta da: un valore costante, un valore contenuto in una cella di memoria ed il risultato di unoperazione aritmetica i cui operandi siano valori costanti o contenuti in altre celle di memoria. La sintassi assegna il valore alla variabile, se questo risultato un valore numerico si possono usare cinque operazioni aritmetiche binarie: somma, sottrazione, moltiplicazione, divisione, resto della divisione (mod). Come per le espressioni matematiche con le parentesi vengono indicate le precedenze. Se la variabile un carattere bisogna segnarlo indicarlo tra apici singoli (per esempio:a). La semantica, invece, prima calcola il valore delle espressioni poi lo memorizza nella cella sostituendo il valore precedente. Degli esempi di istruzioni di assegnamento: n 12 assegna alla variabile n il valore 12 media (x+y)/2 assegna a media la somma dei valori contenuti nelle variabili x e y diviso 2 resto 5mod2 assegna a resto il resto della divisione intera tra 5 e 2 n n+1 somma il valore contenuto in n con 1 e assegna il risultato ad n sostituendo il vecchio valore Le istruzioni di I/O servono per fornire al programmatore delle modalit di acquisizione dei dati (ingresso) e di presentazione dei risultati (uscita). I comandi sono: read (permette di leggere un valore dalla periferica di ingresso e lo memorizza nella cella), print (invia il valore alla periferica di uscita). I possibili esempi di istruzioni di I/O sono: read (m) legge un valore dalla periferica di ingresso e lo assegna alla variabile m print (5) stampa il valore 5 print (w) stampa il carattere w print (ciao) stampa la sequenza di caratteri ciao (devono racchiudersi tra doppi apici) print (x) stampa il valore contenuto nella variabile x print ((x+2)*z)stampa il valore dellespressione (x + 2) * z Le istruzioni composte come detto si dividono in condizionali (cicli a condizione iniziale) e iterative (cicli a condizione finale); le prime indicano che una data sequenza di istruzioni deve essere eseguite sole se vi una particolare condizione controllata prima di eseguire le istruzioni, le seconde invece indicano che una data sequenza deve essere eseguita ciclicamente fin quando non si realizza una determinata condizione quindi il controllo della condizione avviene dopo aver eseguito le istruzioni. Vengono chiamate composte perch al loro interno contengono delle altre istruzioni che, a loro volta, possono essere semplici o composte. if (se) unistruzione condizionale. Se scriviamo: if (condizione) {istruzioni} chiediamo di eseguire le istruzioni se condizione vera altrimenti non eseguire nessuna operazione if (condizione) {istruzioni1} else {istruzioni2} se condizione vera esegui istruzioni1 altrimenti (else) esegui istruzioni2 Condizione unespressione logica che pu essere vera o falsa, elementare o composta. Condizione elementare confronta i valori di due espressioni per mezzo degli operatori: =, , <, >, , , se le espressioni sono caratteri alfabetici entrambi maiuscoli o minuscoli gli operatori si riferiscono allordine alfabetico. La condizione composta una combinazione di pi condizioni 23

elementari per mezzo degli operatori and (e), or (o), not (non). Alcuni esempi di condizioni elementari sono: x=3 vera se il valore memorizzato nella variabile x 3 a b vera se il valore memorizzato nella variabile a maggiore o uguale a quello della variabile b (x+2)*z < y vera se il valore dellespressione (x + 2) * z maggiore del valore memorizzato nella variabile y b > g vera se il carattere memorizzato in b segue g in ordine alfabetico Alcuni esempi di condizioni composte sono: (c1 and c2) vera se c1 e c2 sono vere (c1 or c2) vera se c1 o c2 sono vere, cio se almeno una vera (not c1) vera se c1 falsa Considerando che c1 e c2 possono essere a loro volta condizioni sia elementari che composte: (x = 1) and (y > 0) vera se x uguale ad 1 e y maggiore di 0 (a = 1) or ((b+2) c > 0) vera se a uguale ad 1 o (b + 2) * c maggiore di 0 not (c = v) vera se il carattere memorizzato in c non segue v in ordine alfabetico ((x=1) or (y>0)) and (z = 0) vera se x uguale a 1 o y maggiore di 0 e z uguale a 0 Quindi ora possiamo scrivere alcuni esempi di istruzioni condizionali: if (x = 0) {y 1} se il valore di x 0 assegna ad y il valore 1 if ((x = 1) and (y > 0)) { m1 n3 se il valore di x uno e quello di y maggiore di 0 dai ad m il valore 1 } ed a n il valore 3 if (z>0) {y1) else (yo} se il valore di z maggior di 0 dai ad y il valore 1 altrimenti dagli 0 Stiamo dando delle istruzioni iterative se scriviamo: while (condizione) do {istruzioni} se condizione falsa non fare niente, se invece vera esegui le istruzioni e alla fine valuta di nuovo la condizione, se ancora vera esegui le istruzioni, se falsa non fare niente e cos via Il ciclo, durante le istruzioni iterative, viene quindi ripetuto fin quando la condizione vera, l'istruzione while quindi viene usata quando uno o pi comandi devono essere ripetuti ciclicamente fino a quando una certa condizione non risulta falsa. Ora facciamo alcuni esempi: while (x > 0) do { print (x) finch (while) il valore di x maggiore di 0 devi (do) stampalo (print), xx1 calcolare il valore di x 1 e memorizzarlo in x. Quindi questo procedimento } continua fino a quando x diventa uguale a 0 while (y z) do { yzx xx*3 finch il valore di y diverso da quello di z devi calcolare il valore di z x, } memorizzandolo in y, e quello di x * 3, memorizzandolo in x Esecuzione algoritmi. Lesecuzione di un algoritmo un processo dinamico, il cui stato caratterizzato in ogni istante dal valore di ciascuna variabile e dalla prossima istruzione da eseguire. Gli algoritmi sono rappresentati come una sequenza di istruzioni che vanno eseguite nellordine un cui sono elencate. I dati di partenza devono essere letti e memorizzati in variabili per poter essere, per mezzo delle istruzioni disponibili, manipolati ed ottenere cos il risultato desiderato. Prima di poter eseguire le istruzioni di un algoritmo si dovranno dichiarare i nomi di tutte le variabili interessate dallalgoritmo stesso e il tipo di dati che copntengono (numeri, caratteri, ecc) 24

con la convenzione che una variabile conterr dati di un unico tipo durante lesecuzione dellalgoritmo. Cos facendo il compilatore in grado di verificare eventuali errori semantici allinterno di un programma sintatticamente corretto. Ora facciamo alcuni esempi di algoritmi partendo da uno che legga due numeri e stampi il maggiore: variabili: x, y, z memorizzano numeri reali (interi o reali) read (x) read (y) if (x > y) {z x} else {z y} print (z) Come gi detto un qualsiasi problema pu essere risolto da pi algoritmi: read (x) read (y) if (x > y) {print (x)} else {print (y)} Esempio di lettura di tre numeri e stampa del maggiore: variabili: x, y, z memorizzano numeri reali (interi o reali) read x read y read z if (x y and x z) {print (x)} if (y x) { if (y z) {print (y)} else {print (z)} } Esempio di lettura di una successione di numeri fino a trovarne uno uguale a 0; in tal caso stampa la parola fine (esempio di istruzione iterativa): variabili: dato memorizza un numero (intero o reale) read (dato) while (dato 0) do {read (dato)} print (fine) Il valore letto dallistruzione read ad ogni iterazione dellistruzione while-do viene memorizzato sempre nella stessa variabile dato sostituendo il valore precedentemente memorizzato in essa. Esempio di lettura di una successione di numeri e di somma fino a trovarne uno uguale a zero; in tal caso stampa il valore della somma e termina: variabili: somma e numero somma 0 read (numero) while (numero 0) do {somma somma + numero read (numero)} print (somma) Con il nostro pseudolinguaggio, secondo il teorema di Bhm-Jacopini, possiamo rappresentare qualsiasi algoritmo. Questo teorema afferma che qualunque algoritmo pu essere implementato utilizzando tre sole strutture: la sequenza, la selezione ed il ciclo; da applicare ricorsivamente alla composizione di istruzioni elementari. La sequenza la normale elencazione di istruzioni perch vengano eseguite una di seguito all'altra nell'ordine in cui sono state scritte dal programmatore. La selezione la scelta fra due percorsi da seguire successivamente, che dipende da una condizione che pu essere vera o falsa. Il ciclo, detto anche iterazione, un blocco di istruzioni che vengono ripetutamente eseguite fino a che una certa condizione cambia di stato. Per questo motivo queste istruzioni sono comuni alla maggior parte dei linguaggi di alto livello. Rappresentazione degli algoritmi mediante i diagrammi di flusso o diagrammi a blocchi. Una metodologia utilizzata comunemente per descrivere gli algoritmi fa uso di un linguaggio formale grafico detto diagrammi di flusso o diagrammi a blocchi. 25

I blocchi sono connessi tramite frecce, il cui orientamento indica la successione delle azioni da eseguire. Queste ultime sono indicate dentro i blocchi. Questo linguaggio stato soppiantato negli anni 70 da quello testuale, questo perch rende difficile la comprensione della struttura degli algoritmi complessi. Oggi utilizzato solo per rappresentare algoritmi a basso livello di dettaglio. Gli array. In molti problemi linformazione da elaborare aggregata in componenti costituiti da informazioni pi semplici, per esempio i dati anagrafici di una persona (nome, cognome, ecc). Nella formulazione di algoritmi utile poter usare variabili strutturate che memorizzano informazioni composte. Il caso pi semplice uninformazione composta da una sequenza ordinata di valori omogenei. Informazioni di questo tipo sono rappresentate mediante le variabili array. Un array un tipo di dato strutturato, cio non elementare, usato in tutti i linguaggi di alto livello. Esso consente di definire nuovi tipi di dati a partire da tipi preesistenti. Un array e un insieme di dati memorizzati in locazioni di memoria consecutive. caratterizzato da: un nome, il numero dei suoi elementi (detto dimensione), il tipo dei suoi elementi (numeri, caratteri, ecc). Larray, in altre parole, si pu immaginare come una sorta di casellario, le cui caselle sono dette celle dell'array stesso e ciascuna delle quali si comporta come una variabile tradizionale. Ciascuna delle celle dell'array identificata da un valore di indice. L'indice generalmente numerico e i valori che gli indici possono assumere sono numeri interi contigui che partono da 0 o da 1. Per rappresentare un array quindi dobbiamo considerare che: sar costituito da una sequenza ordinata di valori omogenei ciascuno contenuto in una cella di memoria diversa; lintero array sar indicato con un nome simbolico come le normali variabili; ad ogni elemento di array sar associato un indice corrispondente al proprio numero dordine allinterno della sequenza; ogni singolo elemento di un array si indicher con la sintassi nome [indice] dove nome il nome simbolico dellarray e indice lindice dellelemento; la dimensione dellarray deve essere nota quando si scrive lalgoritmo. Esempio di array di nome numeri composto da 4 elementi:

se voglio indicare lelemento 2 devo scrivere: numeri[2] Sulle array possono essere eseguite tutte le operazioni previste sulle variabili, quindi i singoli elementi di un array possono essere usati in un algoritmo come variabili semplici. Prendendo come esempio un array di nome numeri composto da 4 elementi possiamo eseguire: operazioni di assegnamento (esempio: numeri[2] 0; numeri[1] (numeri[2] + 5) * numeri[3] + m); espressioni condizionali (esempio: if (numeri[3] < 0) {} else {}); operazioni di lettura/scrittura (esempio: read (numeri[1]) print (numeri[2])). Non per possibile eseguire operazioni su unintera variabile array, cio possiamo eseguire operazioni solo sui singoli elementi di una variabile array. Per esempio se abbiamo due array (numeri e vettori) per copiare gli elementi di una nellaltra non possiamo scrivere numeri vettori, anche se hanno la stessa dimensione ed elementi dello stesso tipo. Lindice di un array pu essere denotato anche come risultato di unespressione di valore intero definita come per listruzione di assegnamento. Unespressione pu riferirsi al contenuto di una o pi variabili: in questo caso il valore dellindice 26

dellarray sar calcolato durante lesecuzione dellalgoritmo. Facciamo alcuni esempi prendendo due array chiamate a e b, e due variabili chiamate m e n di valore 3 e 5: a[m] 0 essendo m=3 come se scrivessi a[3] 0 quindi sto assegnando al terzo elemento di a il valore 0 a[m] a[m+1] sto assegnando al terzo elemento di a il valore del quarto elemento di a, e come se scrivessi a[3] a[3+1] a[m] b[m+n] d al terzo elemento di a il valore dellottavo elemento di b (a[3]b[3+5]) Se un array composto da numeri interi il valore del suo elemento pu essere usato come indice di un altro array. Per esempio: v un array di numeri interi, v[3] contiene il valore 5, a un altro array a[v[3]] sto indicando il quinto elemento dellarray a Facciamo ora alcuni esempi e alcune considerazioni su algoritmi in cui si usano e non si usano array. Esempio di lettura di una sequenza di numeri interi e stampa degli stessi numeri in ordine inverso a quello di lettura senza usare un array: variabili: a, b, c memorizzano numeri interi read (a) read (b) read (c) print (c) print (b) print (a) Questa soluzione sarebbe applicabile solo se la lunghezza della sequenza fosse nota al momento della formulazione dellalgoritmo, cio bisogna sapere quante variabili sono presenti, in altro caso questa soluzione non sarebbe attuabile. Altro problema di questa soluzione la lunghezza, infatti se la sequenza contenesse 100 numeri bisognerebbe usare 100 variabili diverse e scrivere 200 istruzioni di I/O. Per ovviare a questi problemi vengono utilizzate le array capaci di memorizzare la sequenza di numeri interi. Riconsideriamo il caso di prima con una sequenza nota di valore 100: variabili: n: numeri interi v: array di 100 numeri interi n1 while (n 100) do { read(v[n]) nn+1 } while (n > 0) do { n n1 print (v[n]) } Consideriamo ora il caso in cui si conosca solo la massima lunghezza possibile della sequenza (1000), mentre la lunghezza effettiva si sapr solo al momento dellesecuzione dellalgoritmo e dobbiamo sempre leggere in un ordine e stampare in ordine inverso: variabili: m e n: numeri interi v: array di 1000 numeri interi read (m) n1 while (n m) do { read(v[n]) 27

n n+1 } while (n > 0) do { nn1 print (v[n]) } Esempio per copiare i valori degli elementi di un array negli elementi di un array della stessa dimensione e dello stesso tipo, ricordandoci che non possibile eseguire operazioni su unintera array (quindi non posso scrivere ab): variabili: n: numeri interi a e b: array di 100 elementi dello stesso tipo while (n 100) do { a[n]b[n] nn+1 } Metodi di risoluzione degli algoritmi. In matematica si dimostrato che non esiste un procedimento generale di risoluzione di problemi che sia esso stesso un algoritmo; infatti, se esistesse, tutti i problemi matematici potrebbero essere risolti da un calcolatore. Un possibile approccio alla formulazione di un algoritmo per la risoluzione di un dato problema consiste per prima cosa nel capire il problema considerando quali sono i dati di partenza e il risultato desiderato. Poi ci si deve fare unidea di come un algoritmo lo possa risolvere considerando che possono esistere pi algoritmi per risolvere un problema. Dopo essersi fatti unidea si formula con precisione un algoritmo, anche in linguaggio naturale, e lo si codifica in un linguaggio di programmazione. Infine si deve valutare la correttezza di un algoritmo e la possibilit che possa essere usato per risolvere altri problemi. Ovviamente questo non il metodo da seguire per risolvere tutti gli algoritmi, deve essere considerato come unidea, una linea guida, in quanto le fasi descritte non devono essere necessariamente svolte sequenza, questo perch molte volte si giunge alla soluzione di un problema andando a tentativi e quindi tornando spesso sui propri passi e un problema, talvolta, viene realmente compreso solo quando si cerca un procedimento per risolverlo. Un altro approccio consiste nel cercare un problema simile ma pi semplice da risolvere o gi risolto, che possa essere visto come un caso particolare del problema considerato, e tentare di costruire la soluzione di tale problema generalizzando quella del problema pi semplice. Ancora un esempio pu essere quello di scomporre un problema complesso in sottoproblemi pi semplici da risolvere, i quali a loro volta possono essere scomposti in sottoproblemi ancora pi semplici e cos via. Questo approccio chiamato top-down. Questi ultimi due approcci sono molto utili in informati e vengono spesso utilizzati. Esempi di formulazione di algoritmi. Trovare il massimo di una sequenza di numeri interi di lunghezza arbitraria (si conoscer la lunghezza solo quando lalgoritmo sar eseguito). Ci stanno chiedendo il numero pi grande presente nella sequenza dandoci come dati di partenza la lunghezza della sequenza e i suoi elementi. Una soluzione pu essere quella di leggere uno alla volta i numeri della sequenza tenendo traccia del numero pi grande tra quelli gi letti. Ora la lunghezza della sequenza viene memorizzata nella variabile m, i numeri della sequenza vengono memorizzati uno alla volta in n, il numero pi grande viene memorizzato in max e per contare i numeri da leggere si usa la variabile i. variabili: m, n, i, max, memorizzano numeri interi 28

read (m) read (n) max n i1 while (i < max) do {read (n) if (n > max) then {max n} i i+1} print max Finch i<max devi leggere n, se n>max allora assegna a max il valore di n, assegna a i il valore i+1 Determinare le cifre della rappresentazione in base due di un dato numero intero. Dati partenza: un numero intero; risultato: la sequenza di cifre della sua rappresentazione in base 2. Un possibile procedimento quello delle divisioni successive per 2. Il valore del numero da rappresentare viene memorizzato nella variabile n, che verr successivamente usata per memorizzare i quozienti delle divisioni per 2, ad ogni passo il resto della divisione per 2 viene memorizzato in r e stampato. variabili: m, n, i e max memorizzano numeri interi read (n) if (n = 0) then {print (0)} else { while (n > 0) do { r n mod 2 print (r) n n/2 } } Determinare il massimo comun divisore tra 2 numeri naturali. Dati di partenza: due numeri naturali; risultato desiderato: il loro MCD Il MCD il pi grande numero intero che sia divisore di entrambi i numeri, quindi possiamo prendere in considerazione tutti i numeri tra 1 e il pi piccolo tra m ed n, tenendo traccia dellultimo numero tra quelli gi considerati che sia divisore sia di m che di n. I due numeri vengono memorizzati nelle variabili m ed n, i numeri da 1 al pi piccolo tra m ed n vengono memorizzati nella variabile d, il pi grande divisore di m ed n tra quelli gi considerati viene memorizzato nella variabile mcd, per determinare se un numero divisore dellaltro si usa loperatore mod. Variabili: m, n, i, e mcd memorizzano numeri interi read (m) read (n) d1 while (d m and d n) do { if ((m mod d = 0) and (n mod d = 0)) then {mcd d} d d+1 } print (mcd) Una soluzione alternativa a questo problema nota con il nome di algoritmo di Euclide e si basa su una propriet secondo la quale: se m = n il MCD(m,n) = m = n se m > n il MCD(m,n) = MCD (m-n,n) se m < n il MCD(m,n) = MCD (m,n-m) Prendiamo lesempio m > n, se indichiamo con s il valore m-n otteniamo: MCD(m,n) = MCD(m-n,n) = MCD(s,n) Applicando lo stesso ragionamento di prima si ottiene: se s = n il MCD(s,n) = s = n se s > n il MCD(s,n) = MCD(s-n,n) se s < n il MCD(s,n) = MCD (s,n-s) 29

Continuando questo ragionamento si otterranno due numeri identici e quindi il MCD cercato. In altre parole questo procedimento calcola il MCD controllando se i numeri sono uguali, se si quei numeri sono il MCD, in caso contrario si sostituisce il numero maggiore con la differenza tra esso e il minore, si controlla se i due numeri sono uguali e cos via ciclicamente. read (m) read (n) while (m n) do {if (m > n) then {m m-n} else {n n-m}} print (m) Determinare se un dato numero naturale sia primo. Un numero primo se non ha altri divisori a parte 1 e se stesso quindi un possibile procedimento consiste nel considerare tutti i numeri tra 2 e n/2 (non pu avere divisori oltre la sua met, per esempio 20 non ha divisori oltre il 10) e verificare se almeno uno di essi sia divisore di n. Lesito sar stampato sotto forma di messaggio, il numero da analizzare viene memorizzato in n, i numeri da 2 a n/2 vengono memorizzati in d, la variabile primo viene usata per tener traccia del fatto che siano trovati divisori n. variabili: n, d e primo memorizzano numeri interi read (n) d2 primo 0 while (d n/2) do {if (n mod d = 0) then {primo 1} d d+1} if (primo = 1) then {print (non primo)} else {print (primo)} Determinare la parte intera della radice quadrata di un dato numero reale non negativo. Un procedimento si basa sullosservazione che la parte intera della radice quadrata di x il pi grande numero intero r tale che r2 x. Per trovare tale numero sufficiente considerare gli interi 0, 1, 2, ecc fino a trovarne uno il cui quadrato sia maggiore di x: il risultato cercato allora il numero che precede lultimo considerato. Il numero in cui si deve calcolare la parte intera della radice quadrata viene memorizzato nella variabile x, i numeri da considerare come possibili radici intere vengono memorizzati nella variabile r, al termine dellistruzione il valore r maggiore di una unit rispetto al risultato desiderato. variabili: x memorizza numeri reali, r memorizza numeri interi read (x) r0 while (r*r x) do {r r+1} print (r-1) Determinare se un dato numero intero sia presente in una sequenza di numeri ordinati in senso crescente. Tenendo conto dellordinamento dei numeri della sequenza, una semplice soluzione consiste nello scorrere tali numeri finch se ne trova uno uguale o maggiore a quello cercato oppure fin quando non si esaurisce la sequenza. Dobbiamo poi sapere se la lunghezza della sequenza nota a priori (usiamo un array) oppure no e fa parte dei dati di ingresso. Consideriamo il caso in cui non conosciamo la lunghezza della sequenza: il numero da cercare viene memorizzato nella variabile c, la lunghezza della sequenza nella variabile m, i suoi elementi (uno alla volta) nella variabile n, la variabile i viene usata per contare gli elementi gi letti. Se lelemento cercato fa parte della sequenza otterremo n = c. variabili: c, m,n, i memorizzano numeri interi read (c) read (m) read (n) i1 while (i < m and n < c) do {read (n) i i+1} if (n = c) then {print (trovato)} else {print (non trovato}

30

Consideriamo ora il caso in cui la lunghezza della sequenza sia nota e sia uguale a 100 ma non si voglia usare una variabile array. variabili: c, n, i memorizzano numeri interi read (c) read (n) i1 while (i < 100 and n < c) do {read (n) i i+1} if (n = c) then {print (trovato)} else {print (non trovato} Consideriamo ora il caso in cui la lunghezza della sequenza sia nota e sia uguale a 100 e si voglia usare una variabile array. variabili: c, n, i memorizzano numeri interi; s un array di 100 numeri interi read (c) i1 while (i 100) do {read (s[1]) i i+1} i1 while (i 100 and s[i] < c) do {i i+1} if (s[i] = c) then {print (trovato)} else {print (non trovato} Ordinare, in senso crescente o decrescente, una sequenza di numeri di lunghezza nota. Tra i diversi algoritmi di ordinamento esistenti consideriamo il selection sort che, per ordinare una sequenza in ordine crescente/decrescente, scambia lelemento pi piccolo/grande con il primo della sequenza e riapplica lo stesso procedimento agli elementi successivi al primo. Utilizziamo lapproccio top-down e descriviamo lalgoritmo prima in linguaggio naturale. Data una sequenza di almeno due elementi dobbiamo: cercare lelemento pi piccolo/grande; scambiare questo elemento con il primo della sequenza; se la sequenza contiene pi di due numeri riapplicare il procedimento alla sequenza meno il primo elemento. Ora descriviamo lalgoritmo usando il nostro pseudolinguaggio e un array: while (la sequenza desiderata che contiene pi di un elemento) do { cercare lelemento pi piccolo/grande; scambiare tale elemento con il primo della sequenza; considerare la sequenza meno il primo elemento} stampare gli elementi della sequenza ordinata Individuiamo tre sottoproblemi: leggere/scrivere gli elementi della sequenza, cercare lelemento pi piccolo/grande di una sequenza, scambiare due elementi di una sequenza. Il primo problema consiste nel leggere gli elementi della sequenza tramite un array di 100 elementi: i 1 while (i 100) do {read (s[i]) i i+1} Per il secondo sottoproblema scorriamo gli elementi della sequenza e teniamo traccia dellindice del pi piccolo tra quelli gi considerati: min 1 i2 while (i 100) do {if (s[i] < s[min]) then {min i} i i+1} Per il terzo sottoproblema assumiamo gli indici come memorizzati nelle variabili a e b, utilizziamo anche unaltra variabile (temp) per evitare che vadano persi i valori: temp s[a] s[a] s[b] s[b] temp adesso uniamo lalgoritmo considerando che ci sar una modifica dovuta alla realizzazione dellistruzione informalmente come considerata la sequenza meno il primo elemento, che si trova allinterno di unistruzione while-do. Si user una variabile (chiamata i dellalgoritmo) per memorizzare lindice del primo elemento della sottosequenza considerata ad ogni iterazione, questo implica che nella ricerca del minimo di una sotto sequenza si dovranno scorrere i suoi elementi a partire da quello di indice i+1. 31

variabili: i, j min, temp memorizzano numeri interi; s un array di 100 numeri interi i1 while (i 100) do {read (s[i]) i i+1} i1 while (i 100) do {min1 ji+1 while (j 100) do {if (s[j] < s[min]) then {minj} jj+1} if (min i) then {temps[i] s[i]s[min] s[min]temp} ii+1} i1 while (i 100) do {print (s[i]) ii+1} Correttezza ed efficienza degli algoritmi. Creato un algoritmo ci si pone il dubbio di verificare se quellalgoritmo corretto per quel problema. Un algoritmo si dice corretto se, per ogni istanza del problema, termina in un numero finito di passi e fornisce la soluzione desiderata. Non esiste una procedura generale per verificare la correttezza di un algoritmo in quanto questa unarea di ricerca molto attiva dellinformatica. Una soluzione semplice potrebbe essere quella di seguire lalgoritmo per tutte le istanze del problema. Sfortunatamente questa una soluzione impossibile da applicare in quanto il numero delle istanze pu essere infinito, infatti, ci sono istanze per cui lalgoritmo non termina. Considerando algoritmi come quelli che trattiamo noi, cio abbastanza semplici, possiamo procedere ragionando per ogni singolo caso. Alcuni approcci possono essere quello di cercare di capire quale la logica seguita dallalgoritmo per risolvere il problema considerato oppure, un altro approccio, individuare le istanze del problema che potrebbero costituire casi particolari e verificare se sono trattate in modo corretto. Facciamo alcuni esempi. Questo algoritmo deve verificare se i numeri memorizzati nellarray v (composto da 5 elementi) sono ordinati in senso non decrescente stampando 1 in caso affermativo o 0 in caso negativo. i1 while (i 5) do { if (v[i] v[i+1]) then {risposta 1) else {risposta 0} i i+1} print (risposta) Questo algoritmo non corretto poich il risultato dipender solo dallordinamento dellultima coppia di numeri, quindi, se la sequenza 5 4 3 1 2, stamper 1 invece che 0. Questo algoritmo deve stampare il numero di copie di elementi distinti di v la cui somma sia pari al valore di n. v un array di 10 numeri interi e n memorizza i numeri interi. s0 i1 while (i < 10) do { if (v[i] + v[i+1] = n) then {s s+1 i i+1} print (s) Questo algoritmo non corretto perch non esamina tutte le coppie di numeri ma solo quelle adiacenti. Possiamo scriverlo correttamente cos: s0 i1 while (i < 10) do { j i+1 while (j 10) do { if (v[i] + v[j] = n) then {s s+1} j j+1} i i+1} print (s)

32

Un algoritmo pi efficiente di un altro quando, per risolvere uno stesso problema, richiede un numero inferiore di passi (quindi pi veloce, cio meno tempo di calcolo) oppure quando usa una minore quantit di risorse (quindi un numero di celle di memoria inferiore). Una misura comune dell'efficienza di un algoritmo la sua complessit temporale, definita come il tempo necessario per risolvere un dato problema, e la sua complessit spaziale, definita come la quantit di memoria richiesta dallalgoritmo. Solitamente il tempo viene privilegiato rispetto allo spazio in quanto una risorsa non riutilizzabile. In genere la complessit di un algoritmo dipende dalla particolare istanza di un problema, per esempio istanze diverse, a parit di dimensione, potrebbero richiedere risorse diverse. Gli algoritmi vengono classificati in base ai valori di complessit valutati in tre casi differenti: il caso migliore (best case) corrisponde alle istanze per le quali la complessit e la pi bassa, cio le istanze di ingresso che comportano meno lavoro per lalgoritmo, cio i dati che richiedono meno elaborazioni per essere trattati. il caso medio (average case) il valore medio (in senso statistico) della complessit rispetto a tutte le possibili istanze, cio le istanze di ingresso tipiche per il problema, richiede di conoscere una distribuzione di probabilit sulle istanze; il caso peggiore (worst case) corrisponde alle istanze per le quali la complessit la pi alta, cio le istanze di ingresso che comportano pi lavoro per lalgoritmo (quelle che richiedono il maggior numero di passi), il caso che bisogna considerare nella valutazione dellalgoritmo. La complessit di un algoritmo dipende da due fattori: il valore dei dati di ingresso (per esempio il numero di operazioni richieste dallalgoritmo di Euclide per calcolare il MCD tra due numeri dipende dei loro valori) e la dimensione dei dati di ingresso (per esempio il numero di operazioni richieste dallalgoritmo selection sort per ordinare una sequenza di numeri dipende dalla lunghezza della sequenza. Per misurare l'efficienza di un algoritmo in maniera univoca, bisogna definire una metrica che sia indipendente dalle tecnologie utilizzate, altrimenti uno stesso algoritmo potrebbe avere efficienza diversa a seconda della tecnologia sulla quale viene eseguito. Per unit di misura si considera il numero di operazioni richieste dallalgoritmo. Le operazioni generalmente considerate sono quelle logico-aritmetiche e la valutazione pu essere approssimata in quanto si tiene conto del tipo di operazione predominante in un dato algoritmo. Se prendiamo come esempio il calcolo del minimo comun denominatore tra due numeri m ed n un possibile algoritmo potrebbe scandire tutti i numeri tra max{m,n} e m*n, fermandosi quando trova un multiplo di m e n. Nel caso peggiore il mcm proprio m*n, questo richiede lesame di m*n-max{m,n}+1 numeri. La complessit temporale quindi proporzionale a m*n-max{m,n}+1. Questo un esempio di dipendenza della complessit dai valori. Lalgoritmo pu essere pi efficiente osservando che, poich si cerca un multiplo comune, sufficiente considerare solo i multipli di max{m,n} nellintervallo indicato quindi, supponendo m>n: 1m, 2m, , n*m. nel caso peggiore saranno quindi esaminati solo min{m,n} numeri invece che m*n-max{m,n}+1. Problemi intrattabili. La complessit di un algoritmo pu essere determinante per distinguere problemi la cui soluzione nota solo in teoria e quelli dove pu essere ottenuta anche in concreto. Il metodo forza bruta un algoritmo di risoluzione di un problema che consiste nel verificare tutte le soluzioni teoricamente possibili fino a che si trova quella effettivamente corretta. Spesso questi problemi sono irrisolvibili anche con calcolatori molto veloci. Al crescere delle dimensioni del problema, infatti, la complessit di un qualsiasi algoritmo basato sulla forza bruta supera la capacita di qualsiasi calcolatore esistente e anche futuro se basato sulla tecnologia attuale. Questo sistema viene utilizzato soprattutto in crittoanalisi, per ottenere il significato di informazioni cifrate senza avere accesso all'informazione segreta che di solito richiesta per 33

effettuare l'operazione, e nellambito della sicurezza informatica, per trovare la password di accesso ad un sistema. Uno dei casi di studio tipici della teoria della complessit il problema del commesso viaggiatore (traveling salesman problem). Il nome nasce dalla sua pi tipica rappresentazione: data una rete di citt, connesse tramite delle strade, trovare il percorso di minore distanza che un commesso viaggiatore deve seguire per visitare tutte le citt una sola volta, partendo dalla citt x e tornando nella stessa citt. Non esistono algoritmi efficienti per la risoluzione di questo problema, l'unico metodo di risoluzione rappresentato dall'enumerazione totale, ovvero nell'elaborazione di tutti i possibili cammini per scegliere poi quello pi breve. Tuttavia, la complessit dell'operazione la rende impraticabile, infatti, considerando che ogni citt sia collegata direttamente a ciascuna altra citt, abbiamo che i percorsi sono: n! = n * (n-1) * (n-2) * * 2. Il risultato, se in numero delle citt 10, 362800 percorsi possibili, se le citt sono 50 avremo circa 1081 percorsi. Per rendersi conto delle dimensioni basta pensare che il numero stimato di atomi nelluniverso circa 1080. Per problemi con queste caratteristiche possiamo progettare algoritmi euristici, cio algoritmi la cui soluzione non ottima per quel problema ma probabilmente buona, oppure trovare un caso specifico del problema (un sottoproblema) per il quale sia possibile o una soluzione esatta o uneuristica migliore. Sottoprogrammi. Per facilitare la formulazione di un algoritmo spesso conveniente suddividerlo in pi parti, ciascuna di queste parti risolve un sottoproblema pi semplice rispetto al problema originario. Nei linguaggi di programmazione di alto livello questa suddivisione si riflette nella possibilit di scomporre un problema in un problema principale e uno o pi sottoprogrammi. Un sottoprogramma una particolare unit di codice che non pu essere eseguita autonomamente, ma soltanto su richiesta del programma principale o di un altro sottoprogramma. Questo ha lo scopo di eseguire una data operazione su un dato insieme di valori di ingresso, detti argomenti del sottoprogramma; viene cio realizzato per svolgere un compito specifico (leggere o stampare gli elementi di un array, calcolare il valore di una particolare funzione matematica, ecc.) per il quale implementa un opportuno algoritmo. Lesecuzione di un programma inizia sempre dal programma principale, il quale pu chiamare un sottoprogramma per ottenere lesecuzione delloperazione corrispondente, questo sottoprogramma pu essere attivato pi volte in uno stesso programma o anche utilizzato da un programma diverso da quello per cui era stato inizialmente progettato. I vantaggi dei sottoprogrammi sono: evitano la ripetizione delle istruzioni in quanto il sottoprogramma pu essere richiamato pi volte, possono essere riusati in programmi che necessitano la stessa operazione, sono disponibili sottoprogrammi prefabbricati. Un sottoprogramma caratterizzato da: un nome attraverso il quale potr essere chiamato dal programma principale o da un sottoprogramma; da un insieme di parametri corrispondenti a variabili nelle quali vengono memorizzati i valori di ingresso (gli argomenti) del sottoprogramma definiti al momento della chiamata. Lesecuzione delle istruzioni di un sottoprogramma provocata da una particolare istruzione del programma che lo attiva (istruzione di chiamata, per cui il programma detto chiamante) che determina la sospensione dellesecuzione delle istruzioni del programma chiamante. Il programma chiamante ed il sottoprogramma scambiano dati attraverso gli argomenti (lista di variabili) che, come detto, ospitano i dati di ingresso e di uscita del sottoprogramma. Con listruzione di chiamata, il programma chiamante fornisce al sottoprogramma una lista di parametri effettivi, costituiti dai valori effettivi di ingresso su cui il sottoprogramma deve operare e dalle variabili del programma chiamante in cui i valori di uscita del sottoprogramma dovranno essere memorizzati. Le istruzioni del sottoprogramma vengono eseguite fino ad incontrare listruzione ritorno che fa riprendere lesecuzione delle istruzioni del programma chiamante. 34

Per terminare lesecuzione di un sottoprogramma e indicare il valore da restituire al programma chiamante si usa unistruzione di ritorno: return espressione. Dove espressione definita come per listruzione di assegnamento. Listruzione return pu comparire in qualsiasi punto di un sottoprogramma, anche in pi punti e, in questo caso, il sottoprogramma termina non appena si incontra la prima istruzione return. Se un sottoprogramma non restituisce nessun valore listruzione return non dovr essere seguita da unespressione. Esempio di un programma principale che legge coppie di numeri interi (fino a che entrambi sono positivi) e ne stampa il massimo comun divisore per mezzo del sottoprogramma mcd: programma principale mcd (m,n) variabili: a, b: numeri interi restituisce un numero intero read (a) parametri: m, n: numeri interi read (b) while (m n) do { while (a > 0 and b > 0) do { if (m > n) then {m m-n} print (mcd(a,b)) else {n n-m} read (a) } read (b) return m } Esempio di un sottoprogramma che stampa gli elementi di un array di 10 numeri interi e non restituisce nessun valore: stampa (v) parametri: v: array du 10 numeri interi variabili: i: numeri interi i1 while (i 10) do { print (v[i]) i i+1 } return Linsieme delle variabili definite in un sottoprogramma pu dividersi in due insiemi: parametri formali, utilizzati per gestire il flusso di dati con il chiamante, e variabili locali, utilizzate per implementare lalgoritmo nel sottoprogramma (es. indici, variabili di appoggio, ecc). Linsieme di queste variabili viene definito ambiente del sottoprogramma mentre, linsieme delle variabili definite nel chiamante, costituisce lambiente del chiamante. Essendo due ambienti distinti le variabili del chiamante non sono visibili dal sottoprogramma e viceversa, nei due ambienti possono quindi esistere variabili con lo stesso nome senza rischio di ambiguit. Basi di dati. Il sistema informativo un componente fondamentale di ogni struttura organizzativa (ente, azienda, ecc). ha il compito di raccogliere, organizzare, conservare e recuperare le informazioni necessarie per il conseguimento degli scopi dellorganizzazione. I sistemi informativi (archivi anagrafici, bancari, ecc) precedono la nascita e la diffusione dei calcolatori elettronici. I sistemi informatici consentono di automatizzare i sistemi informativi. Organizzazione degli archivi. Lapproccio convenzionale allorganizzazione degli archivi fa s che i dati vengano memorizzati su diversi file da pi programmi indipendenti, usando gli strumenti messi a disposizione dal file system del SO. Questo sistema a diversi svantaggi in quanto si possono verificare problemi di: ridondanza (pi copie di uno stesso file si possono trovare in file diversi usati da programmi diversi; inconsistenza (copie diverse di uno stesso dato potrebbero non essere aggiornate); concorrenza (pi programmi potrebbero richiedere contemporaneamente laccesso ad uno stesso dato; integrit dei dati (i programmi che modificano i dati potrebbero non garantire il rispetto di 35

vincoli sui loro valori); privatezza (i SO non forniscono strumenti sufficienti per assegnare permessi di accesso diversi a parti diverse di uno stesso file). Il termine database o base di dati (BD) indica un archivio strutturato in modo tale da consentire la gestione dei dati (l'inserimento, la ricerca, la cancellazione ed il loro aggiornamento) da parte di applicazioni software. Informalmente ed impropriamente, la parola database viene spesso usata come abbreviazione dell'espressione Database Management System (DBMS), che si riferisce a una vasta categoria di sistemi software che consentono la creazione e la manipolazione efficiente di database. Il DBMS costituito da un insieme assai complesso di programmi software che controllano l'organizzazione, la memorizzazione e il reperimento dei dati in un database oltre a controllare la sicurezza e l'integrit del database stesso. Il DBMS accetta richieste di dati da parte del programma applicativo e istruisce il sistema operativo per il trasferimento dei dati appropriati. Il sistema di sicurezza dei dati impedisce agli utenti non autorizzati di visualizzare o aggiornare il database e mediante l'uso di password permesso agli utenti l'accesso all'intero database. I vincoli di integrit permettono di conservare l'integrit del database non consentendo a pi utenti di modificare lo stesso record (oggetto di database) contemporaneamente. I dati sono condivisi tra tutti gli utenti evitando cos la ridondanza e linconsistenza. Dei meccanismi di controllo della concorrenza garantiscono laccesso ai dati ad un solo utente alla volta (mutua esclusione) evitando tentativi di accessi contemporanei. Caratteristica fondamentale dellapproccio base di dati lastrazione dati: rendere, cio, trasparenti allutente finale i dettagli riguardanti gli aspetti logici e fisici della memorizzazione dei dati. Il modello dei dati lo strumento con cui vengono rappresentati i dati ai diversi livelli di astrazione. Larchitettura di un DBMS articolata su tre livelli di astrazione, ciascuno descritto da un proprio schema, dove lo schema descrive la struttura dei dati in base al modello dei dati utilizzato ed invariante nel tempo. I livelli di astrazione di un DBMS sono: livello fisico (descrizione della codifica dei dati nei supporti fisici di memorizzazione), livello logico (descrizione del database secondo un particolare modello), livello esterno (descrizione di una porzione del database). Larchitettura a tre livelli garantisce lindipendenza dei dati, propriet fondamentale dei DBMS consente agli utenti e ai programmi applicativi di interagire con la BD ad un elevato livello di astrazione. Lindipendenza logica consente di interagire con il livello esterno della base di dati in modo indipendente dal livello logico, quindi possibile modificare lo schema logico dei dati senza la necessit di dover modificare schemi esterni e di conseguenza i programmi applicativi. Lindipendenza fisica consente di interagire con il DBMS in modo indipendente dalla struttura fisica di memorizzazione dei dati, rende quindi possibile la modifica dello schema fisico dei dati senza la necessit di dover modificare lo schema logico. I DBMS comprendono i linguaggi dedicati allorganizzazione e alla gestione dei dati, questi linguaggi sono di due tipi e si distinguono secondo il loro utilizzo: i linguaggi per la definizione dei dati (DDL) consentono di definire la struttura della base di dati e le autorizzazioni per l'accesso, sono quindi usati per definire gli schemi esterni, logici e fisici e le autorizzazioni da rilasciare agli utenti per accedere ai dati; i linguaggi per la manipolazione dei dati (DML) consentono di formulare interrogazioni per estrarre dati da un BD e di aggiornare le istanze di una BD, ricordando che le istanze sono dei valori assunti dai dati in un determinato istante e sono le parti della BD variabile nel tempo. Per poter accedere ai dati ci sono diversi modi: mediante linguaggi testuali (ad esempio SQL il pi utilizzato); attraverso comandi speciali integrati nei linguaggi di programmazione (come il C) consentendo cos di includere comandi dei linguaggi DDL o DML per realizzare applicazioni che accedano ad una BD; tramite interfacce grafiche che evitano di usare comandi testuali (ad esempio Wizards). 36

Gli utenti che usufruiranno della base di dati sono: lamministratore che definisce attraverso il DDL lorganizzazione dei dati: schema esterno, logico e fisico, vincolo di integrit, autorizzazioni. Insomma progetta, controlla e amministra il database garantendo lefficienza del DBMS; il programma applicativo definisce e realizza i programmi che accedono alla BD per mezzo del DML; il terminalista che accede alla BD attraverso operazioni predefinite, spesso per mezzo di interfacce grafiche (ad esempio sono i funzionari di banca); lutente finale interagisce con la BD per mezzo di interfacce semplici (generalmente grafiche) per eseguire operazioni quali inserire, modificare o trovare le informazioni di interesse ed in generale operazioni pi limitate rispetto al terminalista (ad esempio utenti dello sportello bancomat). Modello relazionale dei dati. Il modello dei dati la descrizione ad alto livello dellorganizzazione e della struttura dei dati di una BD, indipendente dai dettagli della loro memorizzazione su dispositivi fisici. Il pi diffuso il modello relazionale. Il modello relazionale un modello logico di rappresentazione dei dati implementato su DBMS, detti perci RDBMS. Esso strutturato attorno al concetto di relazione, cio i dati vengono organizzati in relazioni e rappresentati per mezzo di tabelle. La tabella quindi la rappresentazione grafica normalmente accettata per rappresentare la relazione. La tabella individuata da un nome ed costituita da una testata e da un corpo, dove la testata un insieme di attributi (colonne della tabella) ed il corpo un numero variabile di tuple (righe della tabella). La testata di una tabella anche la testata di ciascuna delle sue tuple. Un attributo individuato da un nome univoco e pu assume valori appartenenti ad un dominio (un insieme di valori accettati). Un valore di attributo il valore di una cella identificata da una specifica coppia riga-colonna. Lo schema di una tabella non pu variare nel tempo ed costituito dal nome ed il dominio di ogni attributo e dal nome della tabella, listanza di una tabella, invece, pu variare nel tempo ed costituita dallinsieme delle tuple presenti nella tabella in un dato istante. Le corrispondenze tra i dati in tabelle diverse sono stabilite dai valori di attributi comuni a ciascuna tabella. Facciamo un esempio del modello relazionale con una BD contenente informazioni sugli insegnamenti di un corso di laurea: DOCENTI MANIFESTO CORSO DOCENTE Geometria Rossi Analisi 1 Neri Fisica 1 Verdi Analisi 2 Rossi MATERIA ANNO CREDITI Geometria 1 5 Analisi 1 1 5 Fisica 1 3 6 Analisi 2 2 4 La tabella docenti contiene la corrispondenza tra insegnamenti e docenti (un docente pu insegnare pi materie) mentre la tabella manifesto contiene informazioni su ciascun corso (crediti, anno, materia). I valori di attributi comuni alle due tabelle sono corso e materia. 37

Una chiave di tabella un insieme di attributi tali che nella tabella non possano esistere tuple con valori identici di tali attributi, cio un insieme di attributi che permettono di identificare in modo univoco l'elemento o tupla a cui appartengono. Per convenzione la chiave e sottolineata e questo vincolo viene posto come vincolo di integrit. In ogni tabella ci deve essere almeno una chiave, spesso ne basta una ma a volte ne servono di pi. In questo caso bisogna indicare quale sia la chiave primaria. Vincoli di integrit. Per evitare che i valori di un attributo, o di alcune combinazioni di valori di attributi, possano non essere corretti, i DBMS consentono di definire i vincoli di integrit sulle istanze di una base di dati. Un vincolo di integrit una propriet che deve essere soddisfatta dalle istanze di una base di dati. In generale, ad uno schema di base di dati si associano un insieme di vincoli e si considerano corrette le istanze che soddisfano tutti i vincoli. I vincoli vengono verificati ad ogni aggiornamento della base di dati, se non sono rispettati impediscono linserimento dei valori non corretti e non permettono laggiornamento. La chiave pu essere considerata un vincolo, in quanto due diverse righe non possono avere valori uguali. Un altro vincolo quello di tupla che pu essere valutato su ciascuna tupla indipendentemente dalle altre. Un vincolo definito con riferimento a singoli valori viene detto vincolo su valori o vincolo di dominio in quanto impone una restrizione sul dominio dell'attributo. I vincoli di integrit interrelazionari sono vincoli che definiscono il legame tra pi tabelle, il pi utilizzato e quello di integrit referenziale. Affinch le informazioni di due tabelle (T1 e T2) possano essere messe in relazione necessario che le tabelle abbiano in comune un insieme di attributi X, e che X sia chiave primaria di una delle tabelle (per esempio T2), quindi i valori degli attributi X di ciascuna tupla di T1 compaiono come valori della chiave primaria dellistanza di T2. Reti di calcolatori Internet. La nascita delle reti di calcolo risale al 1969, quando il Ministero della Difesa Statunitense crea ARPA unagenzia finanziata per creare una rete in grado di consentire il collegamento tra computer posti in localit diverse. A cavallo tra gli anni 80 e 90 si diffondono in larga scala le LAN (local area network) costituite da gruppi di calcolatori distribuiti su unarea limitata collegati tra loro mediante cavi e schede di rete. Gradualmente le reti utilizzate dalle aziende si sono espanse fino a coprire aree di dimensioni sempre maggiori con calcolatori distanti centinaia di chilometri. Con lo sviluppo delle tecnologie informatiche risultato possibile realizzare reti di calcolatori che si estendono su aree di grandi dimensioni, le cosiddette WAN, costituite da pi LAN collegate tra loro. Mezzi di trasmissione. Nella maggior parte dei casi la trasmissione dei dati avviene mediante una struttura cablata che costituisce il supporto fisico utilizzato per la propagazione dei segnali elettrici tra un calcolatore e laltro. I tipi di cavo disponibili sono tre: cavo a doppini intrecciati, cavo coassiale e cavo a fibra ottica. Il cavo a doppini intrecciati (linea telefonica) costituito da due o pi fili di rame isolati ed intrecciati. Spesso in un unico cavo sono raggruppati pi doppini intrecciati, il cui numero pu variare in base al tipo specifico di cavo, protetti da una guaina isolante. I doppini intrecciati possono essere non schermati UTP, molto utilizzati per implementare le reti LAN in quanto leggeri, flessibili ed a basso costo; oppure schermati STP, che consentono una riduzione dei disturbi di tipo elettromagnetico. La velocit di trasmissione dei cavi a doppini intrecciati di circa 106 bps (bit/secondo). Il cavo coassiale costituito da un conduttore interno in rame rivestito da uno strato di materiale isolante avvolto in una calza metallica flessibile in rame il tutto circondato da una guaina isolante 38

esterna. Viene utilizzato per brevi distanze (circa 100 metri) ed ha una velocit di circa 109 bps. Rispetto al cavo a doppini intrecciati offre una migliore protezione ai disturbi. Il cavo a fibra ottica di norma composto da un nucleo di vetro ricoperto da un rivestimento anchesso di vetro (materiale riflettente), il tutto protetto da una guaina esterna isolante. Sono flessibili, leggere, immuni ai disturbi elettrici ed alle condizioni atmosferiche estreme, e poco sensibili a variazioni di temperatura. Le fibre ottiche permettono la propagazione dei segnali sotto forma di impulsi luminosi. Viene utilizzata per collegamenti a lunghe distanze ed in ambienti elettromagneticamente inquinati ed ha una velocit di circa 109 bps. In particolari situazioni non possibile collegare tra loro i PC di una LAN utilizzando i sistemi di cablaggio standard. Per ovviare a questo inconveniente sono state sviluppate tecnologie basate su dispositivi a raggi infrarossi, radio e laser che permettono lo scambio dei dati tra calcolatori fisicamente non collegabili tra loro. Architettura delle reti. Esistono tre tipologie principali: reti locali (LAN), reti metropolitane (MAN) e reti geografiche (WAN). Sono caratterizzate da estensione geografica topologia e tecniche di trasmissione. Le LAN mettono in comunicazione un certo numero di dispositivi, come tutte le altre reti, ma a distanza ridotta tra loro, in genere allinterno dello stesso edificio. Utilizzano approcci di tipo broadcast, non esistono o quindi nodi intermedi ma ogni stazione include un trasmettitore/ricevitore che comunica su un canale di trasmissione condiviso con tute le stazioni della rete. Di conseguenza solo una stazione pu inviare in ogni istante mentre le altre sono in ricezione. Le caratteristiche delle LAN sono: ampia larghezza di banda, modularit e facilit di connessione, affidabilit, espandibilit, flessibilit, economicit. Le MAN son reti di media estensione, pi grandi delle LAN ma pi piccolo delle WAN. Sono costituite da pi reti LAN connesse tra loro da bridge o router. In genere sono allestite dagli enti pubblici incaricati gestori della rete telefonica all'interno di un'area metropolitana (una citt). Per questa struttura vengono utilizzate reti veloci ed affidabili e generalmente sono realizzate con cavi a fibre ottiche. Le WAN possono essere considerate come reti di trasmissione tra calcolatori fisicamente distanti tra loro, collegati attraverso mezzi di trasmissione dedicati; in altre parole sono infrastrutture di rete che coprono una nazione od un intero continente collegando tra loro diverse LAN o MAN. Nel caso pi generale le WAN sono rappresentate come la composizione di tre livelli: le reti di trasmissioni che si occupano del trasferimento delle informazioni tra i diversi nodi; la rete di calcolatori composta dai calcolatori (host); gli utenti. Questo tipo di rete detta commutata che rispetto a quella dedicata ha costi inferiori. Le WAN si caratterizzano in base alla strategia utilizzata per instradare i segnali. Topologia delle reti. La topologia delle reti indica la struttura delle connessioni tra i calcolatori. Esistono tre topologie principali: a bus, a stella ed ad anello. La topologia a bus, detta anche topologia lineare, rappresenta la struttura pi semplice da implementare. costituita da un singolo cavo cui sono collegati tutti i PC che costituiscono i nodi della rete. Quando un calcolatore deve inviare dati ad un altro computer trasmette le informazioni sul cavo servendosi della propria scheda di rete, ad ognuna delle quali associato un indirizzo univoco, in modo che solo il destinatario possa leggere il messaggio. Il bus trasmette in broadcast, in quanto in uno stesso istante una sola stazione pu trasmettere e tutte le altre ricevono. I vantaggi di questo sistema sono la semplicit e i bassi costi, in caso di guasto di una stazione non viene disabilitata lintera rete ma solo la stazione guasta, pu essere inserita una nuova stazione semplicemente aggiungendo un cavo. Lo svantaggio di questa struttura la dipendenza di tutte le stazioni da un unico mezzo trasmissivo, quindi, le prestazioni possono diventare un fattore critico in caso si traffico elevato. 39

Nella topologia a stella i calcolatori sono collegati ad un unico nodo centrale (chiamato HUB) che ha il ruolo di server della rete e da cui transitano tutte le comunicazioni. I vantaggi di questa topologia sono: le elevate prestazioni grazie alle connessioni punto-a-punto; la facilit di controllo centralizzato del server; la semplicit del protocollo di comunicazione che si basa sullo scambio di informazioni tra e stazione cliente. I contro di questa topologia invece sono: il possibile blocco delle comunicazioni in caso di traffico elevato; la lunghezza dei cavi richiesti; la dipendenza dallaffidabilit del server in quanto un guasto blocca lintera rete. Nella struttura ad anello si ha una connessione circolare punto-a-punto tra tutte le stazioni collegate con un unico cavo. Linformazione transita nellanello in una direzione fino ad essere ricevuta da una stazione, questa valuta se il messaggio per lei e, in caso contrario, rigenera il segnale e lo trasmette alla stazione successiva. Uno svantaggio di questa topologia la limitata flessibilit, infatti, per inserire una nuova stazione, bisogna aprire lanello e sospendere lattivit di rete. Un altro svantaggio laffidabilit della rete che dipende dallaffidabilit di tutte le stazioni collegate, se una stazione si guasta i messaggi possono essere scambiati solo sui tratti rimasti collegati. Per ovviare a questo problema si realizzano reti a doppio anello, quindi con due collegamenti, uno per direzione. Le tipologie di rete. Progettando una LAN bisogna decidere come gestire le stazioni della rete e consentire loro di condividere le risorse. Abbiamo due possibilit: rete client-server o rete peer-to-peer. Nella condivisione delle risorse con rete client-server presente una stazione, spesso dedicata (server), che gestisce centralmente la condivisione di tutte le risorse, la sicurezza e la gestione della rete. Le risorse condivise e quindi rese accessibili alle altre stazioni della rete (client), sono solo quelle collegate direttamente al server. Nella rete peer-to-peer non esiste una gerarchia tra stazioni per la gestione ed il controllo della rete, essa costituita da un insieme di stazioni connesse in modo paritario in modo che ognuna possa inviare messaggi e condividere risorse sia hardware che software. Ogni stazione, quindi, gestisce il controllo degli accessi alle proprie risorse e decide cosa condividere e con chi. Queste informazioni sono generalmente fornite dal sistema operativo su ogni stazione. La scelta di queste due tipologie dipende da diversi fattori, se si vuole creare una rete di piccole dimensioni che condivida poche risorse preferibile una rete peer-to-peer per costi e semplicit di gestione; viceversa, al crescere delle stazioni collegate e dei file condivisi, necessario passare ad una configurazione client-server. Commutazione di circuito e di pacchetto. Le reti geografiche (WAN) si differenziano in base alla strategia utilizzata per instradare i segnali per i quali son state adottate tecniche di commutazione di circuito e di pacchetto. La tecnica della commutazione di circuito (telefono) consiste nel creare tra sorgente e destinatario un canale logico temporaneo dedicato, costituito da una successione di connessioni tra nodi della rete. Ad ogni nodo della rete i dati sono instradati lungo il canale predisposto in uscita, senza alcun ritardo. Questa tecnica efficiente per le comunicazioni telefoniche in cui la larghezza di banda riservata viene utilizzata quasi per intero (generalmente in ogni istante una delle due parti sta parlando cio usando la linea). Questo non si verifica nelle trasmissioni di dati tra calcolatori, i cui periodi di trasmissione si alternano a periodi di inattivit della linea. Con questa tecnica la trasmissione si effettua a velocit costante che ovviamente pari a quella del calcolatore pi lento rendendo inefficiente lutilizzo della larghezza di banda dedicata. Per evitare i problemi della commutazione di circuito nella comunicazione tra calcolatori negli anni 70 fu introdotta la commutazione di pacchetto che si basa sullinvio di pacchetti di dati di dimensioni ridotte (dellordine del kbyte). Il messaggio viene spezzato in una serie di pacchetti, ognuno dei quali contiene i dati da trasmettere, informazioni di controllo, lindirizzo del destinatario e il numero progressivo che indica la posizione del pacchetto allinterno del 40

messaggio. I vantaggi di questa tecnica sono: le linee risultano utilizzate in modo pi efficiente; il collegamento efficiente anche tra calcolatori aventi velocit di trasmissione differenti; in caso di traffico elevato le comunicazioni non vengono bloccate e i pacchetti sono ugualmente inviati anche se il tempo di consegna aumenta; possibile gestire comunicazioni a priorit diversa. Protocolli di comunicazione. I calcolatori collegati in rete devono cooperare per stabilire una comunicazione, le regole che formalizzano questa cooperazione sono chiamate protocolli di comunicazione. Questi specificano: i formati dei dati, la struttura dei pacchetti incluse le definizioni delle informazioni di controllo, la velocit di trasmissione. Per semplificare il progetto di una rete e aumentarne la flessibilit viene creato un insieme di protocolli, cio tutte le varie le propriet di trasmissione non sono definite in un unico protocollo ma in pi protocolli ognuno dei quali dedicato alla formazione di un particolare aspetto della trasmissione. Larchitettura dei protocolli organizzata a livelli, ognuno dei quali fornisce i servizi necessari a quelli superiori. Il modello pi diffuso per la realizzazione di protocolli ISO/OSI. Quando due stazioni (host A e host B) devono comunicare, i dati prima attraversano tutti i livelli della stazione di partenza per essere quindi ricevuti dal livello fisico della stazione di destinazione dove saranno rielaborati dai livelli superiori, fino a ricostruire, al livello pi alto, il messaggio originario. La struttura del modello ISO/OSI costituita da sette livelli: applicazione, insieme di applicazioni che forniscono agli utenti finali particolari servizi di rete come programmi per la posta elettronica; presentazione, conversione del formato dei dati come formati della codifica in virgola mobile per i numeri reali; sessione, gestisce lapertura e la chiusura della connessione tra calcolatore mittente e destinatario e la loro sincronizzazione; trasporto, in trasmissione suddivide i messaggi in pacchetti mentre in ricezione ricostituisce i messaggi; rete, gestisce linstradamento dei singoli pacchetti; collegamento, rileva e corregge gli errori di trasmissione dei singoli bit di un pacchetto; fisico, definisce i dettagli dei dispositivi fisici utilizzati per la trasmissione e definisce le modalit di trasmissione fisica dei dati tra due calcolatori connessi fisicamente da una linea di trasmissione. Questo modello finalizzato solo a fornire unorganizzazione e una terminologia, senza porre limiti alla architetture delle diverse reti che lo implementano. Oltre al modello ISO/OSI dagli anni 70 in poi si sviluppato un altro insieme di protocolli TCP ed IP. Uno degli obbiettivi principali dei protocolli TCP/IP quello di consentire linteroperabilit tra reti fisiche diverse in modo da realizzare una rete geografica attraverso il collegamento di tante reti pi piccole. Il successo del modello TCP/IP dovuto alla sua efficienza e semplicit ed stato utilizzato come base per lo sviluppo di Internet. Per quanto non esista un modello ufficiale come per ISO/OSI, TPC/IP impostato su unarchitettura a cinque livelli: il livello fisico, definisce linterfaccia fisica tra le stazioni per la trasmissione dei dati e il mezzo di trasmissione; il livello di accesso alla rete, si occupa dello scambio dati fra un sistema finale e la rete a cui collegato, specificando come organizzare i dati in freme e come trasmetterli sulla rete; il livello internet (gestito dal protocollo IP), utilizzato quando due sistemi da connettere non appartengano alla stessa rete, specifica il formato dei pacchetti da inviare ed i meccanismi utilizzati per farli transitare dal calcolatore sorgente a quello destinatario attraverso uno o pi router;

41

il livello di trasporto o host to host (gestito dal protocollo TCP), fa in modo che le informazioni siano trasmesse in modo affidabile, in particolare si occupa di suddividere un messaggio in pacchetti e, in ricezione, di riassemblare i pacchetti nellordine corretto; il livello di applicazione specifica come unapplicazione pu utilizzare linsieme dei protocolli TCP/IP, fornendo quindi la possibilit di comunicazione tra applicazioni eseguite su calcolatori diversi.

Indirizzi IP e TCP. Ad ogni calcolatore collegato ad una rete TCP/IP (Internet) assegnato un indirizzo IP, cio un numero di 4 byte (32 bit). Questi indirizzi sono generalmente rappresentati in forma decimale come una successione di quattro numeri separati da un puntino (per esempio lindirizzo del server web del DIEE 192.167.131.6). Ogni numero decimale rappresenta il valore del corrispondente byte binario; considerando che un byte comprende 8 bit i quattro numeri dellindirizzo IP variano tra 0 e 255. Lindirizzo IP strutturato in due parti: una parte individua la rete fisica a cui la stazione collegata, laltra parte identifica la singola stazione nellambito della rete fisica. Il numero di bit assegnato alle due parti non fisso ma dipende dalle dimensioni della rete, abbiamo cos tre classi primarie chiamate A, B e C, ognuna caratterizzata da una diversa suddivisione dei 4 byte. Nella classe A si usa un byte per individuare la rete ed i restanti 3 byte per indicare lindirizzo del calcolatore collegato a quella rete; nelle reti B si usano 2 byte per indirizzare la rete e 2 byte per le stazioni; mentre per le reti C si usano 3 byte per indirizzare la rete e 1 byte per le stazioni. Tornando allesempio dellindirizzo del server web del DIEE (rete classe B) i primi due numeri (192.167) indicano la rete delluniversit di Cagliari, il terzo (131) la sottorete del DIEE, ed il quarto (6) identifica un elaboratore allinterno della sottorete DIEE. Per aumentare la facilit di utilizzo, non facile da ricordare un numero binario, si diffuso un sistema chiamato DNS (Domanian Name System) che associa ad ogni indirizzo numerico un indirizzo simbolico. Lindirizzo numerico costituito da una successione di stringhe alfanumeriche separate da punti ognuna delle quali identifica un dominio, per esempio www.diee.unica.it lindirizzo simbolico associato allindirizzo IP 192.167.131.6. Linsieme degli indirizzi DNS organizzato in domini e sottodomini in una struttura gerarchica: nellesempio di sopra la stringa pi a destra (it) rappresenta la nazione in altri esempi pu rappresentare il tipo di servizio (com = commerciale ecc); la seconda stringa (unica) indica la rete; la terza stringa (diee) indica la sottorete; la quarta stringa (www) un calcolatore che ha la funzione di server web. Il world wide web (www). Il world wide web (web) il sistema software per la gestione e la condivisione di documenti distribuiti su uno o pi calcolatori. Consente di realizzare documenti multimediali contenenti testo, immagini e suoni e documenti ipertestuali contenenti rimandi (link, collegamenti). Si basa sullarchitettura client-server ed il client il navigatore web (browser) mentre il server il server web. Il browser richiede la visualizzazione delle pagine web ed il server web invia le pagine ai calcolatori che ne fanno richiesta. Il web pu essere inteso come ununica, grande applicazione distribuita, costituita dallinsieme di tutti i server web accessibili su internet e dai browser che gli utenti connessi impiegano per navigare. Il protocollo di comunicazione tra browser e server web HTTP. La sua caratteristica principale la semplicit: HTTP specifica che tutte le comunicazioni devono essere realizzate mediante messaggi costituiti da unintestazione e, opzionalmente, da un corpo. Proprio per mantenere questa semplicit le comunicazioni richiesta-risposta HTTP possono essere gestite senza stato, cio senza tenere traccia di eventuali precedenti connessioni effettuate quindi indipendentemente luna dallaltra.

42

Uno dei motivi che ha contribuito al successo del web stata la standardizzazione di uno schema uniforme di identificazione applicativa. Ogni pagina web, ed ogni file, identificata da un URL (Uniform Resource Location). Alla base del concetto di URL larchitettura client-server ed in particolare lipotesi che ogni calcolatore presente sulla rete con funzione di server disponga di un indirizzo univoco. LURL un nome simbolico composto da: lidentificatore del protocollo di trasmissione, lindirizzo simbolico del server, il path name del file nel file system del server. Per esempio la pagina principale del sito di questo corso si trova nel file index.html, il cui URL http://www.diee.unica.it/~fumera/El/index.html dove: http:// lidentificatore del protocollo, www.diee.unica.it/ lindirizzo simbolico del server, ~fumera/El/index.html la path name del file index.html. La posta elettronica. La posta elettronica uno dei servizi internet pi diffusi e serve a scambiare messaggi di testo ed altri file. Si basa sempre su unarchitettura client-server e non peer-to-peer perch, in questultimo caso, i destinatari del messaggio sarebbero raggiungibili solo fin quando il calcolatore che mantiene la loro casella di posta (mailbox) connesso alla rete. Nel secondo caso invece i server fungono da intermediari tra i client ed in particolare come strumenti di memorizzazione dei messaggi in caso di temporanea irraggiungibilit del client del destinatario. Succede quindi: il mittente opera con un client e mediante questo invia il messaggio al suo server incaricato della spedizione, il protocollo applicativo impiegato in questa fase SMTP (Simple Mail Transfer Protocol); il server del mittente invia il messaggio al server che mantiene la mailbox del destinatario, il protocollo sempre SMTP; il destinatario accede alla sua mailbox ed ottiene il messaggio in essa contenuta, i protocolli impiegati in questa fase sono alternativamente POP (Post Office Protocol) oppure IMAP (Internet Message Access Protocol). I messaggi sono delle sequenze di caratteri di lunghezza arbitraria composte da: header cio informazioni di controllo (indirizzo del mittente, del destinatario, ecc); body cio il testo del messaggio; attachment cio file allegati al messaggio codificati in modo opportuno.

43

Introduzione ..................................................................................................................................... Storia ......................................................................................................................................... Nascita dellinformatica ............................................................................................................ Architettura dei calcolatori .............................................................................................................. Struttura e funzioni di base dei calcolatori ............................................................................... Architettura di von Neumann ................................................................................................... Il calcolatore universale ............................................................................................................ Evoluzione della tecnologia dei calcolatori .............................................................................. Lunit di elaborazione ............................................................................................................. Prestazioni di una CPU ............................................................................................................. Parallelismo .............................................................................................................................. Sistema di memoria .................................................................................................................. Tipi di calcolatore ..................................................................................................................... Il sistema operativo (SO) ................................................................................................................. Evoluzione dei sistemi operativi ............................................................................................... Componenti di un sistema operativo ........................................................................................ Sistemi operativi multiprogrammati ed a partizione di tempo ................................................. La gestione dei processi ............................................................................................................ Competizione tra processi ......................................................................................................... Gestione della memoria ............................................................................................................ File system ................................................................................................................................ Gestione delle periferiche I/O ................................................................................................... Protezione e sicurezza ............................................................................................................... Codifica binaria dellinformazione ................................................................................................. Informazione e supporto fisico ................................................................................................. Sintassi e semantica .................................................................................................................. Codifica analogica e codifica digitale ....................................................................................... Codifica di dati numerici .......................................................................................................... Codifica binaria dei numeri ...................................................................................................... Codifica dei caratteri ................................................................................................................. Codifica delle immagini ............................................................................................................ Algoritmi ......................................................................................................................................... Descrizione degli algoritmi ....................................................................................................... Linguaggi per la rappresentazione degli algoritmi ................................................................... Il pseudo linguaggio del corso .................................................................................................. Esecuzione algoritmi ................................................................................................................. Rappresentazione di algoritmi mediante i diagrammi di flusso o diagrammi a blocchi ........... Gli array .................................................................................................................................... Metodi di risoluzione degli algoritmi ....................................................................................... Esempi di formulazione di algoritmi ........................................................................................ Correttezza ed efficienza degli algoritmi .................................................................................. Problemi intrattabili ..................................................................................................................

pag. 1 pag. 1 pag. 2 pag. 2 pag. 2 pag. 2 pag. 3 pag. 3 pag. 4 pag. 5 pag. 6 pag. 7 pag. 8 pag. 9 pag. 9 pag. 10 pag. 10 pag. 11 pag. 12 pag. 13 pag. 14 pag. 15 pag. 16 pag. 16 pag.16 pag. 17 pag. 17 pag. 18 pag. 20 pag. 21 pag. 21 pag. 21 pag. 21 pag. 22 pag. 23 pag. 25 pag. 26 pag. 26 pag. 29 pag. 29 pag. 32 pag. 34

44

Sottoprogrammi ........................................................................................................................ Basi di dati ....................................................................................................................................... Organizzazione degli archivi .................................................................................................... Modello relazione dei dati ........................................................................................................ Vincoli di integrit .................................................................................................................... Reti di calcolatori Internet ............................................................................................................ Mezzi di trasmissione ............................................................................................................... Architettura delle reti ................................................................................................................ Topologia delle reti ................................................................................................................... Le tipologie di rete .................................................................................................................... Commutazione di circuito e di pacchetto ................................................................................. Protocolli di comunicazione ..................................................................................................... Indirizzi IP e TCP ..................................................................................................................... Il world wide web (www) ......................................................................................................... La posta elettronica ...................................................................................................................

pag. 35 pag. 36 pag.36 pag. 38 pag. 38 pag. 39 pag. 39 pag. 39 pag. 40 pag. 41 pag. 41 pag. 41 pag. 42 pag. 43 pag. 43

45