Formattazione dati, Funzioni, Tipi di dato

Lunedě, 15 Marzo 2004

OBIETTIVI DELLA LEZIONE
In questa lezione:
  1. faremo un ripasso degli argomenti precedenti
  2. esamineremo i tipi di dato built-in del C, la loro occupazione di memoria e rappresentazione
  3. approfondiremo l'uso delle funzioni in particolare il passaggio dei parametri
  4. studieremo le matrici e come si passano alle funzioni
  5. studieremo i tipi di dato strutturati e come si passano alle funzioni

Esercizio di ripasso: Variabili , tipi, visualizzazione, dichiarazione funzioni

Definizione e chiamata di funzioni, passaggio indirizzi e spazio di indirizzamento

  • Consideriamo questo codice che TENTA inutilmente di invertire due variabili....

    // SWAP
    #include <stdio.h>
    #include <stdlib.h>
    
    void swap1( int local_a , int local_b );
    void swap2( int a , int b );
    
    int main()
    {
        int a;
        int b;
    
        a = 3;
        b = 5;
    
        printf("a vale %d  e b vale %d \n" , a , b);
        swap1( a, b);
        printf("a vale %d  e b vale %d \n" , a , b);
    
        swap2( a, b);
        printf("a vale %d  e b vale %d \n" , a , b);
    
        getchar(); getchar();
        exit(0);
    }
    
    void swap1( int local_a , int local_b )
    {
        int temp ;
    
        temp = local_a ;
        local_a = local_b ;
        local_b = temp ;
    }
    
    void swap2( int a , int b )
    {
        int temp ;
    
        temp = a ;
        a = b ;
        b = temp ;
    }
    		

    tutto quello che si ottiene e' semplicemente

    
    a vale 3  e b vale 5
    a vale 3  e b vale 5
    a vale 3  e b vale 5
    		
  • Molto meglio fare cosi:

    // SWAP
    #include <stdio.h>
    #include <stdlib.h>
    
    void swap_OK( int * i_a , int * i_b );
    
    
    int main()
    {
        int a;
        int b;
    
        a = 3;
        b = 5;
    
        printf("a vale %d  e b vale %d \n" , a , b);
        swap_OK( &a, &b);
        printf("a vale %d  e b vale %d \n" , a , b);
    
        getchar(); getchar();
        exit(0);
    }
    
    void swap_OK( int * i_a , int * i_b )
    {
        int temp ;
    
        temp = *(i_a) ;
        *(i_a) = *(i_b) ;
        *(i_b) = temp ;
    }
    		

    Ora funziona correttamente ed inverte il contenuto delle due celle a e b

    
    a vale 3  e b vale 5
    a vale 5  e b vale 3
    		
  • COERCIZIONE DEGLI ARGOMENTI di una funzione

    printf("%.3f \n"  , sqrt(4) );
    		
    2.000		

    Visualizza 2,000 (float) e non 2 intero (intero) la coercizione
    converte 4 (int) in 4 (float) prima di passarlo veramente a sqrt()

  • Esercizio manipolazione stringhe e programmazione Base
    Esaminare il seguente codice ed il suo relativo output
    // STRINGHE
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
    
        char s[80];
        char s2[]="STRINGA DEFINITA con EOL\n";
        int i ;
    
        strcpy(s, "copiata con strcpy" ) ;
    
        printf(s2);
        printf(s);
        printf("\n\n>> %s <<>> %s <<\n\n",  s, s2);
    
        printf("mi calcolo la lunghezza della stringa s2-> %d\n\n\n" , strlen(s2));
    
        for( i=0; i< (strlen(s2)-1) ; i++ )
        {
        s2[i] = 'x' ;
        printf("%s" , s2);
        }
    
    
        getchar();  // non serve a nulla ma ferma la finestra...
        exit(0);
    }
    		
    STRINGA DEFINITA con EOL
    copiata con strcpy
    
    >> copiata con strcpy <<>> STRINGA DEFINITA con EOL
     <<
    
    mi calcolo la lunghezza della stringa s2-> 25
    
    
    xTRINGA DEFINITA con EOL
    xxRINGA DEFINITA con EOL
    xxxINGA DEFINITA con EOL
    xxxxNGA DEFINITA con EOL
    xxxxxGA DEFINITA con EOL
    xxxxxxA DEFINITA con EOL
    xxxxxxx DEFINITA con EOL
    xxxxxxxxDEFINITA con EOL
    xxxxxxxxxEFINITA con EOL
    xxxxxxxxxxFINITA con EOL
    xxxxxxxxxxxINITA con EOL
    xxxxxxxxxxxxNITA con EOL
    xxxxxxxxxxxxxITA con EOL
    xxxxxxxxxxxxxxTA con EOL
    xxxxxxxxxxxxxxxA con EOL
    xxxxxxxxxxxxxxxx con EOL
    xxxxxxxxxxxxxxxxxcon EOL
    xxxxxxxxxxxxxxxxxxon EOL
    xxxxxxxxxxxxxxxxxxxn EOL
    xxxxxxxxxxxxxxxxxxxx EOL
    xxxxxxxxxxxxxxxxxxxxxEOL
    xxxxxxxxxxxxxxxxxxxxxxOL
    xxxxxxxxxxxxxxxxxxxxxxxL
    xxxxxxxxxxxxxxxxxxxxxxxx
    		

MATRICI

Dichiarazione di una matrice, manipolazione e passaggio a funzione
Esaminare il seguente codice ed il suo relativo output
// gestione matrici
#include <stdio.h>
#include <stdlib.h>

#define N_MAX 9


void riempi_Matrice(int a[][N_MAX]);
void stampa_Matrice(int a[][N_MAX]);

int main()
{
    int a[N_MAX][N_MAX];

    riempi_Matrice( a );
    stampa_Matrice( a );

    getchar();
    exit(0);
}


void riempi_Matrice(int a[][N_MAX])
{
	int i;
	int j;


	for(i=0; i < N_MAX;i=i+1)
	{
		printf("\n");  // andiamo a capo

		for (j=0; j < N_MAX; j=j+1)
		{
				a[i][j] = (i+1) * (j+1) ;
		}
	}
	printf("\n\n");
}

void stampa_Matrice(int a[][N_MAX])
{
	int i;
	int j;


	for( i=0 ;  i < N_MAX - 1; i=i+1)
	{
		printf(" \n");  // andiamo a capo

		for (j=0;j < N_MAX;j=j+1)
		{
				printf("%5d",  a[i][j] );
		}
	}

}

		
Ottenendo


    1    2    3    4    5    6    7    8    9
    2    4    6    8   10   12   14   16   18
    3    6    9   12   15   18   21   24   27
    4    8   12   16   20   24   28   32   36
    5   10   15   20   25   30   35   40   45
    6   12   18   24   30   36   42   48   54
    7   14   21   28   35   42   49   56   63
    8   16   24   32   40   48   56   64   72
    9   18   27   36   45   54   63   72   81

		

TIPI DI DATO STRUTTURATO

Definire un tipo struct e manipolarlo
Esaminare il seguente codice ed il suo relativo output
#include <stdio.h>
#include <stdlib.h>

/* il punto (x,y) potra' essere rappresentato con una unica variabile */
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


int main()
{
	int i;
	MissItalia ragazza1;
	MissItalia ragazza2;
	MissItalia gruppo[200];

	strcpy(ragazza1.nome, "Maria Rosaria" );
	ragazza1.altezza = 180;
	ragazza1.voto[0] = 90;
	ragazza1.voto[1] = 90;
	ragazza1.voto[2] = 90;

	printf("Nome=%s, altezza=%d," , ragazza1.nome, ragazza1.altezza );

	printf("voto=");
	for (i=0; i<3; i++)
    	{
      		printf(" %d " ,ragazza1.voto[i]);
    	}

	gruppo[0] = ragazza1;  // sto' copiando tutti i dati ??? Come gli array?
	printf(" %s \n" ,gruppo[0].nome);

    	strcpy(ragazza1.nome, "Cambio il nome a Maria Rosaria" );
	printf(" %s \n" ,ragazza1.nome);  // Cambiato!!
	printf(" %s \n" ,gruppo[0].nome);  // Rimasto !! a

	getchar();
	exit(0);
}
		
Ottenendo
Nome=Maria Rosaria, altezza=180,voto= 90  90  90

 Maria Rosaria
 Cambio il nome a Maria Rosaria
 Maria Rosaria

		

Passaggio di uno struct alla funzione
Esaminare il seguente codice ed il suo relativo output
#include <stdio.h>
#include <stdlib.h>

/* il punto (x,y) potra' essere rappresentato con una unica variabile */
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_miss ( MissItalia * p1 );        // stampa i dati
void aggiusta_voto( MissItalia * p1 );          // rende il voto perfetto (100, 100, 100)!!
void stampa_miss    ( MissItalia * p1 );        // stampa i dati

int main()
{

	MissItalia ragazza1;
	MissItalia * p1;

	MissItalia ragazza2;
	MissItalia * p2;

	// sistemo i puntatori
    	p1 = &ragazza1 ;
    	p2 = &ragazza2 ;

    	inserisci_miss ( p1 );  // i dati finiscono in ragazza1
    	inserisci_miss ( p2 );  // i dati finiscono in ragazza2

    	stampa_miss(p1);
    	stampa_miss(p2);

    	fflush(stdin);	getchar();	exit(0);
}

void inserisci_miss ( MissItalia * p1 )
{
    	char nome[256];

    	printf("Dammi il nome -->");
    	scanf("%s", p1->nome );
    	printf("Dammi il cognonome -->");
    	scanf("%s", p1->cognome );

	p1->altezza   = 180;
	p1->voto[0] = 80;
	p1->voto[1] = 90;
	p1->voto[2] = 99;
	p1->peso      = 78;
	p1->cucina    = 0;  // aiuto!!!

}

void stampa_miss    ( MissItalia * p1 )
{
    printf("\n\n\n------------****------------\n");
    printf("Nome:%s   Cognome:%s \n", p1->nome , p1->cognome );
    printf("altezza:%d   Peso:%d \n", p1->altezza, p1->peso  );
    printf("voto: %d %d %d  \n", p1->voto[0] , p1->voto[1] , p1->voto[2]  );
    printf("cucina [0=aiuto .. 10=professionista] = %d \n", p1->cucina );
}

		
Ottenendo
Dammi il nome -->Giuseppina
Dammi il cognonome -->Bellinzona
Dammi il nome -->Maria
Dammi il cognonome -->berlin



------------****------------
Nome:Giuseppina   Cognome:Bellinzona
altezza:180   Peso:78
voto: 80 90 99
cucina [0=aiuto .. 10=professionista] = 0



------------****------------
Nome:Maria   Cognome:berlin
altezza:180   Peso:78
voto: 80 90 99
cucina [0=aiuto .. 10=professionista] = 0
		

Altre informazioni sull'indirizzamento delle variabili di tipi sono in questo file

NoteSuStructInC.pdf. Buona lettura.

Discussione Esercizi del laboratoio





Lab

Esercizio 1: capire come si sposta una porzione di codice dentro una funzione (dichiarandola ovviamente)
Salvare il file MassimoFunzionale1Compito.c nella directory di lavoro e modificarlo affinche' sia possibile chiamare nel main la seguente funzione
....
int massimo;
int numeri[LUN];
.....
massimo = calcolaMassimo(numeri);
Esercizio 2: Controlla se hai capito come di definiscono e si usano le funzioni
Salvare il file MassimoFunzionale2Compito.c nella directory di lavoro e trovare gli errori presenti.
Esercizio 3: primo esercizio sul passaggio di indirizzo
Leggere attentamente il programma commentato MassimoFunzionale3.c.
Copiarlo nella directory di lavoro visualizzare con delle printf le seguenti variabili ed etichette
  1. numeri, massimo, &massimo
    appena prima della chiamata di calcolaMassimo(numeri, & massimo);

  2. numeri, DammiIndirizzoDelMassimo , *DammiIndirizzoDelMassimo
    appena prima della graffa di chiusura della funzione

  3. Esamina i valori degli indirizzi di memoria che hai stampato a consolle. Di dicono nulla? prova a fare uno schema su carta della memoria.

  4. Se pensi di aver capito, allora stampa anche & DammiIndirizzoDelMassimo , cosa e'? Cosa contiene? quadra con il tuo schema della memoria che hai disegnato su carta?

  5. Sempre appena prima della graffa di chiusura della funzione puoi stampare il valore di massimo? perche' no?
Esercizio 4: programmazione Base
Scrivere il programma Natale.c che stampa sullo schermo la seguente figura:
	           *
	          ***
	         *****
	        *******
	       *********
	      ***********
	     *************
	    ***************
	   *****************
	  *******************
		
Chi la realizzera' con 10 printf del tipo printf(" **** \n") sara' esposto al pubblico ludibrio.
Esercizio 5: MISS ITALIA
Copiate il codice dell'esercizio MISS ITALIA e salvate il programma MissItalia.c. Aggiungete la funzione mancante void aggiusta_voto( MissItalia * p1 ); che avendo in ingresso un puntatore ad una qualunque ragazza definita di tipo MissItalia automaticamente cambia il voto in 100,100,100




Informazioni sul sito