Lezione 16 (2 aprile 2012)

31
Dipartimento Ingegneria Chimica Materiali Ambiente Abilità Informatiche Lezione del 2 Aprile 2012 Prof. Antonino Stelitano

Transcript of Lezione 16 (2 aprile 2012)

Page 1: Lezione 16 (2 aprile 2012)

Dipartimento Ingegneria Chimica Materiali Ambiente

Abilità Informatiche

Lezione del 2 Aprile 2012

Prof. Antonino Stelitano

Page 2: Lezione 16 (2 aprile 2012)

Docente Antonino

Stelitano

Tutor Da definire

Lezioni Lunedì

Mercoledì

14:00 – 17:30 aula 16

Lab. Paolo Ercoli

15:45 – 19:00 aula 17

Lab. Paolo Ercoli

Ricevimento: Per

appuntamento

[email protected]

[email protected]

Sito web: http://w3.uniroma1.it/ab_informatiche/

Page 3: Lezione 16 (2 aprile 2012)

Nome dei campi

• I nomi dei campi all’interno di una struttura devono essere unici, ma campi di strutture differenti possono avere lo stesso nome. – questo non crea ambiguità perché i metodi di accesso ad una

struttura usano sempre il nome della struttura,

struct frutta { char *nome; int calorie; };

struct vegetale { char *nome; int calorie; };

struct frutta a; a.nome struct vegetale c, d; c.nome c.calorie

3

Page 4: Lezione 16 (2 aprile 2012)

• Dati

– Gruppo di contribuenti memorizzati con nome, codice

fiscale, data di nascita (giorno, mese, anno)

– 1000 contribuenti memorizzati in un array

• Problema

– Contare il numero di persone che hanno un’età compresa

tra due valori dati

– Supponiamo di avere definito una funzione leggi per

memorizzare l’array

4

Page 5: Lezione 16 (2 aprile 2012)

Definizione di contribuente struct contribuente {

char nome[15], cod_fis[17];

short int giorno, mese, anno; };

typedef struct contribuente Contribuente;

Definizione matrice dei contribuenti Contribuente gruppo [DIM];

5

Page 6: Lezione 16 (2 aprile 2012)

#include <stdio.h>

#define DIM 1000

int conta_persone (Contribuente [ ], int, int, int);

int leggi (Contribuente [ ]);

int main (void) {

struct contribuente {

char nome[15], cod_fis[17];

short int giorno, mese, anno; };

typedef struct contribuente Contribuente;

Contribuente gruppo [DIM];

int min=20, max=45, a_cor=2002, num_persone=0;

leggi(gruppo);

num_persone =conta_persone (gruppo, min, max ,a_cor);

printf(“Persone di eta’ compresa tra %d e %d anni: %d\n”, min, max, num_persone);

return 0;

}

6

Page 7: Lezione 16 (2 aprile 2012)

int conta_persone (Contribuente gruppo [], int low_age, int high_age, int current_year)

{

int i, age, count = 0;

for ( i = 0; i < size; ++i)

{

age = current_year - gruppo[i].anno;

if (age >= low_age && age <= high_age) count++;

}

return count;

}

7

Page 8: Lezione 16 (2 aprile 2012)

Utilizzo di strutture con funzioni

• Le strutture possono essere passate come parametri a funzioni e possono a loro volta essere restituite dalle funzioni stesse.

• intera struttura

• singoli membri

• puntatori a una struttura

• Quando viene passata una struttura o i suoi membri, il passaggio è per valore: la struttura o i suoi membri non sono modificati

– copia locale nel corpo della funzione chiamata.

– se uno dei membri della struttura è un array, anch’esso viene copiato.

• il passaggio di una struttura per valore può risultare inefficiente.

• Alternativa: passaggio della struttura per riferimento con lo indirizzo della variabile di struttura.

8

Page 9: Lezione 16 (2 aprile 2012)

Esempio:

typedef struct {

char nome [25];

int mat_impiegato;

struct dept sezione;

double salario;

… … …………………………………

} impiegato;

• Si deve definire struct dept prima dell’uso perché il compilatore deve conoscere la dimensione di ogni membro della struttura

struct dept {

char nome_sezione;

int numero_sezione;

};

• Funzione che aggiorna le informazioni sugli impiegati.

9

Page 10: Lezione 16 (2 aprile 2012)

void aggiorna (impiegato *p)

{ …………………………….

printf (“Inserisci il numero della sezione: \n”);

scanf (“%d”, &n);

p -> sezione.numero_sezione = n;

………………..

}

• p -> sezione.numero_sezione è equivalente a

(p -> sezione.numero_sezione)

• si accede, tramite un puntatore, a un campo

• aggiorna ( ) può essere usata chiamata così:

impiegato e;

aggiorna(&e);

• viene passato l’indirizzo di e

• Non è quindi necessario effettuare alcuna copia locale della struttura in aggiorna ( )

10

Page 11: Lezione 16 (2 aprile 2012)

• Altrimenti modifica all’interno della funzione (o

main) che contiene la struttura

• Accesso a un membro di una struttura all’interno

di una struttura:

e.sezione.numero_sezione

• che è equivalente a (e.sezione).numero_sezione

11

Page 12: Lezione 16 (2 aprile 2012)

Strutture nidificate

• Una struttura nidificata è una struttura un cui almeno uno degli elementi è a sua volta una struttura.

• La precedente struttura contribuente potrebbe essere definita così:

typedef struct {

char nome[15], cod_fis[17];

struct {

short int giorno, mese, anno; } data_nascita;

} Contribuente;

• I tre campi che rappresentavano la data di nascita sono sostituiti da una struttura che contiene tre elementi.

• L’allocazione di memoria rimane inalterata, ma invece di accedere all’anno come cont1.anno si deve scrivere

cont1.data_nascita.anno

12

Page 13: Lezione 16 (2 aprile 2012)

Esempio10.3, p.355, Deitel& Deitel

• Simulazione di un mescolatore e distributore di carte

• Rappresentiamo il mazzo con un vettore i cui elementi sono

carte

• Una carta è definita con una struttura

• Per mescolare il mazzo ci serve un generatore di numeri casuali

13

Page 14: Lezione 16 (2 aprile 2012)

rand, srand, time

• Funzione rand ( )

– Generatore di numeri pseudocasuali

– Sempre la stessa sequenza

– Per cambiare sequenza ha bisogno di una specie di

inizializzazione tramite srand

• Funzione srand (unsigned int)

– Prende come argomento un unsigned int

– A seconda del valore dato genera una sequenza diversa

– Per non immettere il valore usiamo la funzione time

• Funzione time(NULL)

– Restituisce l’ora espresso in secondi

– Contenuta in time.h 14

Page 15: Lezione 16 (2 aprile 2012)

Generazione di numeri casuali

• Inizializzazione srand (time(NULL))

• j = rand () % 52;

– rand produce un intero

– Il modulo di questo intero su 52 (che è il numero

delle carte) da’ un valore compreso tra 0 e 51

• Il resto è sempree minore di 52

– Viene utilizzato per determinare a quale carta dare il

valore

15

Page 16: Lezione 16 (2 aprile 2012)

Esercizio

• Scrivere un programma che, data una stringa di

N caratteri, la inverta (es: "Informatica" diventa

"acitamrofnI")

16

Page 17: Lezione 16 (2 aprile 2012)

Soluzione #include <stdio.h>

#define N 31

void scambia(char *a, char *b) {

char aux;

aux = *a;

*a = *b;

*b = aux; }

/* Funzione che calcola la lunghezza della stringa */

int lung(char s[]) {

int i;

/* incremento il contatore fintanto che non incontro il carattere di terminazione */

for (i=0; s[i] != '\0'; i++);

return i;

}

17

Page 18: Lezione 16 (2 aprile 2012)

Soluzione

void inverti2(char v[])

{ int i,l;

l = lung(v); for (i=0; i<l/2; i++) scambia(&v[i],&v[l-i-1]);

}

main() {

char s[N];

scanf("%s",s); inverti2(s); printf("\nStringa invertita: %s",s);

}

18

Page 19: Lezione 16 (2 aprile 2012)

Esercizio

• Scrivere la funzione "massimoMatrice", che calcola il massimo della matrice e la sua posizione.

• La funzione riceve come parametri:

– un array bidimensionale di interi

– due interi che rappresentano le due dimensioni dell'array

– gli indirizzi di due variabili intere per memorizzare gli indici del massimo

• La funzione restituisce il valore del massimo della matrice.

19

Page 20: Lezione 16 (2 aprile 2012)

Soluzione

#include <stdio.h>

#include <stdlib.h>

#define R 3

#define C 2

void stampaMatrice(int [][C], int, int);

void leggiMatrice(int [][C], int, int);

int massimoMatrice (int [][C], int *, int *, int , int );

20

Page 21: Lezione 16 (2 aprile 2012)

Soluzione int main()

{

/* variabile a cui assegnare il valore restituito dalla funzione massimoMatrice */

int massimo;

/* variabili che devono essere modificate dalla funzione massimoMatrice

per restituire gli indici del valore massimo */

int riga = -1, colonna = -1;

int mat[R][C];

leggiMatrice(mat, R, C);

stampaMatrice(mat, R, C);

massimo = massimoMatrice (mat, &riga, &colonna, R, C);

printf("\nMassimo della matrice: %d\n", massimo);

printf ("Posizione: riga %d, colonna %d\n", riga, colonna);

system("pause");

return 0;

}

21

Page 22: Lezione 16 (2 aprile 2012)

Soluzione

void leggiMatrice(int m[][C], int dim1, int dim2)

{

int i, j;

printf("Inserire gli elementi di una matrice di interi %dx%d\n", dim1, dim2);

for (i = 0; i < dim1; i++)

for (j = 0; j < dim2; j++) {

printf("Elemento %d %d: ", i, j);

scanf("%d", &m[i][j]);

}

}

22

Page 23: Lezione 16 (2 aprile 2012)

Soluzione

void stampaMatrice(int m[][C], int dim1, int dim2)

{

int i, j;

printf("\nStampa della matrice:\n");

for (i = 0; i < dim1; i++) {

for (j = 0; j < dim2; j++)

printf("%5d", m[i][j]);

printf("\n");

}

}

23

Page 24: Lezione 16 (2 aprile 2012)

Soluzione

int massimoMatrice (int matrice[][C], int *r, int *c, int dim1, int dim2)

{

int i, j, max;

max = matrice[0][0];

*r = 0;

*c = 0;

for (i = 0; i < dim1; i++)

for (j = 0; j < dim2; j++)

if ( matrice[i][j] >= max) {

max = matrice[i][j];

*r = i;

*c = j;

}

return max;

} 24

Page 25: Lezione 16 (2 aprile 2012)

Esercizio

• Completare il programma scrivendo due funzioni "simmetrica" e

"diagonale", che verificano rispettivamente se una data matrice quadrata e'

simmetrica e diagonale.

• Entrambe le funzioni ricevono come parametri:

– un array bidimensionale di interi

– la dimensione dell'array

• La funzione "simmetrica" restituisce il valore 1 se l'array bidimensionale

corrisponde a una matrice simmetrica, 0 altrimenti.

– Una matrice quadrata si dice simmetrica se gli elementi della matrice sono

simmetrici rispetto alla diagonale principale.

• La funzione "diagonale" restituisce il valore 1 se l'array bidimensionale

corrisponde a matrice diagonale, 0 altrimenti.

– Una matrice quadrata si dice diagonale se tutti gli elementi all'esterno della

diagonale principale sono nulli.

• Una matrice diagonale e' anche simmetrica.

25

Page 26: Lezione 16 (2 aprile 2012)

Soluzione

#include <stdio.h>

#include <stdlib.h>

#define N 3

void stampaMatrice(int [][N], int);

void leggiMatrice(int [][N], int);

int simmetrica (int [][N], int );

int diagonale (int [][N], int );

26

Page 27: Lezione 16 (2 aprile 2012)

Soluzione

int main()

{

int mat[N][N];

/* variabile a cui assegnare il valore restituito dalla funzione simmetrica */

int simm_ok = -1;

/* variabile a cui assegnare il valore restituito dalla funzione diagonale */

int diag_ok = -1;

leggiMatrice(mat, N);

stampaMatrice(mat, N);

simm_ok = simmetrica (mat, N);

27

Page 28: Lezione 16 (2 aprile 2012)

Soluzione

if ( simm_ok == 1 )

printf("\nLa matrice e' simmetrica\n");

if (simm_ok == 0 )

printf("\nLa matrice non e' simmetrica\n");

diag_ok = diagonale (mat, N);

if ( diag_ok == 1 )

printf("\nLa matrice e' diagonale\n");

if (diag_ok == 0 )

printf("\nLa matrice non e' diagonale\n");

system("pause");

return 0;

} 28

Page 29: Lezione 16 (2 aprile 2012)

Soluzione void leggiMatrice(int m[][N], int dim)

{

int i, j;

printf("Inserire gli elementi di una matrice quadrata di interi %dx%d\n", dim, dim);

for (i = 0; i < dim; i++)

for (j = 0; j < dim; j++) {

printf("Elemento %d %d: ", i, j);

scanf("%d", &m[i][j]);

}

}

void stampaMatrice(int m[][N], int dim)

{

int i, j;

printf("\nStampa della matrice:\n");

for (i = 0; i < dim; i++) {

for (j = 0; j < dim; j++)

printf("%5d", m[i][j]);

printf("\n");

}

} 29

Page 30: Lezione 16 (2 aprile 2012)

Soluzione

int simmetrica (int matrice[][N], int dim)

{

int i, j;

for (i = 0; i < dim; i++)

for (j = i+1; j < dim; j++)

if ( matrice[i][j] != matrice[j][i])

return 0;

return 1;

}

30

Page 31: Lezione 16 (2 aprile 2012)

Soluzione

int diagonale (int matrice[][N], int dim)

{

int i, j;

for (i = 0; i < dim; i++)

for (j = 0; j < dim; j++)

if ( i != j && matrice[i][j] != 0)

return 0;

return 1;

}

31