Le Matrici


Lo scopo della lezione di oggi e' prendere confidenza con gli array a piu' dimensioni, e piu' in particolare con le matrici bi-dimensionali.


Iniziamo con un semplice programma che calcola la trasposta di una matrice.

  



Calcolare la trasposta di una matrice

Vogliamo scrivere un programma che, presa in ingresso una matrice 4x3 di valori interi compresi fra 0 e 100 (estremi inclusi), visualizza sullo schermo la matrice letta e la sua trasposta

  1. Invochiamo l'editor per scrivere il codice sorgente del nostro progamma
  2. > emacs trasposta.c &
  3. Digitare il seguente testo all'interno della finestra dell'editor:

/* Programma per calcolare la trasposta di una

matrice letta in ingresso */

#include <stdio.h>

#include <stdlib.h>


#define RIGHE 4

#define COLONNE 3

#define MINIMO 0

#define MASSIMO 100

 

int main () {

  

  //dichiarazione della matrice 

  //e di due variabili ausiliarie

  int matrice[RIGHE][COLONNE];

  int i,j;

  

  //legge i valori della matrice, controllando 

  //che siano nel giusto intervallo


  for(i=0;i<RIGHE;i++)

   for(j=0;j<COLONNE;j++)

    do{

    printf("inserisci l'elemento matrice[%d][%d]",i,j);

    scanf("%d\n",&matrice[i][j]);

    } while (matrice[i][j]<MINIMO || matrice[i][j]> MASSIMO);


  printf("\n");


  //stampa la matrice letta


  printf("matrice di ingresso\n");

  printf("+--------------+\n"); 


  for(i=0;i<RIGHE;i++){

   printf("|");

   for(j=0;j<COLONNE;j++)

    printf("%4d",matrice[i][j]);

   printf("  |\n");

   }

   printf("+--------------+\n");


   //stampa la matrice trasposta


  printf("matrice trasposta\n");

  printf("+------------------+\n"); 


  for(j=0;j<COLONNE;j++){

   printf("|");

   for(i=0;i<RIGHE;i++)

    printf("%4d",matrice[i][j]);

   printf("  |\n");

   }

   printf("+------------------+\n");

   return EXIT_SUCCESS;

 

}


Il programma e' molto semplice. 

Inizialmente vengono letti i valori della matrice di ingresso, controllando che il valore inserito sia compreso nell'intervallo
[MINIMO, MASSIMO] (notare l'uso delle costanti simboliche per definire gli estremi dell'intervallo). Per leggere i valori della matrice utilizzo due cicli for annidati uno dentro l'altro. Questo e' il modo standard per leggere e stampare i valori di una matrice.

Dopo aver letto la matrice di ingresso, stampo sia la matrice di ingresso che la sua trasposta, utilizzando nuovamente i due cicli for annidati. Per stampare la matrice trasposta basta invertire l'ordine delle variabili ausiliarie utilizzate per scorrere gli elementi della matrice. 

Notare l'opzione %4d utilizzata per visualizzare gli interi usando quattro caratteri. Questo permette di ottenere un output allineato anche se i numeri che compongono la matrice sono composti da un numero diverso di cifre (1, 2 o 3).

3. Compiliamo il codice sorgente

> gcc -otrasponi trasposta.c


4. Eseguiamo il programma

> ./trasponi





Redirezione dell'input

Abbiamo gia' visto nelle lezioni scorse come redirigere l'output di un programma in un file di testo, usando l'opzione > nome_file.txt.

Possiamo fare una cosa simile per l'input, specificando il nome di un file di testo da cui il programma deve estrarre i dati di input. 

NOTA BENE: il file di input deve essere stato creato precedentemente!!!!

Vediamo ad esempio come prendere l'input del programma precedente da un file, precedentemente creato, chiamato valori_matrice.txt.

1. Creiamo un file di testo che contiene i valori della matrice (12 valori, separati dal ritorno a capo):

> emacs valori_matrice.txt


2. Invochiamo il progamma trasponi.c, specificando il file valori_matrice.txt come file di ingresso:

> .\trasponi < valori_matrice.txt




Cosa accade se uno dei valori nel file di ingresso non e' compreso nell'intervallo? 


Questo valore viene scartato, e nella matrice viene inserito il valore successivo. Bisogna dunque stare attenti che il file di ingresso contenga un numero sufficiente (almeno 12) di valori nell'intervallo richiesto.






Inizializzazione di una matrice


Esiste un modo rapido di inizializzare una matrice, direttamente quando questa viene dichiarata. 


E' sufficiente elencare i valori che la compongono, riga per riga.


Ad esempio, riferendoci all'esercizio precedente, potremmo scrivere:

int matrice[RIGHE][COLONNE] = {{10,12,14},
                               {34,56,100},
                               {23,35,46},
                               {14,53,4}  };


NOTA BENE: Se nell'inizializzazione specifico meno valori di quelli presenti nella matrice, i valori rimanenti sono inizializzati automaticamente a 0.

Esempio: provare ad inizializzare la matrice come segue:

int matrice[RIGHE][COLONNE] = {{10,12}};


Esempio: modo compatto per inizializzare tutti gli elementi di un vettore a 0:

int tabellone[90] = {0};

Se il numero di inizializzatori e' maggiore del numero degli elementi della matrice, viene segnalato un errore in fase di compilazione!



Esercitazione non guidata

Risolvere il seguente esercizio e spedire il solo file sorgente (suffisso .c) all'indirizzo paolo.santi@iit.cnr.it come attachment di un messaggio di posta elettronica con subject: Esercitazione Lezione 5.2, indicando il vostro nome, cognome e gruppo di appartenenza.

Esercizio:


Un automa deterministico a stati finiti può essere rappresentato con una matrice automa di dimensione N x M dove N è il numero di stati ed M è il numero di simboli dell'alfabeto: la casella automa[i][j] contiene il valore dello stato raggiungibile dallo stato i leggendo il simbolo j. Se nessuno stato è raggiungibile, allora la casella contiene il valore speciale N + 1.

Assumendo che lo stato iniziale sia 0 e che l'automa sfrutti l'alfabeto {0,1,2}, scrivere un programma automa.c che simuli il comportamento dell'automa definito dalla matrice:


  0 1 2

 +-+-+-+

0|1|4|2|

 +-+-+-+

1|4|0|4|

 +-+-+-+

2|1|3|2|

 +-+-+-+

3|4|4|2|

 +-+-+-+


con unico stato finale 2.

Il programma si compone di un ciclo che ad ogni iterazione legge da tastiera un valore intero n compreso tra 0 e 3, estremi inclusi.

Sapreste descrivere le sequenze di simboli che vengono riconosciute con successo?




Torna alla HomePage del corso