OBIETTIVO DELLA LEZIONE
Capire come utilizzare vettori e stringhe. Comprendere cosa è un puntatore e come si usa.
Imparare a scrivere funzioni.
int x[100];
Definisce un array x costituito da 100 numeri interi.
Che spazio occupa nella memoria? Lo spazio occupato da 100 numeri interi
(400byte). x e' l'etichetta della prima cella di memoria.
...
for(i=0; i<100; i++) x[i]=i+1;
...
char s[6];
s[0]='C';
s[1]='r';
s[2]='e';
s[3]='m';
s[4]='a';
s[5]='\0';
Nota che la stringa s e' composta da 6 caratteri.
Il terminatore di stringa e' un carattere come gli altri!
Il simbolo '\0' assomiglia a quello che usiamo per andare a
capo '\n'.
char s[]="Laboratorio di Informatica applicata";
E' un esempio di array non dimensionato a cui si assegna una costante stringa. ATTENZIONE:
La costante stringa "M" è diversa dal carattere 'M' ! "M" e' composta da due caratteri: ''M'+'\0' |
printf("Il risultato di i=x+3 e' %d" , i);
#include <stdio.h> main() { char s[128]; // strcpy(s_to,s_from) copia la stringa s_from in s_to // fino a quando trova un terminatore di stringa strcpy(s,"Laboratorio di Informatica applicata"); printf("%s",s); }Non fare lavoro inutile: se c'e' una funzione gia' pronta usala!
int *p; int i, a[10]; p = &a[0];allora vale la relazione
*(p + i) == a[i]
Primo esercizio puntatori
main() { int n; int *p; int x[100]; p=x; p[0]=3; // assegno un valore alla variabile n n=5; printf("Il valore della variabile n e' %d\n", n); printf("L'indirizzo della variabile n e' %d\n\n", &n); // assegno un valore al primo elemento dell'array x[] x[0]=5; printf("Il primo elemento dell'array x e' %d\n", x[0]); // assegno a p il valore dell'etichetta x p=x; // posso accedere al vettore x tramite il puntatore p printf("p[0] vale %d", p[0]); printf(" e p vale %d\n\n", p); // MA NON POSSO FARE IL VICEVERSA !!!! // x è solo una etichetta NON un puntatore !!!! // verifica: SE COMPILO HO ERRORE // x=p; // printf("x[0] vale %d\n\n", x[0]); // Infatti un puntatore è una variabile QUINDI occupa spazio in memoria. // x è una etichetta e NON occupa spazio in memoria. x[], che è // una variabile, occupa spazio in memoria // ATTENZIONE: // variabile -> occupa celle di memoria // puntatore -> occupa celle di memoria // etichetta -> NON occupa celle di memoria (serve solo al compilatore) // QUINDI: // variabile -> ha un indirizzo // puntatore -> ha un indirizzo // etichetta -> NON ha un indirizzo: E' UN INDIRIZZO !!!!!! // verifica: printf("L'indirizzo di x[0] e' %d\n", &(x[0])); printf("L'indirizzo di x e' %d\n", &x); // INTERPRETATO DAL COMPILATORE // COME &(x[0]) printf("L'indirizzo di p e' %d\n", &p); }
Esercizio Array in memoria
Che indirizzo hanno le celle di un array?
main() { int i, x[100]; for(i=0; i<100; i++) x[i]=i+1; printf("Il valore di x e' %d\n", x); printf("Il valore di x[0] e' %d\n", x[0]); printf("L'indirizzo di x[0] e' %d\n", &x[0]); printf("Il valore di x[99] e' %d\n", x[99]); printf("L'indirizzo di x[99] e' %d\n", &x[99]); printf("La memoria occupata dal vettore e' %d\n", (void *)&x[99]+sizeof(int)-(void *)&x[0]); }
Secondo esercizio puntatori
Come mai la somma non sembra funzionare con i puntatori?
Come mai gli indirizzi p1 e p2 sono così diversi?#include <stdio.h> int i=2; // Questa è una variabile globale. Viene messa dal compilatore // nel segmento dati main() { double d=2.0; int * p1; double * p2; p1=&i; p2=&d; printf("\n"); printf("*p1 vale %d\n",*p1); printf("p1 vale %d\n",p1); printf(" ... mentre p1+1: %d\n\n",p1+1); printf("*p2 vale %f\n",*p2); printf("p2 vale %d\n",p2); printf(" ... mentre p2+1: %d\n\n",p2+1); }
s[3]='c';e
*(s+3)='c';sono equivalenti. Scegliamo il primo modo!
/* * fattoriale */ #include <stdio.h> #include <stdlib.h> void main() { int n, fatt; // con delle virgole si dichiarano tante variabili int int i; // indice del ciclo /* input dell'intero */ printf("intero---->"); scanf("%d", &n); /* calcolo del fattoriale */ fatt=1; /* provate a togliere questa riga e vedete cosa succede!!! */ for (i=1; i<=n; i++) { fatt = fatt * i; } /* visualizzazione risultato */ printf("\n Il fattoriale di %d e' l'intero %d\n",n,fatt); }
/* * fattoriale con funzione */ #include <stdio.h> int calcola_fattoriale(int n); void main() { int n, fatt; // con delle virgole si dichiarano tante variabili int /* input dell'intero */ printf("intero---->"); scanf("%d", &n); /* calcolo del fattoriale */ fatt=calcola_fattoriale(n); /* visualizzazione risultata */ printf("\n Il fattoriale di %d e' l'intero %d\n",n,fatt); } int calcola_fattoriale(int n) // Il calcola del fattoriale è racchiuso in questa funzione { int i, fatt=1; for (i=1; i<=n; i++) { fatt = fatt * i; } return(fatt); // ritorna il valore calcolato }
/* * fattoriale con procedura */ #include <stdio.h> void calcola_fattoriale(int n, int *fatt); void main() { int n, fatt; // con delle virgole si dichiarano tante variabili int /* input dell'intero */ printf("intero---->"); scanf("%d", &n); /* calcolo del fattoriale */ calcola_fattoriale(n, &fatt); /* visualizzazione risultata */ printf("\n Il fattoriale di %d e' l'intero %d\n",n,fatt); } void calcola_fattoriale(int n, int *fatt) // Il fattoriale è calcolato con una procedura: nota che il // tipo di dato che restituisce è void // Inoltre nota che int è stato specificato due volte. // Non è possibile usare (int n, *fatt) { int i; *fatt=1; for (i=1; i<=n; i++) { *fatt = *fatt * i; } // non c'è il return }
/* * fattoriale con ricorsione */ #include <stdio.h> int calcola_fattoriale(int n); void main() { int n, fatt; // con delle virgole si dichiarano tante variabili int /* input dell'intero */ printf("intero---->"); scanf("%d", &n); /* calcolo del fattoriale */ fatt=calcola_fattoriale(n); /* visualizzazione risultata */ printf("\n Il fattoriale di %d e' l'intero %d\n",n,fatt); } int calcola_fattoriale(int n) // La funzione è ricorsiva, cioè chiama se stessa { int risultato; if(n==1) risultato=1; else risultato=n*calcola_fattoriale(n-1); return(risultato); }
Esercizio 1
Usando DevC++, scrivi un breve programma che inizializza una stringa s al valore esercitazione e la stampa.
Sostituisci al terminatore di stringa uno spazio ' '. Cosa succede?
Il programma termina? Se si interrompe, perché accade?
Esercizio 2
Incolla in un file il testo del programma che calcola il fattoriale di un numero intero. Compilalo e prova ad eseguirlo.
Aggiungi un ciclo che permetta all'utente di calcolare più di un risultato, senza dover eseguire nuovamente il programma. (Suggerimento: chiedi all'utente se vuole continuare o no).
Perchè con numeri interi grandi vengono fuori valori strani?
Cosa succede se fatt è un long?
Esercizio 3
Svolgi l'esercizio descritto nel file CarattereCompito.c.
Aggiungi un puntatore per ogni tipo di dato e metti in ciascuno l'indirizzo della variabile corrispondente. Quindi usa printf per vedere il valore dei puntatori.
Cosa succede se stampi la somma di due puntatori?
Esercizio 4
Il programma massimoCompito.c calcola il massimo di un insieme di valori fornito dall'utente. Studialo e quindi individua l'errore.
Rivedi l'esercizio Media.c, che era uno dei compiti per casa della scorsa lezione. Completa ora il programma massimoMediaminimoCompito.c.
Esercizio 5: FACOLTATIVO
Completa i due programmi critta1compito.c e decritta1compito.c.
©2003 Roberto Sassi