Riassunto Teoria Informatica
Esistono due grandi classi di elaboratori: Elaboratori dedicati (special‐purpose computer): Un elaboratore dedicato (embedded system) è un elaboratore programmato per svolgere funzioni specifiche definite a priori in fase di progetto/produzione Elaboratori di uso generale (general‐purpose computer): o Personal Computer: è un qualsiasi computer di uso generico le cui dimensioni, prestazioni e prezzo di acquisto lo rendono adatto alle esigenze del singolo individuo nell'uso quotidiano; o Server: è un elaboratore che fornisce dei “servizi” a altri elaboratori (chiamati clients) attraverso una rete (computer network); Server Farm: un insieme di elaboratori server collocati in un apposito locale (centro di calcolo) presso una media o grande azienda; o Workstation: si contraddistingue dall'essere destinato principalmente a un utilizzo produttivo, e dall'avere alte prestazioni per poter assolvere compiti altamente professionali di vario genere; o Mainframe: sono elaboratori che offrono grandi prestazioni, usati principalmente da grandi imprese per rilevanti applicazioni software (mission critical application). Algoritmo: è una sequenza finita di azioni che devono essere seguite meccanicamente per giungere alla soluzione di un problema. Il computer segue questo tipo di processi. Stadi di sviluppo di un programma 1. Problema 2. Idea → Soluzione 3. Algoritmo → Rappresentato da una Soluzione formale: Pseudo‐codice Diagrammi di flusso** 4. Programma → Traduzione dell’algoritmo in una forma comprensibile ad un elaboratore elettronico 5. Test 6. Documentazione Traduzione di un programma: Scrittura di un file sorgente (main.c) utilizzando un Editor di testi* (Codeblocks); Elaborazione del file sorgente nel compilatore (GCC); Creazione del file oggetto, cioè la traduzione del file sorgente in linguaggio macchina (binario); File oggetto viene passato al linker che vi aggiunge delle componenti da librerie, che permettono l’uso di funzioni quali la stampa, la lettura ecc.; Creazione del file eseguibile (.exe). *Ambiente integrato (IDE, Integrated Development Environment): è un’applicazione software che contiene al suo interno un editor di testi per programmatori, un compilatore C, un ambiente di verifica dei programmi. **Diagrammi di flusso (flow‐chart): Sono strumenti grafici che rappresentano l’evoluzione logica dell’algoritmo, è detto strutturato se contiene solo un insieme predefinito di strutture elementari: ‐ Un blocco Start e uno Stop ‐ Sequenza di blocchi (di elaborazione e/o di input‐output) ‐ If/Else ‐ While/Do Teorema di Böhm – Jacopini: Qualunque diagramma di flusso è sempre trasformabile in un diagramma di flusso strutturato equivalente a quello dato. Quindi, qualunque flusso logico può essere realizzato utilizzando solamente due strutture di controllo: ‐ Meccanismo di decisione (If/Else) ‐ Meccanismo di ripetizione (loop While/Do)
Elementi dell’elaboratore: Memoria Centrale: memoria veloce, contiene i dati che devono essere elaborati; interagisce frequentemente con l’unità di elaborazione. È composta da: RAM (Random Access Memory): memoria volatile, non permanente. Molto veloce, comunicazioni frequenti con l’unità di elaborazione. Il tempo di accesso a qualunque cella di memoria è sempre costante; ROM (Read Only Memory): memoria in sola lettura che contiene dati utili all’avvio, è scritta una sola volta e non modificabile. Memoria di Massa (memoria secondaria): Molto più lenta, ma capace di contenere i dati che vogliamo immagazzinare per un tempo indefinito (Hard disk, Cd, floppy…). Microprocessore: è un chip che realizza le funzioni di CPU (Central Processing Unit) in un computer o in un sistema digitale. È un elemento complesso, il cervello dell’elaboratore. Una CPU generica contiene: Unità di controllo (“CU”): è un componente delle CPU che ha il compito di coordinare tutte le azioni necessarie per l'esecuzione di una istruzione e di insiemi di istruzioni. È il componente che dà la possibilità al microprocessore di eseguire istruzioni diverse; Unità aritmetica e logica (“ALU”): si occupa di eseguire le operazioni logiche e aritmetiche. Solitamente è composta da circuiti combinatori. Ogni unità ha un dato compito non è flessibile, ma comunque molto veloce; Registri: speciali locazioni di memoria interne alla CPU, molto veloci, usati per conservare temporaneamente dei dati (es. risultati parziali), a cui è possibile accedere molto più rapidamente della memoria centrale. I registri sono pochi in numero e di ridotte dimensioni. Tre registri sempre presenti sono: o IR (Istruction Register): che immagazzina l'istruzione in fase di elaborazione; o PC (Program Counter): che contiene l'indirizzo in memoria della prossima istruzione da eseguire (e da cui fare il fetch); o Flag: questo registro non contiene valori numerici convenzionali, ma è piuttosto un insieme di bit, detti appunto flag, che segnalano stati particolari della CPU e alcune informazioni sul risultato dell'ultima operazione eseguita. Unità di decodifica: si occupa di ricevere le istruzioni in ingresso e di attivare le opportune unità interne del processore per eseguire l'istruzione caricata; Unità di gestione della memoria ("MMU" ‐ Memory Management Unit) è una classe di componenti hardware che gestisce le richieste di accesso alla memoria generate dalla CPU. La MMU può avere vari compiti tra cui la traslazione (o traduzione) degli indirizzi virtuali in indirizzi fisici, la protezione della memoria, il controllo della cache della CPU, l'arbitraggio del bus, la commutazione di banchi di memoria; Unità di controllo dei Bus: gestisce i bus della CPU. Bus (sistema circolatorio del computer): sono componenti hardware che interfacciano le diverse unità dell’elaboratore. Se mal dimensionato, potrebbe essere causa di un ‘collo di bottiglia’. Caratteristiche di un bus sono: Trasporto di un solo dato per volta; Frequenza, ossia i numeri di dati trasportati al secondo; Ampiezza, il numero di bit di cui è costituito il singolo dato. Tipi di Bus ‐ un singolo Bus è suddiviso in tre ‘sotto‐bus’: Bus Dati (DBUS), la sua dimensione indica la dimensione di una cella di memoria; Bus degli Indirizzi (ABUS), la sua dimensione determina il massimo numero di celle di memoria indirizzabili; Bus di Controllo (CBUS), trasporta i dati di controllo (anche verso le periferiche); Più è grande l’Abus, più celle possono essere rappresentate, più indirizzi vengono trasportati con maggiore possibilità di combinazione; più è grande il Dbus tanto più grande è la dimensione di una singola cella.
Le caratteristiche del Bus sono correlate alla quantità massima di memoria centrale che si può fisicamente installare sull’elaboratore, secondo la formula:
2 |
|
| ∗| Bus di Input/Output: mettono in comunicazione il computer con le periferiche, attraverso specifiche interfacce, permettendo il “contatto con il mondo umano”. Esempi di bus di I/O (o esterni) sono gli Usb, universali ed orientati alle memorie di massa (tipo Pen Drive e simili). La massima quantità di memoria esterna dipende dal bus di I/O e non dipende dalla’ABUS. Un Elaboratore esegue le istruzioni basandosi su un ciclo standard: 1. Prelievo di un’istruzione della memoria centrale; 2. Istruzione caricata sulla CPU che attiva le zone addette con le giuste tempistiche; 3. L’indirizzo dell’istruzione da eseguire viene passato dal PC all’IR; 4. Interpreta l’istruzione ‐ Logica di Controllo; 5. Esegue l’istruzione ‐ il comando viene passato dalla Logica di Controllo all’esecutore; 6. In caso di avvenuta di esecuzione, il ciclo ricomincia, in caso contrario viene segnalato un errore. Clock: ogni elaboratore contiene un elemento di temporizzazione, il clock, un segnale digitale sincrono, che genera un riferimento temporale comune per tutti gli elementi costituenti il sistema di elaborazione. Un ciclo macchina è un intervallo di tempo in cui viene svolta un’operazione elementare, ed è un multiplo intero del periodo (T) del Clock. L’esecuzione di un’istruzione richiede un numero intero di cicli macchina. MAX MEM
Sistema di numerazione posizionale (decimale, binario..) Occorre definire la base B da cui discendono varie caratteristiche: ‐ Cifre (a) = { 0, 1, 2, ..., B‐1 } ‐ peso della cifra i‐esima = Bi
A
∗
Sistema Binario: è in base 2, le cifre sono 1 e 0 (1 = True e 0 = False). La prima cifra del numero binario prende il nome di MSB (Most Significant Bit), mentre l’ultima LSB (Least Significant Bit). Ogni cifra è rappresentata nel calcolatore da 1 bit (8 bit = 1 byte). Quindi attraverso il linguaggio binario si possono rappresentare numeri limitati dal numero di bit (N) disponibili: possono essere create 2N combinazioni (dove il minimo è 0 e il massimo 2N‐1). Come convertire (Decimale ←→ Binario): Binario → Decimale: si effettua la somma pesata delle cifre binarie. ESEMPIO: 1101(2) = 1*23 + 1*22 + 0*21 + 1*20= 8 + 4 + 0 + 1 = 13(10) Decimale → Binario: si procede con divisioni successive per 2, riportando il resto (che può essere 1 o 0); al termine dell’operazione si “ricopiano” i resti in ordine inverso. ESEMPIO: 13(10) = 1101(2) 13 6 3 1 0 1 0 1 1 1101
Operazioni con i numeri binari: SOMMA – regole base: Es: 110(2) + 111(2) = 1101(2) 1 1 0 + 0 = 0 0 1 1 0 + 0 + 1 = 1 0 1 1 1 = 1 + 0 = 1 1 + 1 = 0 (overflow* = 1) 1 1 0 1 DIFFERENZA – regole base: Es: 101(2) ‐ 11(2) = 10(2) 1 0 ‐ 0 = 0 0 1 0 1 ‐ 0 ‐ 1 = 1 (borrow = 1) 0 0 1 1 = 1 ‐ 0 = 1 0 0 1 0 1 ‐ 1 = 0 *Overflow: indica l’errore che si verifica in un sistema di calcolo automatico quando il risultato di un’operazione non è rappresentabile con la medesima codifica e numero di bit degli operandi (si lavora con numero fisso di bit). Quindi quando il numero (risultante o no) eccede il numero massimo di bit disponibile per quel numero. Codifica HEX (Esadecimale): Codifica OCT (Ottale): base = 16 (H) base = 8 (Q) cifre = { 0, 1, ..., 9, A, B, C, D, E, F } cifre = { 0, 1, 2, 3, 4, 5, 6, 7 } usato per compattare i numeri binari (4:1) usato per compattare i numeri binari (3:1) Es: 10111001(2) = B9(16) Es: 10111001(2) = 271(8)
Numeri col segno ‐ in binario esistono varie codifiche: Modulo e segno: l’MSB assumerà valore 0 per segno positivo, 1 se il segno è negativo; verranno quindi occupati un Bit dal segno e N‐1 Bit dal modulo. Gli svantaggi sono il doppio zero (lo zero è rappresentabile come 00 = +0 e 10 = ‐0), operazioni complesse. Con N numero di Bit, è rappresentabile l’intervallo: [−(2 −1 − 1), +(2 −1 – 1)] (si parla di range simmetrico) Complemento a 2: in questa codifica per un numero a N bit, il MSB ha peso negativo, pari a −2 −1. Mentre gli altri bit hanno tutti peso positivo. Di conseguenza il MSB indica sempre il segno: 0 = ‘+’ 1 = ‘−’ Esempi: o 1000CA2 = ‐23 = ‐810 o 1111CA2 = ‐23 + 22+ 21 + 20 = ‐8 +4 +2 +1 = ‐110 o 0111CA2 = 22 + 21 + 20 = 710 Per quanto riguarda le operazioni, queste si effettuano direttamente, senza badare ai segni degli operandi. Con operandi aventi segno discorde, non si può mai verificare overflow, mentre, in caso di segno concorde, l’overflow si verifica quando il risultato ha segno discorde; nel caso in cui si verifica un carry sull’ultima cifra, esso non si considera. Convertire da Decimale in CA2: se il numero è positivo allora CA2 = M&S; se il numero è negativo, si calcola il corrispondente positivo in M&S, dopodiché si ricopia da destra verso sinistra fino al primo numero 1, quindi si copia invertendo gli uni con gli zeri. Esempio: ‐10 → |‐10| = 01010M&S → 10110CA2
Rappresentazione Virgola Mobile (Floating Point): Utile per rappresentare numeri reali, o in notazione scientifica all’interno del calcolatore, N = ± M × 2E Nella memoria vengono salvati: Segno (±) Esponente (E, la base è 2) Mantissa (M, nella forma “1,..” max < 2) Formati: IEEE 754 SP (Singola Precisione 32bit): IEEE 754 DP (Doppia Precisione 64bit): Intervallo valori:
Codifica ASCII (American Standard Code for Information Interchange): Codifica standard per i caratteri, la più usata nelle telecomunicazioni, le caratteristiche più importanti sono: Usa 8 bit (originariamente 7 bit per US‐ASCII) per rappresentare i simboli; 52 caratteri alfabetici (a...z A...Z); 10 cifre (0...9); segni di interpunzione (,;!?...); caratteri di controllo, non stampabili (e.g. CR (13) Carriage Return; NL (10) New Line). Unicode: esprime tutti i caratteri di tutte le lingue del mondo (più di un milione). UTF‐8: è la codifica di Unicode più usata: ‐ 1 byte per caratteri US‐ASCII (MSB=0); ‐ 2 byte per caratteri Latini con simboli diacritici, Greco, Cirillico, Armeno, Ebraico, Arabo, Siriano e Maldiviano; ‐ 3 byte per altre lingue di uso comune; ‐ 4 byte per caratteri rarissimi; Logica Booleana: La logica su cui si basa il computer, è la logica Booleana, basata su variabili che sono in grado di assumere solo due valori, Vero (1) o Falso (0). Gli operatori si dividono tra operatori Unari (es. NOT) e Binari (es. AND) che vengono descritti tramite una tavola delle verità: per N operandi la tabella avrà 2N righe che elencano tutte le possibili combinazioni di valori che delle variabili indipendenti ed il valore assunto dalla variabile dipendente. Una funzione booleana è una combinazione di variabili e operatori booleani che associa più variabili indipendenti e restituisce una variabile. Nelle funzioni vanno eseguiti prima gli AND e poi gli OR.
Gli operatori Booleani:
Operatore NOT (! negazione):
Operatore AND (&& ‘x’ moltiplicazione):
Operatore OR (|| ‘+’ somma):
Operatore XOR (⊕ : Proprietà Commutativa: A×B = B×A A × B × C = (A×B) × C = A × (B×C) = (A×C) × B Proprietà Associativa: A+B = B+A A + B + C = (A+B) + C = A + (B+C) = (A+C) + B Proprietà Distributiva: A×(B+C) = A×B + A×C A+(B×C) = (A+B) × (A+C) Teorema di De Morgan: A+B = !(!A×!B) A×B = !(!A+!B)
Un esempio di dimostrazione:
A + ( B × C ) = ( A + B ) × ( A + C ) ?
A 0 0 0 0 1 1 1 1
B 0 0 1 1 0 0 1 1
C 0 1 0 1 0 1 0 1
A 0 0 0 0 1 1 1 1
+ + + + + + + + +
B 0 0 1 1 0 0 1 1
x x x x x x x x x
C 0 1 0 1 0 1 0 1
= = = = = = = =
R 0 0 0 1 1 1 1 1
(A 0 0 0 0 1 1 1 1
+ + + + + + + + +
B) 0 0 1 1 0 0 1 1
x (A + C) x 0 + 0 x 0 + 1 x 0 + 0 x 0 + 1 x 1 + 0 x 1 + 1 x 1 + 0 x 1 + 1
= = = = = = = =
R 0 0 0 1 1 1 1 1
Seguendo questa logica, si passa dal Transistor al Chip. Il Chip, attraverso delle porte logiche, elabora il segnale ricevuto, applicando la logica booleana, trasformandolo in un segnale elettrico di I/O. Quando ci viene sottoposto un problema di logica booleana bisogna: 1. Individuare le variabili Booleane; 2. Creare la tabella di verità; 3. Scrivere l’espressione algebrica; 4. Operare eventuali semplificazioni; 5. Disegnare il circuito utilizzando le porte logiche partendo dall’espressione trovata. Approccio Top‐Down: Un programma realistico può consistere di migliaia di istruzioni Sebbene fattibile, una soluzione “monolitica” del problema non è molto produttiva (per quanto riguarda il riuso del codice e la comprensione del codice), e non è intuitiva. Quindi si preferisce usare un approccio Top‐Down al problema: Decomposizione del problema in sottoproblemi più semplici; Organizzazione strutturata; Struttura gerarchica a partire dal problema complesso fino a sottoproblemi sempre più semplici; Ripetibile su più livelli. Spazio occupato dalle variabili (IN GENERALE, se non diversamente specificato)(1byte = 8bit): Char: 1 byte = 8 bit; Int: 2 byte = 16 bit (dipende dalla struttura dell’elaboratore); Long: 4 byte = 32 bit (dipende dalla struttura dell’elaboratore); Float: 4 byte = 32 bit; Double: 8 byte = 64 bit (dipende dalla struttura dell’elaboratore); Long double: 12 byte = 96 bit (dipende dalla struttura dell’elaboratore).
Multipli del Byte Prefissi SI Nome Simbolo Multiplo kilobyte kB = 103 byte megabyte MB = 106 byte gigabyte GB = 109 byte Flag Printf: %[flags][min dim][.precisione][dimensione] Flags: ‘‐‘ giustificazione della stampa a sinistra ‘+’ premette sempre il segno Min dim: dimensione minima di stampa in caratteri .precisione: numero di cifre frazionarie (per numeri reali) Dimensione: h → short l → long Carattere: %d ‐ intero %u ‐ unsigned %s ‐ stringa %c ‐ carattere %x ‐ esadecimale %o ‐ ottale %f ‐ float %g ‐ double
Parametri linea di comando: main (int argc, char* argv[]){} argc: Numero di argomenti specificati. Esiste sempre almeno un argomento (il nome del programma) argv: Vettore di stringhe: argv[0] = primo argomento argv[i] = generico argomento argv[argc‐1] = ultimo argomento
Nome kibibyte mebibyte gibibyte
Prefissi binari Simbolo KiB MiB GiB
Multiplo = 210 bit = 220 bit = 230 bit
Flag Scanf: %[*][max dim][dimensione] [*]: ignora l’elemento [max dim]: dimensione massima in caratteri del campo Dimensione: h → short l → long
Flags apertura File FILE* fopen(char* , char* ); Tipo di accesso al file : “r”: sola lettura “w”: sola scrittura (cancella il file se esiste) “a”: append (aggiunge in coda ad un file) “r+”: lettura/scrittura su file esistente “w+”: lettura/scrittura su nuovo file “a+”: lettura/scrittura in coda o su nuovo file Ritorna: Il puntatore al file in caso di successo NULL in caso di errore Struct: typedef struct stud { char nome[40]; unsigned int matricola; unsigned int voto; }studente; …. studente studente1; …. Studente1.matricola = NNNNN;