Il linguaggio C Gli array I numeri casuali La direttiva DEFINE - Dichiarazione e memorizzazione di array L'inizializzazione di array La ...
←
→
Trascrizione del contenuto della pagina
Se il tuo browser non visualizza correttamente la pagina, ti preghiamo di leggere il contenuto della pagina quaggiù
Il linguaggio C Gli array Dichiarazione e memorizzazione di array L’inizializzazione di array La crittografia Gli algoritmi di ordinamento I numeri casuali C L an gu ag La direttiva DEFINE e Fondamenti di Informatica I - a.a. 2020-21 1
Gli array (vettori!) Nel linguaggio C, un array è un insieme di variabili dello stesso tipo memorizzate consecutivamente Ogni variabile dell’array, detta elemento, può essere acceduta mediante il nome dell’array ed un indice, con il primo elemento individuato dall’indice di valore 0 Esempio: Memorizzare la temperatura media registrata per ogni giorno dell’anno Si dichiara un array di 365 elementi (piuttosto che 365 variabili!), identificati con un solo nome, e che occupano posizioni di memoria consecutive Nota: Gli array contengono informazione correlata (le temperature di un anno, i voti di esame di uno studente, etc.) Fondamenti di Informatica I - a.a. 2020-21
La dichiarazione di array - 1 La sintassi della dichiarazione di un array è: Specificatore Nome Dimensione di tipo dell’array [ dell’array ] = La dichiarazione viene effettuata {inserendo Valoriuna iniziali coppia } di parentesi quadre dopo il nome dell’array La dimensione dell’array viene specificata inserendo il numero di elementi all’interno delle parentesi quadre Fondamenti di Informatica I - a.a. 2020-21 3
La dichiarazione di array - 2 Il riferimento ad un elemento dell’array è invece l’operazione di accesso al dato elemento ed avviene utilizzando il nome dell’array seguito dall’indice dell’elemento (racchiuso fra parentesi quadre) Le istruzioni di dichiarazione di un array e di riferimento ad un elemento dell’array sono molto simili nella forma, ma molto diverse nel significato /* I seguenti sono riferimenti a elementi /* La seguente è una dichiarazione; * dell’array; i valori 0,1,2,… specificano * il valore 365 specifica il numero * gli elementi a cui accedere * di elementi dell’array */ */ daily_temp[0] = 2; int daily_temp[365]; daily_temp[1] = 5; daily_temp[2] = 3; ……… Fondamenti di Informatica I - a.a. 2020-21 4
La dichiarazione di array - 3 Esempio: Calcolo della temperatura media annua #include #define DAYS_IN_YEAR 365 main() { int j, sum=0; int daily_temp[DAYS_IN_YEAR]; /* si assegnano i valori a daily_temp[] */ for (j=0; j
La modalità di memorizzazione degli array Esempio 4 byte int ar[5]; /* dichiarazione */ ar[0] = 15; 0FFC 1000 15 ar[0] ar[1] = 17; 1004 ar[1] ar[3] = 3; 17 1008 non definito ar[2] ar[3] 100C 3 ar[4] 1010 non definito 1014 1018 ar[2] e ar[4] sono indefiniti: il contenuto delle posizioni di memoria è quello rimasto da esecuzioni precedenti (garbage) Fondamenti di Informatica I - a.a. 2020-21 6
L’inizializzazione di array - 1 La presenza di valori indefiniti in alcuni elementi dell’array può provocare errori difficili da rilevare Þ Occorre inizializzare l’intero vettore !! Dichiarare l’array static (vettore a durata fissa): gli elementi del vettore, non inizializzati esplicitamente, vengono posti a zero Valori diversi possono essere specificati, facendoli seguire alla dichiarazione dell’array, racchiusi fra parentesi graffe: tali valori devono essere espressioni costanti che possano essere convertite automaticamente nel tipo dell’array Fondamenti di Informatica I - a.a. 2020-21 7
L’inizializzazione di array - 2 4 byte Esempio 0FFC static int ar[5]; 1000 0 15 ar[0] static int br[5] = {1,2,3.5,4,5}; 1004 ar[1] 17 0 1008 0 non definito ar[2] 100C ar[3] 0 ar[4] 1010 0 1014 1 br[0] Nota: il valore floating-point br[1] 1018 2 3.5 è convertito nel valore 101C 3 br[2] intero 3 1020 4 br[3] 1024 br[4] 5 1028 Fondamenti di Informatica I - a.a. 2020-21 8
L’inizializzazione di array - 3 Specificare un numero maggiore di valori di inizializzazione, rispetto agli elementi dell’array, costituisce un errore segnalato dal compilatore Se vengono specificati meno valori rispetto alla dimensione, gli elementi rimanenti vengono inizializzati a zero Esempio: La dichiarazione static int cr[5] = {1,2,3}; produce l’inizializzazione cr[0] = 1 cr[1] = 2 cr[2] = 3 cr[3] = 0 cr[4] = 0 Fondamenti di Informatica I - a.a. 2020-21 9
L’inizializzazione di array - 4 Se vengono specificati i valori iniziali, può essere omessa la dimensione dell’array: il compilatore calcola automaticamente il numero degli elementi sulla base del numero dei valori iniziali specificati Esempio: static char dr[] = {‘a’, ‘b’, ‘c’, ‘d’}; comporta la creazione di un array di quattro elementi, di tipo char, caratterizzati dai valori iniziali dr[0] = ‘a’ dr[1] = ‘b’ dr[2] = ‘c’ dr[3] = ‘d’ Fondamenti di Informatica I - a.a. 2020-21 10
Uscita dal limite superiore di un array Il compilatore, di solito, non controlla che l’accesso agli elementi di un array venga effettuato rispettandone i limiti dimensionali ⇨ È possibile accedere per errore ad elementi per i quali non è stata allocata memoria (aree di memoria riservate ad altre variabili, riservate ad altri processi, etc.) Esempio: Essendo ar un array di 10 elementi, main() quelli cui è possibile accedere in modo { int ar[10], j; corretto hanno indice da 0 a 9: il ciclo for contiene un errore off-by-one for (j= 0; j
Crittografia - 1 Poiché in formato elettronico viene memorizzato e trasmesso ogni tipo di informazione (anche personale, quindi coperta dalla privacy), viene posta attenzione alla sicurezza rispetto ad accessi indesiderati I file, nei sistemi multiutente, sono provvisti di vari livelli di protezione, il primo dei quali è costituito dall’autenticazione al sistema tramite password Oltre ai tipi di protezione standard, il contenuto di un file riservato può essere codificato, utilizzando tecniche crittografiche che producono, a partire dal testo in chiaro, il cosiddetto crittogramma, o testo cifrato Il legittimo proprietario del file (e chi da lui autorizzato) è l’unico depositario della chiave di decodifica ed è quindi l’unico in grado di operare l’inversione da testo cifrato a testo in chiaro Fondamenti di Informatica I - a.a. 2020-21 12
Crittografia - 2 Inoltre, negli attuali sistemi informativi distribuiti, e più in generale nel settore delle telecomunicazioni, la crittografia ha assunto rilievo ed interesse crescenti nelle infrastrutture di sicurezza Fondamenti di Informatica I - a.a. 2020-21 13
Crittografia - 3 Se il sistema di cifra, o cifrario, è ben congegnato, l’operazione di decifrazione o decifratura deve risultare semplice al legittimo proprietario (o al destinatario del messaggio), ma di complessità proibitiva alla “spia” ⇨ possibile in quanto gli utenti “legittimi” possiedono un’informazione che deve rimanere inaccessibile alla spia, la chiave del cifrario Occorre notare la distinzione tra decifrazione e decrittazione, l’operazione illegittima in cui non ci si può avvalere della chiave Fondamenti di Informatica I - a.a. 2020-21 14
Crittografia - 4 /* Dato un carattere, ne fornisce un valore codificato */ #define ILLEGAL_VAL -1 Ciao 48=‘0’ ⇨ 114=‘r’ char encode(ch) char ch; { 9G_5 static unsigned char encoder[128] = {127, 124, 121, 118, 115, 112, 109, 106, 103, 100, 97, 94, 91, 88, 85, 82, 79, 76, 73, 70, 67, 64, 61, 58, 55, 52, 49, 46, 43, 40, 37, 34, 31, 28, 25, 22, 19, 16, 13, 10, 7, 4, 1, 126, 123, 120, 117, 114, 111, 108, 105, 102, 99, 96, 93, 90, 87, 84, 81, 78, 75, 72, 69, 66, 63, 60, 57, 54, 51, 48, 45, 42, 39, 36, 33, 30, 27, 24, 21, 18, 15, 12, 9, 6, 3, 0, 125, 122, 119, 116, 113, 110, 107, 104, 101, 98, 95, 92, 89, 86, 83, 80, 77, 74, 71, 68, 65, 62, 59, 56, 53, 50, 47, 44, 41, 38, 35, 32, 29, 26, 23, 20, 17, 14, 11, 8, 5, 2} /* Controlla la presenza di caratteri illeciti */ if (ch > 127) return ILLEGAL_VAL; else return encoder[ch]; /* Fornisce il carattere codificato */ } Fondamenti di Informatica I - a.a. 2020-21 15
Crittografia - 5 Il codice Shift Cypher con K=3 era utilizzato da Giulio Cesare Esercizio: Con K=11, si somma 11 al valore corrispondente alla lettera e, nel caso che la somma superi 25, si divide il numero per 26 e si considera il resto della divisione intera we will meet at midnight 22 4 22 8 11 11 12 4 4 19 0 19 12 8 3 13 8 6 7 19 ß 7 15 7 19 22 22 23 15 15 4 11 4 23 19 14 24 19 17 18 4 hphtwwxppelextoytrse Fondamenti di Informatica I - a.a. 2020-21 16
Gli algoritmi di ordinamento - 1 L’ordinamento di una sequenza di informazioni consiste nel disporre le stesse informazioni in modo da rispettare una qualche relazione d’ordine; ad esempio, una relazione d’ordine “minore o uguale” dispone le informazioni in modo “non decrescente” L’ordinamento è un’operazione molto importante perché permette di ridurre notevolmente i tempi di ricerca di un’informazione, nell’ambito di una sequenza di informazioni Nel caso in cui tale sequenza risulta ordinata, secondo una qualche relazione d’ordine, è infatti possibile sfruttare la stessa relazione d’ordine per effettuare la ricerca Fondamenti di Informatica I - a.a. 2020-21 17
Gli algoritmi di ordinamento - 2 Esistono due categorie di algoritmi di ordinamento: la classificazione è fatta in base alla complessità di calcolo e alla semplicità algoritmica La complessità di calcolo si riferisce al numero di operazioni necessarie all’ordinamento; tali operazioni sono essenzialmente confronti e scambi tra gli elementi dell’insieme da ordinare La semplicità algoritmica si riferisce alla lunghezza e alla comprensibilità del codice Fondamenti di Informatica I - a.a. 2020-21 18
Gli algoritmi di ordinamento - 3 Algoritmi semplici di ordinamento Algoritmi che presentano complessità O(n2), dove n è il numero di informazioni da ordinare: sono caratterizzati da poche e semplici istruzioni, dunque si realizzano con poche linee di codice Algoritmi evoluti di ordinamento Algoritmi che presentano complessità computazionale O(n*log2n): sono più complessi, fanno spesso uso di ricorsione; la convenienza del loro utilizzo si rileva quando il numero n di informazioni da ordinare è molto elevato Fondamenti di Informatica I - a.a. 2020-21 19
Bubblesort - 1 La strategia Bubblesort (ordinamento a bolla) prevede il confronto dei primi due elementi di un array, e lo scambio, se il primo è maggiore del secondo Dopo il primo confronto, si effettua un confronto fra il secondo ed il terzo elemento (con eventuale scambio), fra il terzo ed il quarto, etc. Gli elementi “pesanti” (grandi) tendono a scendere verso il fondo del vettore, mentre quelli “leggeri” (più piccoli) salgono (come bolle) in superficie Fondamenti di Informatica I - a.a. 2020-21 20
Bubblesort - 2 Il confronto fra tutte le coppie di elementi adiacenti viene detto passaggio Se, durante il primo passaggio, è stato effettuato almeno uno scambio, occorre procedere ad un ulteriore passaggio Ad ogni passaggio, almeno un elemento assume la sua posizione definitiva (l’elemento più grande del sottoinsieme attualmente disordinato) Devono essere effettuati al più n-1 passaggi Al k-esimo passaggio vengono effettuati n-k confronti (con eventuali scambi): almeno k-1 elementi sono già ordinati Complessivamente, vengono effettuati n*(n-1)/2 confronti Þ La complessità computazionale del Bubblesort è O(n2) Fondamenti di Informatica I - a.a. 2020-21 21
Bubblesort - 3 #define FALSE 0 #define TRUE 1 Nota #include Nel caso migliore, void bubble_sort(list, list_size) quando il vettore è int list[], list_size; già ordinato, si { effettua un solo int j, temp, sorted=FALSE; passaggio, con n-1 while (!sorted) { confronti e nessuno sorted = TRUE; /* assume che list sia ordinato */ scambio for (j=0; jlist[j+1]) scende a O(n) { /* almeno un elemento non è in ordine */ sorted = FALSE; temp = list[j]; list[j] = list[j+1]; list[j+1] = temp; } } /* fine del ciclo for */ } /* fine del ciclo while */ } Fondamenti di Informatica I - a.a. 2020-21 22
Numeri casuali Non è possibile generare veri numeri casuali con un calcolatore o con qualsiasi metodo deterministico. Quello che viene fatto è scrivere programmi di generazione che producono sequenze di numeri con il maggior numero possibile di proprietà dei numeri casuali (numeri pseudo-casuali). Alcune proprietà sono più importanti di altre nel simulare i numeri casuali (es. data una sequenza di numeri pseudo-casuali, ci aspettiamo che alcuni numeri compaiano più di una volta ed altri mai. Se tutti comparissero una volta non avremmo una serie di numeri casuali). Ogni numero deve avere la stessa probabilità di essere generato. Fondamenti di Informatica I - a.a. 2020-21 23
Numeri casuali - 2 Esempio di algoritmo per generare una sequenza di N numeri pseudo- casuali compresi tra 0 e m-1: a[1]=a1 for (i=2, i
Numeri casuali - 3 In C il generatore di numeri random è l’operatore rand(). L’istruzione: i = rand (); genera un intero compreso tra 0 e RAND_MAX, valore definito nella libreria (che dovrete quindi sempre includere nell’usare questo operatore). Il valore di RAND_MAX nello standard ANSI è almeno 32767. La distribuzione nell’intervallo è uniforme. Fondamenti di Informatica I - a.a. 2020-21 25
Numeri casuali - 4 Per ottenere una serie di altri numeri, si utilizza rand in congiunzione con l’operatore resto. Ad esempio rand() % 6 (6 si chiama il fattore di scala) genera degli interi nell’intervallo tra 0 e 5. Per traslare la serie di valori, basterà aggiungere un intero all’istruzione, che viene detto valore di traslazione. In generale avremo quindi che: n = a + rand() % b genererà numeri interi random nell’intervallo desiderato. Fondamenti di Informatica I - a.a. 2020-21 26
La direttiva #define La direttiva #define consente di associare un nome ad una costante Esempio: #define NIENTE 0 associa il nome “NIENTE” alla costante 0 Per evitare confusione fra nomi di costanti e nomi di variabili, è pratica comune usare solo lettere maiuscole per le costanti e solo minuscole per le variabili L’associazione di nomi alle costanti permette… …di semplificare la modifica del software: cambiare il valore ad una costante equivale a cambiarne la sola definizione e non tutte le occorrenze !!! Fondamenti di Informatica I - a.a. 2020-21 27
Puoi anche leggere