Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Corso di Programmazione 1 a.a.2006/2007 Prof.ssa Chiara Petrioli Corso di Laurea in Informatica Università degli Studi “La Sapienza” (lezioni 16-19) Strutture, Unioni e Liste
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Strutture Le strutture sono collezioni di variabili correlate sotto un unico nome Possono contenere variabili di diversi tipi di dato Esempio struct card{ char *face; char *suit; }; Definisce un tipo di dato struttura struct card costituita da due campi un campo face stringa che dice che carta è quella corrente: asso, due,…,re un campo suit stringa che dice il seme della carta corrente (cuori,…,fiori) Membri di una struttura Etichetta di una struttura
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Esempio Il recordi di un impiegato struct impiegato{ char *nome; char *cognome; int eta; char sesso; float stipendio; }; La struttura consente di raggruppare Informazioni correlate, in questo caso Relative ad un singolo impiegato
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Dichiarazione di variabili struct struct card a, deck[52], *cPtr; a è una variabile di tipo struct card viene allocata memoria per due campi puntatori deck è un vettore di strutture. Contiene 52 elementi. Ciascun elemento è una struttura costituita da due campi face e suit cPtr è un puntatore ad una struttura (contiene l’iundirizzo della locazione di memoria in cui è memorizzato un elemento di tipo struct card)
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Dichiarazione di variabili struct struct card a, deck[52], *cPtr; a è una variabile di tipo struct card viene allocata memoria per due campi puntatori deck è un vettore di strutture. Contiene 52 elementi. Ciascun elemento è una struttura costituita da due campi face e suit cPtr è un puntatore ad una struttura (contiene l’iundirizzo della locazione di memoria in cui è memorizzato un elemento di tipo struct card) ALTERNATIVA struct card{ char *face; char *suit; }a,deck[52],*cPtr;
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Operazioni su strutture Assegnare variabili struct a variabili struct dello stesso tipo di struttura Determinare in che locazione di memoria è memorizzata una struttura Accedere ai membri di una struttura (per leggere o scrivere il loro valore) Con l’operatore sizeof determinare la dimensione di una struttura (cosa che serve ad esempio per sapere quanta memoria deve essere allocata a ciascun elemento di quel tipo di dato struttura)
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Operazioni illecite Due elementi di tipo struttura non possono essere confrontati – Ci possono essere dei bit con valore indeterminato nelle locazioni di memoria allocate ad una struttura –Ad esempio struct example{ char c; int i; } sample1,sample2; Un computer con una parola di 2byte potrebbe richiedere l’allineamento all’inizio della parola successiva per membri successivi della struttura Buco. In questo byte potrebbe essere contenuto qualsiasi valore impossibile confrontare sample1 e sample2 direttamente. Bisogna confrontare i valori dei vari membri delle due strutture.
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Inizializzazione di strutture struct card{ char *face; char *suit; }; struct card a={“Asso”,”Fiori”}; Se il valore di un membro non è indicato tra le parentesi graffe è inizializzato automaticamente a 0 (o a NULL se è di tipo puntatore).
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Come si accede ai membri di una struttura Operatore membro di struttura (operatore punto.) – accede ad un membro della struttura attraverso il nome della variabile di struttura Esempio printf(“%s”, a.suit); Stampa il campo suit della variabile a, di tipo struct card
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Come si accede ai membri di una struttura Operatore puntatore a struttura -> – accede ad un membro della struttura attraverso un puntatore alla stessa Esempio printf(“%s”, cPtr->suit); Stampa il campo suit della struttura puntata da cPtr. cPtr è un puntatore ad una struttura di tipo struct card cPtr->suit equivale a (*cPtr).suit le parentesi sono necessarie perché l’operatore membro di struttura ha priorità maggiore di * Risolve il riferimento e accede al membro suit della struttura usando l’operatore membro di struttura
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Un esempio #include<stdio.h> struct card{ char *face; char *suit; };main(){ struct card a; struct card *aPtr; a.face =“Asso”; a.suit=“Picche”;aPtr=&a; printf(“%s di %s\n%s di %s\n %s di %s \n”, a.face, a.suit, aPtr->face, aPtr->suit, (*aPtr).face, (*aPtr).suit); return 0; } Asso di Picche
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Usare le strutture con le funzioni Le strutture possono essere passate alle funzioni fornendo i singoli membri, l’intera struttura o un puntatore ad una struttura. Vettori di strutture sono passati per riferimento. Per passare una struttura per riferimento si deve passare alla funzione l’indirizzo di memoria dove è memorizzata la struttura. Le funzioni possono restituire strutture Passati per valore Può consentire ad una funzione di restituire più valori
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Un esempio Si scriva una funzione che dato un vettore restituisca il più piccolo elemento del vettore ed il più grande elemento del vettore Definiamo: struct min_max{ int min; int max; };
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007Soluzione struct min_max minmax_v (int vett[ ], int n) { struct min_max temp; if (n==1) {temp.min=vett[0];temp.max=vett[0]; return temp; }else{temp=minmax_v(vett,n-1); if (vett[n-1]<temp.min) temp.min=vett[n-1]; if (vett[n-1]>temp.max) temp.max=vett[n-1]; return temp; }} La funzione minmax_v prende in input un vettore di interi vett e la sua dimensione n restituisce in output una struttura di tipo min_max che contiene nei suoi membri il minimo ed il massimo tra gli elementi del vettore
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Come si può passare per valore un vettore Dobbiamo creare una struttura che contenga come membro il vettore Dato che una struttura o i membri della struttura sono passati per valore il vettore verrà passato nello stesso modo (basta passare alla funzione il membro della struttura che contiene il vettore) – Verrà quindi fatta una copia del vettore e si opererà su tale copia
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007typedef La parola chiave typedef consente di creare pseudonimi per i tipi di dato precedentemente definiti, tipicamente per abbreviare i nomi di tali tipi di dato typedef struct card Card; dice che nel seguito del programma quando si troverà scritto Card di farà riferimento al tipo struct card Card deck[52]; Card NON è un nuovo tipo di dato, è un sinonimo per struct card !
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007Esempio Mescolatore di carte (variante ad alta efficienza di quello precedentemente visto) Vettore di tipo Card fillDeck inizializzato in modo da contenere le carte ordinate dall’asso al re per ogni seme La funzione shuffle che mescola il mazzo riceverà come input un vettore di 52 strutture di tipo Card, scorrerà le carte e per ogni carta sceglierà un numero casuale tra 0 e 51 (carta con cui la carta esaminata sarà scambiata). Mescola effettuando scambi, non potendo portare ad attese lunghe o indefinite per il completamento.
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007Codice #include #include #include<stdlib.h>#include<time.h> struct card { char *face; char *suit; }; typedef struct card Card; void fillDeck (Card *,char *[ ], char *[ ]); void shuffle(Card *); void deal(Card *);
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007Codicemain(){ Card deck[52]; char *face[ ]={“Asso”, “Due”, “Tre”, “Quattro”, “Cinque”, “Sei”, “Sette”, “Otto”, “Nove”, “Dieci”, “Fante”, “Donna”, “Re”}; char *suit[ ]={“Cuori”, “Quadri”, “Picche”, “Fiori”}; srand(time(NULL)); fillDeck(deck, face, suit); shuffle(deck);deal(deck); return 0; } Deck è un vettore di strutture
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Codice void fillDeck(Card *wDeck, char *wFace[ ], char *wSuit[ ]) { int i; for (i=0;i<=51;i++) {wDeck[i].face=wFace[i%13];wDeck[i].suit=wSuit[i/13];}} Inizializziamo al caso in cui per ciascun seme le carte sono ordinate
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007Codice void shuffle(Card *wDeck) { int i,j; Card temp; for (i=0;i<=51;i++){ j=rand()%52;temp=wDeck[i];wDeck[i]=wDeck[j];wDeck[j]=temp;}}
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Codice void deal (Card *wDeck) { int i; for (i=0;i<=51;i++) printf(“%s of %s \n, wDeck[i].face, wDeck[i].suit); }