Esempi di codice in linguaggio C visti durante le esercitazioni

Daniele Paolo Scarpazza

Indice delle esercitazioni



Esercitazione del 21 ottobre 2003
/*****************************************************
 Maggiore tra n numeri 
 La sequenza è terminata dall'inserimento del numero 0 */
 
#include <stdio.h>
int numero, massimo;

main()
{
 printf("\nInserisci il numero: ");
 scanf("%d", &numero);
 massimo=numero;

 while (numero!=0)
 {
  printf("Inserisci il numero: \n");
  scanf("%d", &numero);

  if (numero>massimo)
   massimo=numero;
 }

 printf("Il massimo è %d.\n",massimo);
}

/*****************************************************
 Calcolo di x^n */

#include <stdio.h>
float x, pot=1;
int n, cont=1;

main()
{
 printf("\nInserire x e n :\n");
 scanf("%f  %d", &x, &n);

 while (cont<=n)
 {
  pot=pot*x;
  cont++;
 }
 printf("il risultato di %f elevato a %d è %f", x, n, pot);
}

/*****************************************************
 Calcolo di n! - Prima versione */

#include <stdio.h>
main ()
{
   int numero,i=1,fattoriale=1;
   printf("Inserisci il numero: ");
   scanf("%d",&numero);

   while (i<=numero)
   {
      fattoriale=fattoriale*i;
      i++;
   } 
   printf("Il fattoriale di %d è %d\n", numero, fattoriale);
}

/*****************************************************
 Calcolo n! - Seconda versione */
#include <stdio.h>
main ()
{
   int numero, i,fattoriale=1;
   printf("Inserisci il numero: ");
   scanf("%d",&numero);

   for (i=1; i<=numero; i++) fattoriale *= i;
  
   printf("Il fattoriale di %d è %d\n", numero, fattoriale);
}

/*****************************************************
 Conversione da base 10 a base 2 - Prima versione */
#include <stdio.h>
main()
{
  int  n, pos;
  char risultato[]="                                ";
  printf("Inserisci il numero da convertire: ");
  scanf("%d",&n);
  pos = strlen(risultato)-1;

  while (n !=0)
    {
      if (n % 2 == 1) 
	risultato[pos]='1';
      else
	risultato[pos]='0';
	
      pos--;
      n = n/2;
    }  
  printf("%s\n",risultato);
}


/*****************************************************
 Conversione da base 10 a base 2 - Seconda versione */
#include <stdio.h>
main()
{
  int  n, pos;
  char risultato[]="                                ";
  printf("Inserisci il numero da convertire: ");
  scanf("%d",&n);

  for (pos = strlen(risultato)-1; n!=0; n/=2)
      risultato[pos--]='0' + n%2;      	
  
  printf("%s\n",risultato);
}


/*****************************************************
 Conversione da base 10 a base 2 - Terza versione */
#include <stdio.h>
main()
{
  int  n, pos;
  char risultato[]="                                ";
  printf("Inserisci il numero da convertire: ");
  scanf("%d",&n);

  for (pos=31; n!=0; n>>=1) risultato[pos--]='0' + (n & 1);      	      
  printf("%s\n",risultato);
}

/*****************************************************
 Conversione da base 2 a base 10 - Prima versione */
#include <stdio.h>
#include <stdlib.h>
main()
{
  int  n       = 0, 
       potenza = 1,
       pos;
  char ingresso[32+1];

  printf("Inserisci il numero da convertire: ");
  gets(ingresso);

  pos = strlen(ingresso)-1;
  while (pos>=0)
    {    
      switch(ingresso[pos])
	{
	case '0' : 
	  break;	  
	case '1' :
	  n += potenza;
	  break;
	default  : 
	  printf("Ingresso non valido\n");
	  exit(-1);	  
	}
      potenza *= 2;
      pos--;
    }
  printf("%d\n",n);
}

/*****************************************************
 Conversione da base 2 a base 10 - Seconda versione */
#include <stdio.h>
#include <stdlib.h>

main()
{
  int  n       = 0, 
       ordine  = 0,
       pos;
  char ingresso[32+1];

  printf("Inserisci il numero da convertire: ");
  gets(ingresso);
  
  for (pos = strlen(ingresso)-1; pos>=0; pos--)
    {    
      switch(ingresso[pos])
	{
	case '0' : 	  
	case '1' : n += (ingresso[pos]-'0') * (1 << ordine++);  break;
	default  : printf("Ingresso non valido\n");             exit(-1);	  
	}     
    }
  
  printf("%d\n",n);
}

/*****************************************************
 Conversione da base 2 a base 10 - Terza versione */
#include <stdio.h>
#include <stdlib.h>

main()
{
  int  n = 0, pos;
  char ingresso[32+1];

  printf("Inserisci il numero da convertire: ");
  gets(ingresso);
  
  for (pos = 0; ingresso[pos]; pos++)
    {    
      n <<= 1;
      switch(ingresso[pos])
	{
	case '0' :      break;	  
	case '1' : n++; break;
	default  : printf("Ingresso non valido\n"); exit(-1);	  
	}           
    }  
  printf("%d\n",n);
}

/*****************************************************
 Conversione da base 2 a base 10 - Quarta versione */
#include <stdio.h>
#include <stdlib.h>
main()
{
  int  n = 0, pos;
  char ingresso[32+1];

  printf("Inserisci il numero da convertire: ");
  gets(ingresso);
  
  for (pos = 0; ingresso[pos]; pos++)
    {          
      n<<=1;
      switch(ingresso[pos])
	{
	case '1' : n |=  1;
	case '0' : break;	  
	default  : printf("Ingresso non valido\n"); exit(-1);	  
	}           
    }  
  printf("%d\n",n);
}

Esercitazione del 22 ottobre 2003
/*****************************************************
 Chiedo in ingresso un vettore di 10 reali e li stampo
 in ordine inverso rispetto a quello di inserimento */

#include <stdio.h>
#define DIMENSIONE 10

float vettore[DIMENSIONE]; 
int i;     

main()
{
  for (i=0;i<DIMENSIONE;i++) {
    printf("\n Elemento (%d/%d): ", i+1, DIMENSIONE);
    scanf("%f", &vettore[i]);
  }
  
  printf("\nVettore: ");
  
  for (i=DIMENSIONE-1;i>=0;i--)
    printf("%.2f ", vettore[i]);
}

/** Esempio di esecuzione:
    
 Elemento (1/10): 2
 Elemento (2/10): 33
 Elemento (3/10): 12
 Elemento (4/10): 3 
 Elemento (5/10): 6
 Elemento (6/10): 7
 Elemento (7/10): 8
 Elemento (8/10): 9 
 Elemento (9/10): 100 
 Elemento (10/10): 0

Vettore: 0.00 100.00 9.00 8.00 7.00 6.00 3.00 12.00 33.00 2.00 
*/



/****************************************
 Ordinamento di un vettore di 20 elementi 
*/

#include <stdio.h>

#define DIMENSIONE 20  
#define VERO        1
#define FALSO       0
#define bool      int

int     sequenza[DIMENSIONE]; 
int     i;        
bool    finito = FALSO;             
int     temp;         

main()
{
  for (i=0; i<DIMENSIONE; i++) {
    printf("\nElemento (%d): " , i+1);
    scanf("%d", &sequenza[i]);
  }
  
  while (!finito) {
    finito = VERO; 
    for (i=0; i<DIMENSIONE-1; i++)
      if (sequenza[i]>sequenza[i+1])
	{
	  temp          = sequenza[i];
	  sequenza[i]   = sequenza[i+1];
	  sequenza[i+1] = temp;
	  finito = FALSO;
	}      
  }
  
  printf("\nOrdinato: ");
  for (i=0; i<DIMENSIONE; i++)  
    printf("%d ", sequenza[i]);	
}

/** Esempio di esecuzione:
 
Elemento (1): -10
Elemento (2): 100
Elemento (3): 3
Elemento (4): 4
Elemento (5): 55
Elemento (6): -45
Elemento (7): 3
Elemento (8): 2
Elemento (9): 5
Elemento (10): 11
Elemento (11): 11
Elemento (12): 0
Elemento (13): 90
Elemento (14): 12
Elemento (15): 31
Elemento (16): 51
Elemento (17): 66
Elemento (18): -89
Elemento (19): -5
Elemento (20): 4
Ordinato: -89 -45 -10 -5 0 2 3 3 4 4 5 11 11 12 31 51 55 66 90 100 
*/



/****************************************
 Mostra l'elemento massimo in una matrice 
 di numeri letti dall'utente
*/

#include <stdio.h>

#define RIGHE 3
#define COLONNE 4

int matrice[RIGHE][COLONNE];   
int r, c;                        
int val_max, riga_max, col_max;  

main()
{
  for (r=0; r<RIGHE; r++)
    for (c=0; c<COLONNE; c++) {	
      printf("\nElemento (%d,%d): ", r+1, c+1);
      scanf("%d", &matrice[r][c]);	
    }
  
  /* inizializzazione del massimo */
  val_max=matrice[0][0];
  riga_max=0;
  col_max=0;
  
  /* scansione della matrice */
  for (r=0; r<RIGHE; r++)
    for (c=0; c<COLONNE; c++)
      if (matrice[r][c]>val_max) {
	val_max=matrice[r][c];
	riga_max=r;
	col_max=c;
      }
  
  printf("\nIl massimo è %d, in posizione (%d,%d)", 
	 val_max, riga_max+1, col_max+1);
  
  /** Domande:
      -quale comportamento mostra il programma se 
       esistono due elementi massimi?
      -come modifichereste il programma per ottenere 
       il comportamento opposto?
  */
}



/************************************************
 Gestisce una serie di 10 elementi interi */

#include <stdio.h>

#define MAX_NUM 10                  

typedef enum {VUOTA, PIENA} dispon; 

typedef struct {
  int elemento;
  dispon stato;
} cella;                            

cella vett[MAX_NUM];                
int i, operaz, numero;

main()
{
  for (i=0;i<MAX_NUM;i++)
    vett[i].stato=VUOTA;
  /* inizializzazione del vettore */
  
  do {      
    /* richiesta operazione da eseguire */
    printf("\nInserisci l'operazione (0 fine, 1 aggiungi, 2 elimina, 3 visualizza): ");
    scanf("%d",&operaz);
    
    /* elaborazione */
    switch (operaz)
      {
      case 0:
	printf("\nFine Programma!");
	break;
      case 1:
	/* richiesta numero sul quale operare */
	printf("\nInserisci il numero: ");
	scanf("%d",&numero);
	
	/* ricerca cella disponibile */
	for(i=0;i<MAX_NUM;i++) {
	  if (vett[i].stato==VUOTA) {
	    /* inserimento */
	    vett[i].elemento=numero;
	    vett[i].stato=PIENA;
	    break;
	  }
	}
	
	/* verifica inserimento */
	if (i==MAX_NUM)	
	  printf("\nNon ci sono celle disponibili!");
	break;
      case 2:
	/* richiesta numero sul quale operare */
	printf("\nInserisci il numero positivo: ");
	scanf("%d",&numero);
	
	/* ricerca numero nell'array */
	for(i=0;i<MAX_NUM;i++) {
	  if ((vett[i].stato==PIENA) && 
	      (vett[i].elemento==numero)) {
	    /* eliminazione */
	    vett[i].stato=VUOTA;
	    break;
	  }
	}
	  
	if (i==MAX_NUM)
	    printf("\nNumero non presente!");
	break;
      case 3:
	/* visualizzazione array */
	for(i=0;i<MAX_NUM;i++) {
	  if (vett[i].stato==PIENA)
	    printf("\n Posizione %d = %d", i, vett[i].elemento);
	  else
	    printf("\n Posizione %d VUOTA", i);	  
	}
	
	break;
      default:
	printf("\nOperazione non supportata!");
	break;
      }
  } while (operaz!=0); 
}

Esercitazione del 4 novembre 2003
/*****************************************************
 * Calcolo del fattoriale per mezzo di una funzione
 */

#include <stdio.h>
long fattoriale(int); // prototipo

void main ()
{
   int numero;
   printf("Inserisci il numero:");
   scanf("%d",&numero);
   printf("Il fattoriale di %d e' %ld\n", numero,
	   fattoriale(numero));
}

long fattoriale(int num)
{
   int i;
   long fattoriale=1;
   for (i=1;i<=num;i++) fattoriale*=i;
   return fattoriale;
}



/*************************************
 * Esempio di uso di una struct
 */

#include <stdio.h>

#define LUNGH_NOME 50

typedef struct 
{
  char nome    [LUNGH_NOME];
  char cognome [LUNGH_NOME];
  int  anni;	
} Persona;


void ChiediDati(Persona* persona)
{
 printf("Prego inserire i seguenti dati:\n"
 	"Nome: ");
 gets(persona->nome);
 printf("Cognome:");
 gets(persona->cognome);
 printf("Eta':");
 scanf("%i", &persona->anni);
}

void MostraDati(Persona persona)
{
 printf("Dati della scheda:\n"
	"Nome: %s\nCognome: %s\nEta': %i\n",
	persona.nome, persona.cognome, persona.anni);
}

void MostraDati2(Persona* persona)
{
 printf("Dati della scheda:\n"
	"Nome: %s\nCognome: %s\nEta': %i\n",
	persona->nome, persona->cognome, persona->anni);
}

void main ()
{
 Persona persona;
 ChiediDati(&persona);
 MostraDati(persona);
 MostraDati2(&persona);
}








/*************************************
 * Esempio di memorizzazione di schede
 */

#include <stdio.h>
#include <ctype.h>

#define LUNGH_NOME 50
#define NUM_SCHEDE 30

typedef int bool;
const int vero = 1, falso=0;

typedef struct 
{
  char nome    [LUNGH_NOME];
  char cognome [LUNGH_NOME];
  int  anni;	
} Persona;

Persona schede[NUM_SCHEDE];
      
void ChiediDati(Persona* persona)
{
 printf("Prego inserire i seguenti dati:\n"
	"Nome:    ");
 gets(persona->nome);
 printf("Cognome: ");
 gets(persona->cognome);
 printf("Eta':    ");
 scanf("%i", &persona->anni);
}

void MostraDati(Persona* persona)
{
 printf("Dati della scheda:\n"
	"Nome:    %s\nCognome: %s\nEta':    %i\n",
	persona->nome, persona->cognome, persona->anni);
}

void main ()
{
 int i, prossima=0;
 char scelta;

 while (vero) {

  do {
   printf("Vuoi inserire un'altra scheda (S/N)?");
   fflush(stdin);
   scelta = toupper(getchar());
   fflush(stdin);
  } while (scelta!='S' && scelta!='N');

  if (scelta=='N') break;

  ChiediDati(&schede[prossima++]);
 }

 /* pensate al significato della variabile ultima e
    al suo contenuto in questo punto del programma. */
 printf("\n\nSchede inserite:\n");
 for(i=0;i<prossima;i++)
  MostraDati(&schede[i]);
}



/************************************************
 * Come nel caso precedente, ma la stampa avviene
 * in ordine di cognome.
 */

#include <stdio.h>
#include <ctype.h>
#include <string.h>

#define LUNGH_NOME 30
#define NUM_SCHEDE 30

typedef int bool;
const int vero = 1, falso=0;

typedef struct 
{
  int  valida;
  char nome    [LUNGH_NOME];
  char cognome [LUNGH_NOME];
  int  anni;	
} Persona;

Persona schede[NUM_SCHEDE];
      
void ChiediDati(Persona* persona)
{
 printf("Prego inserire i seguenti dati:\n"
	"Nome:    ");
 gets(persona->nome);
 printf("Cognome: ");
 gets(persona->cognome);
 printf("Eta':    ");
 scanf("%i", &persona->anni);
 persona->valida = vero;
}

void MostraDati(Persona* persona)
{
 printf("Dati della scheda:\n"
	"Nome:    %s\nCognome: %s\nEta':    %i\n",
	persona->nome, persona->cognome, persona->anni);
}

void StampaSchede(int massima) {
 char min_cognome [LUNGH_NOME];
 int  i, min_indice;

 printf("\n\nSchede inserite:\n");
 while(vero)
 {
  min_indice = -1;
  strcpy(min_cognome,"zzzzzzzzzzzzzzzzzzzzzzzzzzzz");
  for(i=0; i<=massima; i++)
  {
   if (schede[i].valida && 
       stricmp(schede[i].cognome,min_cognome)<0)
   {
    min_indice=i;
    strcpy(min_cognome,schede[i].cognome);
   }
  }
  if (min_indice==-1) return;
  MostraDati(&schede[min_indice]);
  schede[min_indice].valida=falso;
 }
}

void main ()
{
 int i, prossima=0;
 char scelta;

 for(i=0;i<=NUM_SCHEDE;i++) schede[i].valida = falso;

 while (vero) {
  do {
   printf("Vuoi inserire un'altra scheda (S/N)?");
   fflush(stdin);
   scelta = toupper(getchar());
   fflush(stdin);
  } while (scelta!='S' && scelta!='N');

  if (scelta=='N') break;

  ChiediDati(&schede[prossima++]);
 }

 StampaSchede(prossima-1);
}

Esercitazione del 24 novembre 2003
/***************************************************
 * Confronto fra passaggio di parametri 
 * per valore e indirizzo 
 */

#include <stdio.h>
void change(int, int*);

void main()
{
 int pesche, mele;

 pesche = 5;
 mele   = 7;
 printf("I valori iniziali nel main sono %d %d\n", pesche, mele);
 
 /* La funzione passa per valore pesche e per indirizzo mele */
 change(pesche, &mele); 
 
 /* Solo il valore di mele è stato realmente modificato */
 printf("I valori finali nel main sono %d %d\n",pesche , mele);
}


void change(int my_pesche, int *my_mele)			
{
 printf("Valori iniziali nella funzione %d %d\n",my_pesche, *my_mele);
 my_pesche = my_pesche + 5;
 *my_mele = *my_mele + 10;
 printf("Valori finali nella funzione %d %d\n", my_pesche, *my_mele);
}




/***************************************************
 * Passaggio di parametri di tipo vettore e struttura 
 */
#include <stdio.h>
#include <string.h>
#define MAX 80

/* tipo per contenere il risultato dell'analisi della stringa */
typedef struct
{
 int caratteri;
 int cifre;
} analisi;

/* La funzione conta le lettere e le cifre che compongono   
 * la stringa passata come parametro.
 */
void conteggio(char [],analisi *);

void main()
{
 analisi risultato = {0,0};
 char stringa[MAX];
 /* inserimento stringa */
 printf("\nInserisci la stringa da analizzare: ");
 gets(stringa);
 conteggio(stringa,&risultato);
 printf("\ncifre = %d ; caratteri = %d ",risultato.cifre,risultato.caratteri);
}

/* la funzione conta le lettere e le cifre che compongono la stringa passata come parametro */
void conteggio(char stringa[], analisi *risultato)
{
 int i,l;
 l=strlen(stringa);
 for(i=0;i<l;i++) /* verifica di ciascun carattere */
   if ((stringa[i]>='0') && (stringa[i]<='9'))
     risultato->cifre++;
   else
     risultato->caratteri++;

}



/***************************************************
 * Gestione delle prenotazioni di un cinema 
 */
#include <stdio.h>
#include <string.h>
#define MAX_POSTI  30
#define VERO        1
#define FALSO       0
typedef char string[30];

typedef struct 
{                 /* dati per uno spettatore */
 string cognome;
 string telefono;
} spettatore;             

typedef struct 
{                    /* dati per un posto del cinema */
 int cod_posto;      /* cod_posto è il codice che distingue ciascun posto */
 spettatore cliente; /* viene riempito all'atto di una prenotazione */
 int occupato;       /* vale VERO (1) se il posto è prenotato */
} posto;                  

void inizializza(posto*);                     
int  prenota_posto(posto*, spettatore, int*);  
void stampa_lista_prenotazioni(posto*);

void main()
{
 posto cinema[MAX_POSTI];
 int scelta;
 spettatore spet;
 int posto_prenotato;
 inizializza(cinema);

 do
 {
  printf("\n\n1. Prenotazione posto\n");
  printf("2. Stampa prenotazioni\n");
  printf("0. Uscita\n\n");
  printf("Seleziona una operazione: ");
  scanf("%d", &scelta);
  switch (scelta)
  {
   case 0:  printf("\n\nFine programma"); 
            break;
   case 1:  printf("\nCognome: ");
	    scanf("%s", spet.cognome);
	    printf("Telefono: ");
	    scanf("%s", spet.telefono);
	    if (!prenota_posto(cinema, spet, &posto_prenotato))
	     printf("Prenotazione non effettuata\n");
	    else
              printf("Prenotato posto %d", posto_prenotato);
            break;
   case 2:  stampa_lista_prenotazioni(cinema);
	    break;
   default: printf("\n\nSelezione errata.");
            break;
  }
 } while (scelta!=0);
}


/* Cerca di effettuare una prenotazione.
 * Restituisce il codice di successo come valore di ritorno.
 * Restituisce il numero di prenotazione per indirizzo. 
 */

int prenota_posto(posto lista[], spettatore persona, int* prenotazione)
{
 int i;
 for (i=0;i<MAX_POSTI;i++)
  if (!lista[i].occupato)
   {
    strcpy(lista[i].cliente.cognome, persona.cognome);
    strcpy(lista[i].cliente.telefono, persona.telefono);
    lista[i].occupato = VERO;
    *prenotazione = lista[i].cod_posto;
    return VERO;
   }
 return FALSO;
}

void stampa_lista_prenotazioni(posto *lista)
{
 int i;
 for (i=0;i<MAX_POSTI;i++)
  if (lista[i].occupato)
  {
   printf("\n\nPosto: %d",  lista[i].cod_posto);
   printf("\nCognome: %s",  lista[i].cliente.cognome);
   printf("\nTelefono: %s", lista[i].cliente.telefono);
  }
}

void inizializza(posto lista[])
{
 int i;
 for(i=0;i<MAX_POSTI;i++)
 {
  lista[i].cod_posto = i;
  lista[i].occupato  = FALSO;
 }
}




/***************************************************
 * Sostituzione di una riga in una matrice.
 * Scrivere un programma C che riceve in ingresso una  matrice     
 * quadrata di dimensione prefissata NxN e un vettore 1xN,         
 * entrambi di tipo int; successivamente il programma richiede un  
 * indice di riga r. In output deve essere restituita la matrice   
 * con la riga r-esima sostituita.    
 */

#include <stdio.h>
#define DIM 4        /* dimensione della matrice e del vettore */
void leggi_matrice (int [][]);
void stampa_matrice(int mat[][DIM]);
void leggi_vettore (int*);
void sostituisci   (int mat[][DIM], int*, int);

main()
{
 int i, j;            /* contatori cicli*/
 int r;		      /* indice di riga */

 int matr[DIM][DIM];  /* matrice */
 int vett[DIM];       /* vettore */

 leggi_matrice(matr);
 stampa_matrice(matr);
 leggi_vettore(vett);

 /* lettura da ingresso indice di riga */
 printf("\nInserire l'indice di riga per la sostituzione: ");
 scanf("%d",&r);
 sostituisci(matr, vett, r);

 /* stampa della matrice finale */
 printf("\nMatrice finale:\n\n");
 stampa_matrice(matr);
}

void stampa_matrice(int mat[][DIM])
{
 int i, j;            
 for(i=0;i<DIM;i++)
 {
  for (j=0;j<DIM;j++) printf("%3d ",mat[i][j]);
  printf("\n");
 }
}

/* lettura da ingresso della matrice */
void leggi_matrice(int mat[][DIM])
{
 int i, j;            
 printf("Inserire una matrice quadrata %dx%d: \n\n", DIM, DIM);
 for(i=0;i<DIM;i++)        
  for(j=0;j<DIM;j++)       
   {
    printf("Elemento matrice (%d,%d): ", i, j);
    scanf("%d",&mat[i][j]);
   }
}

void leggi_vettore(int vet[])
{
 int i;            /* contatori cicli*/
 /* lettura da ingresso del vettore */
 printf("\nInserire un vettore 1x%d: \n\n", DIM);
 for(i=0;i<DIM;i++)         /* i sono le righe */
 {
  printf("Elemento vettore %d: ", i);
  scanf("%d",&vet[i]);
 }
}

void sostituisci(int mat[][DIM], int vet[], int indice)
{
 int j;
 /* sostituzione */
 for(j=0;j<DIM;j++) mat[indice][j]=vet[j];
}

Esercitazione del 2 dicembre 2003
/***************************************************************
 * Gestione di un'archivio studenti con una lista dinamica 
 */

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef char string[30];
typedef enum {false=0, true} boolean;

typedef struct { 
  long matricola;
  string cognome;
  string nome;
} DatiStudente;

typedef struct nodo {     
  DatiStudente  dati;       
  struct nodo * prox; 
} Nodo;          

typedef Nodo * Lista;

void    Inizializza(Lista *);
boolean ListaVuota(Lista);
void    LeggiStudente(DatiStudente *);
void    MostraStudente(DatiStudente *);
void    MostraLista(Lista lista);

void    InserisciInTesta(Lista *, DatiStudente);
void    InserisciInCoda(Lista *, DatiStudente);
void    InserisciInCoda2(Lista *, DatiStudente);

Nodo *  Ricerca(Lista lista, long matricola);
Nodo *  Ricerca2(Lista lista, long matricola);
Nodo *  Ricerca3(Lista lista, long matricola);
Nodo *  Ricerca4(Lista lista, long matricola);


int main()
{
 Lista lista = NULL;
 Nodo * p;
 int scelta;
 DatiStudente temp_stud;

 do
 {
  printf("\n1. Inserimento nuovo studente in prima posizione\n"
	 "2. Inserimento nuovo studente in ultima posizione\n"
	 "3. Ricerca studente nella lista\n"
	 "4. Visualizzazione completa della lista\n"
	 "0. Uscita\n\n"
	 "Seleziona una operazione: ");

  scanf("%d", &scelta);

  switch (scelta)
  {
  case 0:  
    puts("Fine programma");		
    break;
  case 1:  
    LeggiStudente(&temp_stud);
    MostraStudente(&temp_stud);
    InserisciInTesta(&lista, temp_stud);	
    break;
  case 2:  
    LeggiStudente(&temp_stud);
    MostraStudente(&temp_stud);
    InserisciInCoda2(&lista, temp_stud);
    break;
  case 3:
    {
      long matricola;
      printf("Inserisci la matricola da cercare: ");
      scanf("%li", &matricola);
       
      if (p = Ricerca(lista, matricola))
	{
	  printf("Studente presente in archivio\n");
	  MostraStudente(&(p->dati));
	} 
      else 
	printf("Studente non presente in archivio\n");
      
    
      /* verifico che tutte le versioni della ricerca
       * portano allo stesso risultato */
      assert(p == Ricerca2(lista, matricola));
      assert(p == Ricerca3(lista, matricola));
      assert(p == Ricerca4(lista, matricola));
      
    }
    break;
    
  case 4:
    MostraLista(lista);
    break;

   default: 
     printf("Selezione errata.");            
     break;
  }
 } while (scelta!=0);
 return 0;
}



/* verifica se la lista è vuota ovvero la testa della lista è pari a NULL */
boolean ListaVuota(Lista lista)
{
  return (lista==NULL);
}

/* Lettura da tastiera dei dati di uno studente */
void LeggiStudente(DatiStudente *stud)
{
  puts("Lettura dati studente:");  
  printf("Matricola : ");  scanf("%ld", &stud->matricola);
  printf("Cognome   : ");  scanf("%s", stud->cognome);
  printf("Nome      : ");  scanf("%s", stud->nome);
}

/* Visualizzazione a video dei dati di uno studente */
void MostraStudente(DatiStudente *stud)
{
  puts("Visualizzazione scheda studente:");  
  printf("Matricola : %ld\n", stud->matricola);
  printf("Cognome   : %s\n",  stud->cognome);
  printf("Nome      : %s\n",   stud->nome);
}

/* Inserimento di uno studente in testa alla lista */
void InserisciInTesta(Lista *pLista, DatiStudente stud)
{
  Nodo * p;
  p = (Nodo *) malloc(sizeof(Nodo));
  p->dati = stud;
  p->prox = *pLista;
  *pLista = p;
}

/* Inserimento di uno studente in coda alla lista */
void InserisciInCoda(Lista *pLista, DatiStudente stud)
{
  Nodo * cursore;
  Nodo * p = (Nodo *) malloc(sizeof(Nodo));
  
  p->dati = stud;
  p->prox = NULL;
  
  if (ListaVuota(*pLista))
    *pLista=p;
  else
    {
      cursore = *pLista;
      while (cursore->prox) cursore=cursore->prox;
      cursore->prox=p;
    }
}

/* Inserimento in coda, versione ricorsiva */
void InserisciInCoda2(Lista *pLista, DatiStudente stud)
{
  Nodo * p = (Nodo *) malloc(sizeof(Nodo));
  p->dati = stud;
  p->prox = NULL;
  
  if (ListaVuota(*pLista))
    *pLista=p;
  else
    InserisciInCoda2( &(*pLista)->prox, stud);
}



/* Ricerca: prima versione */
Nodo * Ricerca(Lista lista, long matricola)
{
  Nodo * cursore = lista;  
  while (cursore) {
    if (cursore->dati.matricola==matricola) return cursore;
    cursore = cursore->prox;
  }  
  return NULL;  
}

/* Seconda versione, non fa uso del cursore */
Nodo * Ricerca2(Lista lista, long matricola)
{
  while (lista) {
    if (lista->dati.matricola == matricola) return lista;
    lista = lista->prox;
  }
  return NULL;  
}

/* Terza versione, fa uso del costrutto for */
Nodo * Ricerca3(Lista lista, long matricola)
{
  for(; lista; lista = lista->prox)    
    if (lista->dati.matricola == matricola)
      return lista;
  return NULL;  
}


/* Quarta versione, ricorsiva */
Nodo * Ricerca4(Lista lista, long matricola)
{
  if (!lista) return NULL;
  if (lista->dati.matricola == matricola) return lista;
  else return Ricerca4(lista->prox, matricola);
}

/* Attraversamento di tutta la lista e visualizzazione 
 * dei dati degli studenti in essa contenuti */
void MostraLista(Lista lista)
{
  for (; lista; lista = lista->prox)
    MostraStudente(&lista->dati);
}

Esercitazione del 9 dicembre 2003
/**************************************
 * Esempio di programmazione modulare
 * File "somma.c"
 */

#include <stdio.h>
#include "sommamod.h"

void main()
{
	int a, b, somma;

	printf("Inserisci a: ");
	scanf("%d", &a);

	printf("Inserisci b: ");
	scanf("%d", &b);

	somma=Esegui_Somma(a, b);

	printf("La somma dei due elementi è %d", somma);

}



/*******************************
 * File "sommamod.h"
 */

extern int Esegui_Somma(int, int);



/*******************************
 * File "sommamod.c"
 */
 
#include "sommamod.h"

int Esegui_Somma(int a, int b)
{
	return (a+b);
}

Esercitazione del 16 dicembre 2003
/*1*************************************************
 * Esempio: apertura di un file di testo,
 * scrittura di dieci interi casuali, uno per riga
 */

#include <stdio.h>
void main()
{
 char nome[20];
 int i, numero;
 FILE *fp;

 printf("\nNome File : ");
 scanf("%s",nome);

 fp=fopen(nome, "w");
 if (fp==NULL)
  printf("\nErrore nell'apertura del file ! ");
 else
 {
  for (i=0;i<10;i++)
  {
   numero= rand() % 20 + 64;
   fprintf(fp,"%d\n",numero);
  }
  fclose(fp);
 }
}





/*2***************************************************
 * Come nell'esempio precedente, ma i numeri vengono
 * scritti in formato binario.
 */
#include <stdio.h>
void main()
{
 char nome[20];
 int i, numero;
 FILE *fp;

 printf("\nNome File : ");
 scanf("%s",nome);

 fp=fopen(nome, "wb");
 if (fp==NULL)
	printf("\nErrore nell'apertura del file ! ");
 else
 {
  for (i=0;i<10;i++)
  {
   numero= rand() % 20 + 64;
   fwrite(&numero,sizeof(int), 1, fp);
  }
 fclose(fp);
 }
}





/*3****************************************************************
 * Lettura di numeri interi da due file diversi e confronto.
 * I numeri sono conservati in forma di testo nel primo file, in
 * forma binaria nel secondo.
 */
 
#include <stdio.h>
void main()
{
 char nome_txt[20], nome_bin[20];
 int i, numero_txt, numero_bin;
 FILE *fp_txt, *fp_bin;

 /* inserimento nomi dei file */
 printf("\nNome file di testo : ");
 scanf("%s",nome_txt);

 printf("\nNome file binario : ");
 scanf("%s",nome_bin);

 /* apertura file di testo */
 fp_txt = fopen(nome_txt, "r");
 if (fp_txt==NULL)
  /* errore nell'apertura del file		*/
  printf("\nErrore nell'apertura del file di testo! ");
 else
 {
  /* apertura del file binario			*/
  fp_bin=fopen(nome_bin, "r");
  if (!fp_bin)
   printf("\nErrore nell'apertura del file di testo! ");
  else
  {
   /* ciclo di confronto dei numeri letti dai due file */
   /* termina al raggiungimento della fine di un file  */
   while (! (feof(fp_txt) || feof(fp_bin) ) )
   {
    /* lettura numero intero dal file di testo */
    fscanf(fp_txt, "%d", &numero_txt);

    /* lettura numero intero dal file binario */
    fread(&numero_bin, sizeof(int), 1 , fp_bin);

    /* confronto */
    if (numero_txt==numero_bin)
     printf("\nI numeri coincidono: %d", numero_txt);
    else
     printf("\nI numeri non coincidono: %d != %d", numero_txt, numero_bin);
   }
   fclose(fp_bin);
   }
  fclose(fp_txt);
 }
}





/*4****************************************************
 * Scrittura di 10 righe di testo in un file, in due
 * operazioni distinte, con apertura del file anche
 * in modo append.
 */

#include <stdio.h>
#include <string.h>
void main()
{
 FILE *fp;
 char buffer[64];
 int index;
 /* creazione del file */
 fp = fopen("RIGHE.TXT","w");

 /* stringa iniziale di ogni riga */
 strcpy(buffer,"Questa e' una linea di esempio.");

 /* scrittura di 5 righe */
 for (index = 1; index <=5; index++)
  fprintf(fp,"%s  Linea numero %d\n",buffer,index);

 /* chiusura del file */
 fclose(fp);

 /* apertura del file in modalita' append */
 fp = fopen("RIGHE.TXT","a");

 /* scrittura di ulteriori 5 righe */
 for (index = 6;index <= 10;index++)
  fprintf(fp,"%s  Linea numero %d\n",buffer,index);

 /* chiusura del file */
 fclose(fp);
}





/*5******************************************
 * Lettura del file generato nell'esercizio
 * precedente un carattere alla volta.
 */

#include "stdio.h"
void main()
{
 FILE *fp;
 int c;

 fp = fopen("RIGHE.TXT","r");
 if (!fp) printf("Il file non esiste\n");
 else
  do
  {
   c = getc(fp);
   putchar(c);
  } while (c != EOF);
  fclose(fp);
}




/*6**************************************************
 * Lettura dello stesso file riga per riga
 */

#include "stdio.h"
void main()
{
 FILE *fp;
 char riga[100];
 char *c;
 fp = fopen("RIGHE.TXT","r");
 do
 {
  /* legge una riga dal file (n-1 caratteri o fino alla fine della riga */
  c = fgets(riga,100,fp);
  /* verifica errori durante la lettura */
  if (c)
   printf("%s",riga);
 } while (c != NULL);        	 /* ripete fino alla fine del file */

 /* chiusura file */
 fclose(fp);
}




/*7*******************************************************
 * Memorizzazione di informazioni anagrafiche a blocchi
 * e ricerca
 */

#include <stdio.h>
/* tipo di informazione da memorizzare nel file */
typedef struct
{
 char nome[30];
 char cognome[30];
 char codfis[16];
} anagr;


/* funzione per l'inserimento dei dati */
int get_persona(anagr *temp)
{
 char more;
 printf("Vuoi inserire una nuova persona (Y or N)? ");
 fflush(stdin);
 scanf("%c", &more);

 if(more == 'N' || more == 'n')	return 0;
 printf("Cognome        : ");  scanf("%s", temp->cognome);
 printf("Nome           : ");  scanf("%s", temp->nome);
 printf("Codice fiscale : ");  scanf("%s", temp->codfis);
 return 1;
}

/* funzione per la visualizzazione dei dati */
void mostra_persona(anagr *temp)
{
 printf("Cognome        : %s\n", temp->cognome);
 printf("Nome           : %s\n", temp->nome);
 printf("Codice fiscale : %s\n", temp->codfis);
}

void main()
{
 char *name = "anagra.bin";
 char *name_filtro = "filtro.bin";
 FILE *pfile = NULL, *pfiltro=NULL;

 anagr persona;
 char cerca[20]="";

 /* apertura file di destinazione */
 if((pfile = fopen(name, "ab")) == NULL)
 {
  /* errore in apertura del file */
  printf("Impossibile aprire %s in scrittura.\n", name);
  exit(1);
 }

 /* inserimento dati anagrafici delle persone */
 while(get_persona(&persona))
  /* memorizzazione su file dell'anagrafica inserita */
  fwrite(&persona, sizeof(persona), 1, pfile);

 /* chiusura file destinazione */
 fclose(pfile);

 /* apertura dello stesso file in lettura */
 if((pfile = fopen(name, "rb")) == NULL)
 {
  /* errore in apertura del file */
  printf("Impossibile aprire il file");
  exit(1);
 } else {
  /* apertura del file in scrittura	*/
  if((pfiltro = fopen(name_filtro, "wb")) == NULL)
   /* errore in apertura del file	*/
   printf("Impossibile aprire il file per la scrittura");
  else
  {
   printf("Quale cognome vuoi cercare? ");
   scanf("%s", cerca);

   while (fread(&persona, sizeof(anagr),1,pfile)!=0)
   {
    /* verifica cognome cercato */
    if (strcmp(persona.cognome, cerca)==0)
    {
     /* visualizzazione del record desiderato */
     mostra_persona(&persona);
     /* scrittura sul secondo file */
     fwrite(&persona, sizeof(anagr),1,pfiltro);
    }
   }
   fclose(pfiltro);
  }
 }
 fclose(pfile);
}


Esercitazione del 7 gennaio 2004
/*1*********************************
   Esercitazione del 7 Gennaio 2004 
   Ripasso su array e puntatori, 
   vedere pag. 87 K&R
*/

int main()
{
 int x,i;

 int a[10];
 /* dichiaro un array di 10 interi: a[0], a[1]... a[9]*/
 
 int *pa;
 /* dichiaro un puntatore ad intero */
 
 for (i=0; i<10; i++) a[i] = i+1;
 /* scrivo i valori 1,2 ... 10 nelle celle */
 
 pa = &a[0];
 /* pa punta ora alla prima cella dell'array a 
    (pa contiene l'indirizzo di a[0])
 */
 
 printf("*pa vale: %i\n", *pa);
 /* scrivo il contenuto della cella puntata da pa,
    cioè a[0], che contiene il valore 1.
 */
 
 x = *pa;
 /* memorizzo in x il valore puntato da pa (idem);
    x e *pa sono memorizzati a locazioni differenti,
    e sono "separati" fra loro.
 */
 
 x++;
 printf("x ora vale              : %i\n", x);
 printf("*pa x invece vale ancora: %i\n", *pa);
 /* infatti se incremento x (x=2), 
    *pa non è cambiato (e vale ancora 1) */
 
 /* invece *pa e a[0] sono memorizzati nella stessa
    locazione */
 a[0] = 123;
 printf("a[0] ora vale           : %i\n", a[0]);
 printf("*pa vale anch'esso      : %i\n", *pa);
    
 /* il nome di un array (senza le parentesi quadre!)
    è un'espressione che indica la locazione della 
    prima cella dell'array, quindi le due istruzioni 
    seguenti sono equivalenti:*/   

 pa = &a[0];
 pa = a;
	 
 /* se pa è un puntatore a intero, l'espressione pa
    indica l'indirizzo di un intero, e l'espressione
    (pa+1) indica l'indirizzo dell'intero successivo.
    In questo caso , quindi (pa+1) == &a[1];
 */

 printf("L'uguaglianza (pa+1) == &a[1] vale: %i\n", (pa+1) == &a[1]);
  
 /* si noti che il "+1" significa "l'elemento successivo"
    e non "il byte successivo", quindi in generale non è
    vero che   (int)(pa+1) == ((int) pa)+1    
    */
 
 printf("L'uguaglianza (int)(pa+1) == ((int) pa)+1 vale: %i\n", (int)(pa+1) == ((int) pa)+1);   
 
 /* infatti: */ 
 printf("Puntatori: pa = %p, (pa+1) = %p, ((int)pa)+1 = %p\n", pa, pa+1, ((int)pa)+1);   
 
 /* per passare all'elemento successivo puntato da pa, posso
    usare l'operatore ++*/
 
 pa = &a[0];
 pa++;
 printf("L'uguaglianza pa == &a[1] vale: %i\n", pa == &a[1]);
 
 /* con l'operatore ++ posso allora scorrere tutti gli elementi */
 printf("Elementi *pa: ");    
 for (pa=a; pa < &a[10]; pa++)
  printf("%i; ", *pa);
 
 printf("\n");
 
 pa=a;
 
 /* attenzione a non confondere le due istruzioni seguenti */
 pa++;
 (*pa)++;
 
 /* posso anche percorrere a in senso inverso usando 
    l'operatore -- sul puntatore pa, come segue */
    
 printf("Elementi *pa in ordine inverso: ");    
 for (pa=&a[9]; pa >= a; pa--)
  printf("%i; ", *pa);   
 printf("\n");
 
 /* pa e' un puntatore a intero, quindi puo' fungere da array
    di interi: pa[i] e' una espressione valida */   
 
 printf("Elementi pa[]: ");    
 for (pa=a, i=0; i<10; i++)
  printf("%i; ", pa[i]);
 printf("\n");
 
 /* grazie a questa intercambiabilita' fra puntatori e array
    posso allocare "array" dinamicamente. Ad esempio */
    
 pa = (int *) malloc ( sizeof(int) * 10 );
 
 /* ora posso trattare a tutti gli effetti pa come se fosse 
    un array di interi dichiarato come segue:
       int pa[10];
    copiandoci, per esempio, gli elementi di a raddoppiati.   
 */
 for (i=0; i<10;i++) pa[i] = a[i] * 2;
 
 /* posso confrontare a video i due array cosi': */
 printf("Elementi del nuovo pa[]: ");
 for (i=0; i<10; i++) printf("%i; ", pa[i]);
 printf("\n");
 printf("Elementi di a[]        : ");
 for (i=0; i<10; i++) printf("%i; ", a[i]);
 printf("\n");
 
 /* ho finito di usare pa[], devo ricordarmi di disallocarlo */
 free(pa);
 
 /* adesso scrivere l'espressione *pa non e' piu' sicuro */
 
 /* a e' un array di interi: l'espressione "a" e' quindi un
    puntatore al primo elemento dell'array. Posso quindi 
    trattare a come un puntatore a intero, per esempio
    dereferenziandolo con *:                                 */
 
 printf("Il primo elemento di a e': %i\n", *a);
  
 for (i=0; i<10; i++)
  printf("%i; ", *(a + i));
 
 /* non posso invece scrivere la seguente istruzione:
    
    a++; 
    
    infatti a e' una espressione, ma non un nome di 
    variabile (a[0], a[1], ... sono nomi di variabili!).
 */
 
    
 return 0;
}





/*2*********************************
   Esercitazione del 7 Gennaio 2004 
   Ripasso su array multidimensionali, 
   array di puntatori e puntatori a puntatori;
   vedere pag. 101 K&R e successive.
*/

#define RIGHE   3
#define COLONNE 4


int main()
{
 /* Dichiariamo tre variabili che potranno
    essere usate indifferentemente 
 */
 
 int a[RIGHE][COLONNE]; /* matrice 2D*/
 
 int *pa[RIGHE];        /* array 1-D di puntatori*/
 
 int **ppa;             /* puntatore a puntatore/i */
 
 /* a e' gia' pronta;
    posso quindi inizializzare i suoi elementi.
 */
 int i,j;
 for (i=0; i<RIGHE; i++) 
  for (j=0; j<COLONNE; j++) 
   a[i][j] = (i+1)*(j+1);
 
 /* mostro il contenuto di a: */
 printf("Segue il contenuto di a[][]:\n");
 for (i=0; i<RIGHE; i++) 
 {
  for (j=0; j<COLONNE; j++) printf("%4i ", a[i][j]);
  printf("\n");
 }
 
 /* pa invece non e' pronta: e' infatti un array
    di 3 (=RIGHE) puntatori che puntano a locazioni 
    casuali (quindi non sono da usare!). 
     
     pa[0]-----> ...
     pa[1]-----> ...
     pa[2]-----> ...
    
    Devo quindi inizializzare ciascuno di essi.
 */
 for (i=RIGHE-1; i>=0; i--)
  pa[i] = (int *) malloc(sizeof(int) * COLONNE);

 /* Ora ciascun pa[] punta a array monodimensionali
    validi di 4 (=COLONNE) interi ciascuno
     
     pa[0]-----> [ int int int int ]
     pa[1]-----> [ int int int int ]
     pa[2]-----> [ int int int int ]
     
    Posso quindi assegnare il valore a tali interi.
    Notate che tratto pa come se fosse un array 2-D.
 */
 for (i=0; i<RIGHE; i++) 
  for (j=0; j<COLONNE; j++) 
   pa[i][j] = (i+1)*(j+1);

 /* Mostro ora il contenuto di pa. Idem;
 */
 printf("Segue il contenuto di pa[][]:\n");
 for (i=0; i<RIGHE; i++) 
 {
  for (j=0; j<COLONNE; j++) printf("%4i ", pa[i][j]);
  printf("\n");
 }
 
 /* Considero ora ppa, che non e' pronto, infatti
    punta a una locazione casuale:
 	ppa-----> ...
    Lo inizializzo quindi facendo in modo che punti
    ad un array allocato dinamicamente e contenente
    3 (=RIGHE) puntatori a interi:
 */
 
 ppa = (int**) malloc( sizeof(int*) * RIGHE);
 
 /* Ora ppa punta a un array di 3 puntatori, che puntano
    a locazioni casuali
           ppa
            |
            v
         [int *]-----> ...
         [int *]-----> ...
         [int *]-----> ...
    
    e quindi vanno inizializzati.
  */
 
 for (i=RIGHE-1; i>=0; i--)
  ppa[i] = (int *) malloc(sizeof(int) * COLONNE);

 /* Ora ciascun ppa[] punta a array monodimensionali
    validi di 4 (=COLONNE) interi ciascuno
     
     ppa[0]-----> [ int int int int ]
     ppa[1]-----> [ int int int int ]
     ppa[2]-----> [ int int int int ]
     
    Posso quindi assegnare il valore a tali interi.
    Notate che tratto ppa come se fosse un array 2-D.
 */
 
 for (i=0; i<RIGHE; i++) 
  for (j=0; j<COLONNE; j++) 
   ppa[i][j] = (i+1)*(j+1);

 /* Mostro ora il contenuto di ppa. Idem;
 */
 printf("Segue il contenuto di ppa[][]:\n");
 for (i=0; i<RIGHE; i++) 
 {
  for (j=0; j<COLONNE; j++) printf("%4i ", ppa[i][j]);
  printf("\n");
 }
 
 return 0;
}

Esercitazione del 13 gennaio 2004
/***************************************************************
 * Esercitazione del 13 gennaio, ripasso su liste dinamiche.
 * Gestione di una rubrica telefonica con una lista dinamica
 * ordinata alfabeticamente.
 * (Confrontare con "archivio studenti", esercitazione del 
 * 2 dicembre 2003)
 */

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef char string[30];
typedef enum {false=0, true} boolean;

typedef struct nodo {
  string cognome;
  string nome;
  string telefono;
  struct nodo * prox;
} Nodo;

typedef Nodo * Lista;

void    Inizializza(Lista *);
boolean ListaVuota(Lista);
void    LeggiVoce(Nodo *);
void    MostraVoce(Nodo *);
void    MostraLista(Lista lista);
void Inserisci(Lista *pLista, Nodo * voce);

void LeggiVoce(Nodo *voce)
{
  puts("Inserimento voce:");
  printf("Cognome   : ");  scanf("%s", voce->cognome);
  printf("Nome      : ");  scanf("%s", voce->nome);
  printf("Telefono  : ");  scanf("%s", voce->telefono);
}

void MostraVoce(Nodo *voce)
{
  printf("'%s %s', tel. %s\n", voce->cognome, voce->nome, voce->telefono);
}


/* Inserimento di una nuova voce in ordine alfabetico per cognome */
void Inserisci(Lista *pLista, Nodo * voce)
{
  if (!(*pLista))
   *pLista = voce;
  else if (strcmp(voce->cognome, (*pLista)->cognome)>0)
   Inserisci(&((*pLista)->prox), voce);
  else
  {
   voce->prox = *pLista;
   *pLista = voce;
  }
}

void MostraLista(Lista lista)
{
  for (; lista; lista = lista->prox)
    MostraVoce(lista);
}


int main()
{
 Lista lista = NULL;
 Nodo * p;
 int scelta;

 do
 {
  printf("\n1. Inserimento nuova voce\n"	
	 "2. Visualizzazione completa della lista\n"
	 "0. Uscita\n\n"
	 "Seleziona una operazione: ");

  scanf("%d", &scelta);
  switch (scelta)
  {
  case 0:  
    puts("Fine programma");		
    break;
  case 1:
    p = (Nodo*) malloc(sizeof(Nodo));
    p->prox = NULL;
    LeggiVoce(p);
    MostraVoce(p);
    Inserisci(&lista, p);
    break;
  case 2:
    MostraLista(lista);
    break;

   default: 
     printf("Selezione errata.");            
     break;
  }
 } while (scelta!=0);
 return 0;
}




/*******************************************************************
 * fp_encode.c : Programma di esempio che mostra la codifica binaria
 * floating point in singola precisione di un valore reale inserito
 * dall'utente.
 *
 */

/* Costanti che indicano il numero di bit richiesti per: */
#define W_bits 32
		 /* - tutto quanto il numero in singola precisione */
#define F_bits 23
		 /* - la mantizza normalizzata decapitata */
#define E_bits 8
		 /* - l'esponente in eccesso a 127 */
#define S_bits 1
		 /* - il segno */

#if sizeof(float) != 4
#error Floating point a singola precisione non a 32 bit!
#endif

#if sizeof(long int) != 4
#error Long int non a 32 bit!
#endif

#include <stdio.h>

int main()
{
 char risultato[W_bits+2+1];
 int bit; /* ordine del bit considerato: 0=LSB, 31=MSB  */
 int pos; /* posizione corrente nella stringa di uscita */

 union doppia_personalita {
  float         single; /* valore in singola precisione */
  unsigned long bits;   /* valore intero che contiene gli stessi bit */
 } valore;


 while (1) {
  printf("Inserire un numero reale....: ");
  scanf("%f",&valore.single);
  printf("Valore inserito.............: %g \n", valore.single);

 for (bit=0, pos=W_bits-1+2; bit<W_bits; bit++)
 {
  risultato[pos--]='0' + (valore.bits >> bit & 1);

  if (pos==W_bits-1+2-F_bits)          risultato[pos--]=' ';
  if (pos==W_bits-1+2-F_bits-E_bits-1) risultato[pos--]=' ';
 }
 risultato[W_bits+2]=0;
 printf("Codifica binaria............: %s \n",risultato);
 printf("                              - -------- -----------------------\n"
	"                              S     E               F\n");
	    }
 return 0;
}






/*******************************************************************
 * fp_decode.c : Programma di esempio che mostra il valore reale in
 * base 10 corrispondente a una codifica binaria floating point in 
 * singola precisione inserita dall'utente.
 *
 */

#define W_bits 32

#if sizeof(float) != 4
#error Floating point a singola precisione non a 32 bit!
#endif

#if sizeof(long int) != 4
#error Long int non a 32 bit!
#endif

#include <stdio.h>

int main()
{
 int bit; /* ordine del bit considerato: 0=LSB, 31=MSB  */

 union doppia_personalita {
  float         single; /* valore in singola precisione */
  unsigned long bits;   /* valore intero che contiene gli stessi bit */
 } valore;

 while (1) {
  puts("\n                                        "
       "S<--E---><----------F---------->");
  printf("Inserire i 32 bit del numero reale....: ");
  bit=0;
  while (bit<W_bits)
  {
   char c = getch();
   switch (c)
   {
    case  3 : /* Ctrl-C */
    case 27 : /* Ctrl-C */
	      return 0;
    case  8 : if (bit>0) putchar(c);
    default : break;
    case '1': valore.bits |= 1;
    case '0': putchar(c);
	      if (++bit>=W_bits) break;
	      valore.bits <<= 1;
   }
  }
  printf("\nValore floating point.................: %g \n",valore.single);
 }
 return 0;
}


Esercitazione del 13 gennaio 2004.

Esempi di conversione da numeri reali in base 10 a valori floating point in 
codifica a singola precisione.


Numero da codificare: 22.625 Codifica del segno: + 0 Codifica della parte intera: 22 10110 Decapitata 0110 Codifica in virgola fissa della parte decimale: 0.625 1010000000000000000 Posizione Residuo Cifra Nuovo residuo 0.625 0.6250 -1 1.25 1 0.2500 -2 0.5 0 0.5000 -3 1 1 0.0000 -4 0 0 0.0000 ... Codifica dell'esponente: Posizione della virgola: 4 Eccesso: 127 Esponente da codificare: 131 In binario: 10000011 Numero codificato: 0 10000011 0110 1010000000000000000
Numero da codificare: 5.9737E+24 (massa della Terra in kg) Codifica del segno: + 0 Codifica decimale con tutte le cifre: 5973700000000000000000000 Codifica in binario con tutte le cifre: 10011110000111110101110000000000000_ 00000000000000000000000000000000000_ 00000000000 In binario "scientifico": 1.00111100001111000000E+82 Decapitato 00111100001111101011110 Codifica dell'esponente: 82 Eccesso: 127 Esponente da codificare: 209 Codifica dell'esponente: 11010001 Numero codificato: 0 11010001 00111100001111000000000
Numero da codificare -1.60217733E-19 (carica elettrica dell'elettrone in Coulomb) Codifica del segno: - 1 Codifica decimale con tutte le cifre: -0.000000000000000000160217733 Posizione Residuo Cifra Nuovo residuo 1.60217733E-19 -1 3.20435E-19 0 3.20435466E-19 -2 6.40871E-19 0 6.40870932E-19 ... ... 0 ... -62 0.738873879 0 7.38873879E-01 -63 1.477747758 1 4.77747758E-01 -64 0.955495517 0 9.55495517E-01 -65 1.910991033 1 9.10991033E-01 -66 1.821982067 1 8.21982067E-01 -67 1.643964134 1 6.43964134E-01 -68 1.287928268 1 2.87928268E-01 -69 0.575856535 0 5.75856535E-01 -70 1.15171307 1 1.51713070E-01 -71 0.30342614 0 3.03426140E-01 -72 0.606852281 0 6.06852281E-01 -73 1.213704561 1 2.13704561E-01 -74 0.427409122 0 4.27409122E-01 -75 0.854818244 0 8.54818244E-01 -76 1.709636489 1 7.09636489E-01 -77 1.419272978 1 4.19272978E-01 -78 0.838545956 0 8.38545956E-01 -79 1.677091911 1 6.77091911E-01 -80 1.354183823 1 3.54183823E-01 -81 0.708367646 0 7.08367646E-01 -82 1.416735291 1 4.16735291E-01 -83 0.833470582 0 8.33470582E-01 -84 1.666941165 1 6.66941165E-01 -85 1.33388233 1 3.33882330E-01 -86 0.66776466 0 6.67764660E-01 -87 1.33552932 1 3.35529320E-01 -88 0.67105864 0 6.71058640E-01 -89 1.34211728 1 3.42117280E-01 -90 0.68423456 0 6.84234560E-01 -91 1.368469119 1 3.68469119E-01 -92 0.736938238 0 7.36938238E-01 -93 1.473876476 1 4.73876476E-01 -94 0.947752953 0 9.47752953E-01 -95 1.895505905 1 8.95505905E-01 -96 1.79101181 1 7.91011810E-01 -97 1.582023621 1 5.82023621E-01 -98 1.164047241 1 1.64047241E-01 -99 0.328094482 0 3.28094482E-01 -100 0.656188965 0 6.56188965E-01 Codifica in binario con tutte le cifre: 000000000000000000000000000000000000_ 000000000000000000000000001011110100_ 1001101101011010101010111100 In binario "scientifico" 1.01111010010011000000000E-63 Decapitato 01111010010011011010110 Codifica dell'esponente: -63 Eccesso: 127 Esponente da codificare: 64 Codifica dell'esponente: 01000000 Numero codificato: 1 01000000 01111010010011011010110
Esempio di conversione da codifiche floating point in singola precisione a numeri reali in base 10. Numero codificato: 1 01111101 11010000000000000000000 Decodifica del segno: 1 - Decodifica dell'esponente: 01111101 In decimale: 125 Eccesso: -127 Esponente: -2 Mantissa: 1.11010000000000000000000 In binario scientifico: 1.11010000000000000000000 E -2 Con tutte le cifre: 0.011101 In decimale: 0 * 0.5 1 * 0.25 1 * 0.125 1 * 0.0625 0 * 0.03125 1 * 0.015625 ------------ 0.453125 Numero in base decimale: - 0.453125
Codifiche "speciali" e di particolare interesse: Codifiche per lo zero: 0 0 00000000 00000000000000000000000 -0 1 00000000 00000000000000000000000 Codifiche per l'infinito: +Inf 0 11111111 00000000000000000000000 -Inf 1 11111111 00000000000000000000000 Codifiche per il Not-a-Number (0/0, inf-inf, inf*0): +NaN 0 11111111 11111111111111111111111 -NaN 1 11111111 11111111111111111111111 Le altre codifiche del tipo seguente non sono ammesse: x 11111111 xxxxxxxxxxxxxxxxxxxxxxx Il reale più piccolo memorizzabile, in valore assoluto: 0 00000000 00000000000000000000001 = 1.40129846E-45 Il reale più grande memorizzabile, in valore assoluto: 0 11111111 11111111111111111111111 = 3.40282347E+38