Il linguaggio C Gli array I numeri casuali La direttiva DEFINE - Dichiarazione e memorizzazione di array L'inizializzazione di array La ...

Pagina creata da Sabrina Palmieri
 
CONTINUA A LEGGERE
Il linguaggio C Gli array I numeri casuali La direttiva DEFINE - Dichiarazione e memorizzazione di array L'inizializzazione di array La ...
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
Il linguaggio C Gli array I numeri casuali La direttiva DEFINE - Dichiarazione e memorizzazione di array L'inizializzazione di array La ...
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