OBIETTIVI DELLA LEZIONE
In questa lezione:
- faremo un ripasso degli argomenti precedenti
- esamineremo i tipi di dato built-in del C, la loro occupazione di memoria e rappresentazione
- approfondiremo l'uso delle funzioni in particolare il passaggio dei parametri
- studieremo le matrici e come si passano alle funzioni
- studieremo i tipi di dato strutturati e come si passano alle funzioni
Ogni variabile deve ricevere dalla scanf il tipo di dato corretto. Quindi scanf("%c" ... per i caratteri, scanf("%d" ... per gli interi, scanf("%f" ... per numeri con la virgola, ecc. Successivamente e' possibili visualizzarli come vogliamo MA dobbiamo usare sempre il giusto cast
// Ripasso Tipi di dato #include <stdio.h> #include <stdlib.h> int main() { char c; int i; float f; char s[256]; // carattere printf("metti un carattere -->") ; scanf("%c" , &c) ; // scanf con %c !!!! printf(" Hai messo il carattere -> %c <-- \n", c); printf(" visto come intero -> %d <-- \n", (int)c ); printf(" visto come float -> %f <-- \n", (float) c ); // intero printf("metti un intero -->") ; scanf("%d" , &i) ; // scanf con %d !!!! printf(" Hai messo l'intero -> %d <-- \n", i); printf(" visto come carattere -> %c <-- \n", (char) i ); printf(" visto come float -> %f <-- \n", (float) i ); // float printf("metti un numero con virgola -->") ; scanf("%f" , &f) ; // scanf con %f !!!! printf(" Hai messo il float -> %f <-- \n", f); printf(" visto come carattere -> %c <-- \n", (char) i ); printf(" visto come intero -> %f <-- \n", (int) i ); getchar(); getchar(); // non serve a nulla ma ferma la finestra... exit(0); }
quello che otteniamo dalla compilazione ed inserendo il carattere 'a', l'intero 97 e il numero con virgola 97.2345 e':
metti un carattere -->a Hai messo il carattere -> a <-- visto come intero -> 97 <-- visto come float -> 97.000000 <-- metti un intero -->97 Hai messo l'intero -> 97 <-- visto come carattere -> a <-- visto come float -> 97.000000 <-- metti un numero con virgola -->97.2345 Hai messo il float -> 97.234497 <-- visto come carattere -> a <-- visto come intero -> 97.234497 <--
Il tipo di dato int NON e' portabile!! Su ogni processore puo' essere implementato con un numero di bit diverso. Meglio usare long!
// Ripasso Tipi di dato #include <stdio.h> #include <stdlib.h> int main() { char c; double d; long l; unsigned int ui; float f; c = 130; d = 130; l = 130; ui = 130; f = 130; printf("130 \n"); printf(" Come carattere : -> %c <-- \n", c); printf(" Come double : -> %f <-- \n", d); printf(" Come long : -> %d <-- \n", l); printf(" Come unsigned int : -> %u <-- \n", ui); printf(" Come float : -> %f <-- \n", f); // 2^31 -1 c = 2147483648 - 1; d = 2147483648 - 1; l = 2147483648 - 1 ; ui = 2147483648 - 1; f = 2147483648 - 1; printf("2^31 -1 \n"); printf(" Come carattere : -> %c <-- \n", c); printf(" Come double : -> %f <-- \n", d); printf(" Come long : -> %d <-- \n", l); printf(" Come unsigned int : -> %u <-- \n", ui); printf(" Come float : -> %f <-- \n", f); // 2^31 c = 2147483648 ; d = 2147483648 ; l = 2147483648 ; ui = 2147483648 ; f = 2147483648 ; printf("2^31 \n"); printf(" Come carattere : -> %c <-- \n", c); printf(" Come double : -> %f <-- \n", d); printf(" Come long : -> %d <-- \n", l); printf(" Come unsigned int : -> %u <-- \n", ui); printf(" Come float : -> %f <-- \n", f); // 2^32 - 1 c = 4294967296 - 1; d = 4294967296 - 1; l = 4294967296 - 1; ui = 4294967296 - 1; f = 4294967296 - 1; printf("2^32 - 1 \n"); printf(" Come carattere : -> %c <-- \n", c); printf(" Come double : -> %f <-- \n", d); printf(" Come long : -> %d <-- \n", l); printf(" Come unsigned int : -> %u <-- \n", ui); printf(" Come float : -> %f <-- \n", f); // 2^32 c = 4294967296 ; d = 4294967296 ; l = 4294967296 ; ui = 4294967296 ; f = 4294967296 ; printf("2^32 \n"); printf(" Come carattere : -> %c <-- \n", c); printf(" Come double : -> %f <-- \n", d); printf(" Come long : -> %d <-- \n", l); printf(" Come unsigned int : -> %u <-- \n", ui); printf(" Come float : -> %f <-- \n", f); // 2^32 + 1 c = 4294967296 + 1 ; d = 4294967296 + 1 ; l = 4294967296 + 1 ; ui = 4294967296 + 1 ; f = 4294967296 + 1 ; printf("2^32 + 1 \n"); printf(" Come carattere : -> %c <-- \n", c); printf(" Come double : -> %f <-- \n", d); printf(" Come long : -> %d <-- \n", l); printf(" Come unsigned int : -> %u <-- \n", ui); printf(" Come float : -> %f <-- \n", f); getchar(); getchar(); // non serve a nulla ma ferma la finestra... exit(0); }
130 Come carattere : -> é <-- Come double : -> 130.000000 <-- Come long : -> 130 <-- Come unsigned int : -> 130 <-- Come float : -> 130.000000 <-- 2^31 -1 Come carattere : -> <-- Come double : -> 2147483647.000000 <-- Come long : -> 2147483647 <-- Come unsigned int : -> 2147483647 <-- Come float : -> 2147483648.000000 <-- 2^31 Come carattere : -> <-- Come double : -> 2147483648.000000 <-- Come long : -> -2147483648 <-- Come unsigned int : -> 2147483648 <-- Come float : -> 2147483648.000000 <-- 2^32 - 1 Come carattere : -> <-- Come double : -> 4294967295.000000 <-- Come long : -> -1 <-- Come unsigned int : -> 4294967295 <-- Come float : -> 4294967296.000000 <-- 2^32 Come carattere : -> <-- Come double : -> 4294967296.000000 <-- Come long : -> 0 <-- Come unsigned int : -> 0 <-- Come float : -> 4294967296.000000 <-- 2^32 + 1 Come carattere : -> ? <-- Come double : -> 4294967297.000000 <-- Come long : -> 1 <-- Come unsigned int : -> 1 <-- Come float : -> 4294967296.000000 <--
// 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
// 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
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] ); } } }Ottenendo1 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
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); }OttenendoNome=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 ); }OttenendoDammi 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.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
- numeri, massimo, &massimo
appena prima della chiamata di calcolaMassimo(numeri, & massimo);
- numeri, DammiIndirizzoDelMassimo , *DammiIndirizzoDelMassimo
appena prima della graffa di chiusura della funzione
- Esamina i valori degli indirizzi di memoria che hai stampato a consolle. Di dicono nulla? prova a fare uno schema su carta della memoria.
- 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?
- 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
©2004 Roberto Sassi