Allocazione dinamica delle matrici, alcune funzioni di libreria, parametri del main, classificazione delle variabili

OBIETTIVO DELLA LEZIONE
  1. Conoscere le tecniche di allocazione dinamica delle matrici
  2. Conoscere le funzioni per la generazione pseudocasuale di numeri
  3. Conoscere i parametri del main
  4. Comprendere la classificazione delle variabili in C
.:. LUCIDI DELLA LEZIONE .:.

Lab

Prima di iniziare

Rileggi velocemente i lucidi della lezione di stamattina. I costrutti presentati saranno molto utili per risolvere gli esercizi di oggi.

Esercizio 1: Allocazione dinamica delle matrici
Si prenda il codice C visto a lezione di stampamatrice.c e aggiungere la disallocazione corretta della memoria.
#include <stdio.h>
#include <stdlib.h>

void prt (double **a, int n, int m);
int main()
{
   int i,j, n,m;
   double **a; 
   n=4;
   m=5;
   a= (double**) calloc (n, sizeof(double*));
   for(i=0; i < n; i++)
       a[i]= (double*) calloc (m, sizeof(double));
   for(i=0; i < n; i++)
      for(j=0; j < m; j++)
        a[i][j]= i*j;   
   prt(a,n,m);
   
   // disallocare correttamente la memoria

   getchar();     
   return 0;
}
void prt (double **a, int n, int m)
{
   int i,j;
   for(i=0; i < n; i++){
      for(j=0; j < m; j++)
         printf("%5.0f\t",a[i][j]);
      printf("\n");
   }
}



soluzione.
Esercizio 2: Allocazione dinamica delle matrici
Crea il programma traccia.c che contiene una funzione traccia() che:
  • prenda come parametro una matrice quadrata, di interi, di dimensione qualsiasi e la relativa dimensione (ricorda che una matrice quadrata ha lo stesso numero di righe e di colonne, quindi basta passare solo una dimensione);
  • calcoli la traccia della matrice (ovvero la somma degli elementi che stanno sulla diagonale principale: a[i][i]);
  • restituisca tale somma.
#include <stdio.h>
#include <stdlib.h>

// prototipo della funzione "traccia"

int main()
{
	//dichiarazione di una matrice allocata dinamicamente
  // allocazione della matrice con 5 righe e 5 colonne
  
  // riempo la matrice
  for(i=0; i< n; i++)
      for(j=0; j<n; j++)
       a[i][j]= i+j;   
  
  //chiamata della funzione "traccia" sulla matrice
  
  // disallocazione della matrice


}  // main

// definizione della funzione "traccia"


soluzione.
Esercizio 3: Allocazione dinamica corretta delle matrici
Si noti che quando abbiamo allocato le matrici dinamiche non ci siamo curati di gestire possibili errori di memoria. Si scriva un programma che:
  • durante l'allocazione controlli che tutto vada bene (ovvero che i puntatori siano diversi da NULL) ;
  • se un puntatore e' NULL disallochi correttamente tutta la memoria allocata fino a quel punto.
#include <stdio.h>
#include <stdlib.h>

int main()
{
  int i,j, n,m;
  int **a; 
  a= (int**) calloc (n, sizeof(int*));
  // controllo l'allocazione
   for(i=0; i< n; i++){
       a[i]= (int*) calloc (m, sizeof(int));
       // controllo l'allocazione 
       // se ho un puntatore a NULL disalloco 
       // la memoria allocata fino a qui
   }
  
   
  // disallocazione della matrice


}  // main



soluzione.
Esercizio 4: generazione di numeri pseudocasuali
La funzione rand() restituisce valori nell'intervallo [0, RAND_MAX]:
  • si dichiari una variabile media di tipo double inizializzata al valore RAND_MAX/2.0;
  • si stampi tale valore su terminale;
  • si scriva un programma che chiami rand() 1000 volte in un ciclo for che aggiorni le variabili sopra_media e sotto_media che contengono rispettivamente il numero di volte che rand() ha restituito un valore sopra la media e uno sotto la media.;
  • ad ogni esecuzione del ciclo for si stampi la differenza tra due valori di sopra_media e sotto_media: tale valore dovrebbe oscillare intorno allo 0, riscontrate questo comportamento?


soluzione.
Esercizio 5: generazione di numeri pseudocasuali tra 0 e 1
La funzione rand() restituisce valori nell'intervallo [0, RAND_MAX]:
  • scrivere una funzione rand01() che utilizzando la funzione rand() restituisca uniformemente un numero reale tra 0 e 1;
  • scrivere una funzione randDado() che utilizzando la funzione rand() restituisca uniformemente un numero intero tra 1 e 6 (simulando il lancio di un dado);
  • utilizzare queste due funzioni nel main
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
// prototipi delle due funzioni
 
int main()
{
  // inizializzare il seme di rand()

  for(i=0;i<10;i++)
      printf("Numero casuale tra 0 e 1: %.5f\n", rand01());
   for(i=0;i<10;i++)
      printf("Tiro un dado ed esce: %d\n", randDado());

}  // main

// definizione delle due funzioni



soluzione.
Esercizio 6: time e clock
Scrivere un programma con un tempo di esecuzione abbastanza lungo (per esempio che usa un for ripetuto almeno 10000000 volte) e
  • valutare il tempo di esecuzione con la funzione time() ;
  • valutare il tempo di esecuzione con la funzione clock() ;
  • confrontare i due risultati: sono diversi? Perche'?
Esercizio 7: clock e for infiniti
I seguenti comandi for ciclano all'infinito? Per ciascun ciclo che termina scrivere un breve programma che lo include e ne verifica il tempo di esecuzione con la funzione clock():
  • int i; for (i = 0 ; i < 999999999 ; i++);
  • int i; for (i = 100 ; i > 0 ; i++);
  • short i; for (i = 100 ; i > 0 ; i++);
  • for ( ; ; );


soluzione.
Esercizio 8: parametri del main
Utilizzando la traccia di codice sotto riportata, crea il programma copiaVocali.c che:
  • dati due nomi di file come argomenti della riga di comando, copi tutte le vocali del primo file nel secondo;
  • provare ad eseguire il programma settando correttamente i parametri in DevC
#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char *argv[])
{
   FILE * file_in;
   FILE * file_out;
   char c;
  
   // controllo che il numero di argomenti passati sia corretto (vedi lucidi della lezione)
   
   
   // apro il file da copiare
   
   
   // apro il file in cui copiare le vocali del primo 
   
      
   // eseguo la copia
      
   // chiudo i file  
   

   fflush(stdin);
   return 0;
}



soluzione.
Esercizio 9: parametri del main
Utilizzando la traccia di codice sotto riportata, crea il programma confronta.c che:
  • dati due nomi di file come argomenti della riga di comando, confronti il loro contenuto;
  • e scriva a terminale se i due file sono identici o meno.
#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char *argv[])
{
   FILE * file_in;
   FILE * file_out;
   char c;
  
   // controllo che il numero di argomenti sia corretto
   
   
   // apro i due file passati come parametri del main
   
   
   // scorro contemporaneamente i due file per verificare che siano uguali
   
      
   // chiudo i file
      
      
   

   fflush(stdin);
   return 0;
}



soluzione.
Esercizio 10: parametri del main
Utilizzando la soluzione dell'esercizio precedente, crea il programma confronta2.c che:
  • dati due nomi di file e un intero positivo come argomenti della riga di comando, confronti il contenuto dei due file;
  • e scriva a terminale se il numero di caratteri diversi tra i due file e' inferiore o superiore all'intero dato.


soluzione.
Esercizio 11: variabili locali static
Utilizzando la traccia di codice sotto riportata, crea il programma MissItaliaNew.c che modifichi solo la funzione inserisci utilizzando una variabile locale di tipo static per inserire la miss nuova nell'array passato (la variabile statica serve a mantenere il conto della prima posizione libera nel vettore dove inserire la nuova miss).
#include <stdio.h>
#include <stdlib.h>

typedef struct	{
	char nome[256] ;
	char cognome[256] ;
	int voto[3];  	// voto[0] e' il voto della giuria (da 0 a 100),
	             	  // voto[1] quello della giuria speciale e voto[2] il voto
	             	  // telefonico.
	int altezza;
	int peso;
	int cucina;    	// 0= aiuto!!!  10= apre un ristorante
} MissItalia;     	// Iniziale maiuscola


void inserisci(MissItalia *Concorso);  // chiede una miss all'utente 
                                       // e la inserisce nella prima posizione
                                       // libera di Concorso
void stampa_concorso(MissItalia *Concorso, int dim); // stampa tutte le miss
int main()
{

    MissItalia *Concorso;
    int dim;
    int i;
  
    printf("Quante miss sono in concorso? --> ");
    scanf("%d", &dim); 
   
    // inizializza il vettore Concorso che contiene tutte le miss
    Concorso = (MissItalia *) calloc (dim, sizeof(MissItalia));
    if (Concorso == NULL) {
      printf("E' finita la memoria");
      exit(-1);
    }
    
    
    for (i=0; i<dim; i++)
      inserisci(Concorso); 
   
    
  
    stampa_concorso(Concorso, dim);  
   
    free(Concorso);
    
    fflush(stdin);	
    getchar();	
    exit(0);
}

void inserisci(MissItalia *Concorso)
{
   // dichiarare la variabile indice di tipo static
   
   // inserire il nome e il cognome in posizione indice del'array richiesti all'utente
   
   Concorso[indice].altezza = 180;
   Concorso[indice].voto[0] = 80;
   Concorso[indice].voto[1] = 90;
   Concorso[indice].voto[2] = 99;
   Concorso[indice].peso    = 78;
   Concorso[indice].cucina  = 0;  // aiuto!!!
   
   //aggiornare la variabile indice per inserire la prossima miss
}




void stampa_concorso(MissItalia *Concorso, int dim)  // stampa il nome di tutte le miss in Concorso
{
   int i;
   for (i=0; i<dim; i++)
      printf("\n\n miss %s ", Concorso[i].nome);
}




soluzione.




Informazioni sul sito