24
MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in linguaggio C che legga da un file “input.txt” una sequenza di interi rappresentanti dei voti d’esame (quindi compresi tra 18 e 30): Esempio: Input.txt 27 30 18 18 21 25 18 30 28 30 30 Stampi su file output.txt il voto massimo ed il corrispondente numero di occorrenze. Ad esempio: Output.txt 30 4 Nello scrivere il programma si implementino ed utilizzino le seguenti strutture dati e funzioni: (2 punti) Tipo di dato strutturato tipo_statistiche costituito da: Un intero chiamato massimo; un intero chiamato occorrenze. (1 punto) Tipo di dato tipo_voto costituito da N variabili di tipo intero. (6 punti) Funzione leggi_interi con: tipo in ingresso: stringa indicante il nome_file da aprire e una variabile di tipo tipo_voto chiamata voti; tipo in uscita: intero. La funzione legge dal file chiamato nome_file una sequenza di interi, e la memorizza in voti. Restituisce il numero di interi letti. (10 punti) Funzione estrai_statistiche con: tipo in ingresso: tipo_voto di nome voti, una variabile num_voti indicante il numero di voti di cui è costituita voti tipo in uscita: tipo_statistiche La funzione restituisce scrive negli slot massimo ed occorrenze di una variabile di tipo tipo_statistiche il voto massimo e il numero di volte che esso appare in voti. (6 punti) Funzione scrivi_risultati tipi in ingresso: tipo_statistiche chiamata s tipo in uscita: vuoto Stampa su file “output.txt” gli slot massimo e occorrenze di s. Soluzione.

MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI

ESERCIZIO 1

(8 punti) Scrivere un programma in linguaggio C che legga da un file “input.txt” una

sequenza di interi rappresentanti dei voti d’esame (quindi compresi tra 18 e 30):

Esempio:

Input.txt 27 30 18 18 21 25 18 30 28 30 30

Stampi su file output.txt il voto massimo ed il corrispondente numero di occorrenze. Ad

esempio:

Output.txt 30 4

Nello scrivere il programma si implementino ed utilizzino le seguenti strutture dati e funzioni:

(2 punti) Tipo di dato strutturato tipo_statistiche costituito da:

Un intero chiamato massimo;

un intero chiamato occorrenze.

(1 punto) Tipo di dato tipo_voto costituito da N variabili di tipo intero.

(6 punti) Funzione leggi_interi con:

tipo in ingresso: stringa indicante il nome_file da aprire e una variabile di tipo

tipo_voto chiamata voti;

tipo in uscita: intero.

La funzione legge dal file chiamato nome_file una sequenza di interi, e la memorizza in

voti. Restituisce il numero di interi letti.

(10 punti) Funzione estrai_statistiche con:

tipo in ingresso: tipo_voto di nome voti, una variabile num_voti indicante il numero

di voti di cui è costituita voti

tipo in uscita: tipo_statistiche

La funzione restituisce scrive negli slot massimo ed occorrenze di una variabile di tipo

tipo_statistiche il voto massimo e il numero di volte che esso appare in voti.

(6 punti) Funzione scrivi_risultati

tipi in ingresso: tipo_statistiche chiamata s

tipo in uscita: vuoto

Stampa su file “output.txt” gli slot massimo e occorrenze di s.

Soluzione.

Page 2: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 2

Definizione del tipo di dato richiesto:

typedef int tipo_voto[N];

typedef struct

{

int massimo;

int occorrenze;

} tipo_statistiche;

Prototipi delle funzioni assegnate:

int leggi_interi(char *nome_file, tipo_voto voti);

tipo_statistiche estrai_statistiche(tipo_voto voti, int n);

void scrivi_risultati(tipo_statistiche s);

Implementazione del programma:

/*Programma per la lettura di voti e docenti*/

#include <stdio.h>

#define N 100

/*Definizione del tipo*/

/*Prototipi delle funzioni*/

int main()

{

tipo_voto voti;

tipo_statistiche s;

int n;

n=leggi_interi(“input.txt”,voti);

s=estrai_statistiche(voti,n);

scrivi_risultati(s);

return 0;

}

Implementazione delle singole funzioni:

int leggi_interi(char* nome_file, tipo_voto voti)

{

FILE *fp;

int n;

n=0;

fp=fopen(nome_file,”r”);

while((!feof(fp))&&(n<N))

{

fscanf(fp,”%d”,&voti[n]);

n++;

}

fclose(fp);

return n;

}

tipo_statistiche estrai_statistiche(tipo_voto voti, int n)

{

Page 3: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 3

tipo_statistiche s;

int i;

/* prima di tutto trovo il massimo voto */

s.massimo=0;

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

if(voti[i]>s.massimo)

s.massimo=voti[i];

/* ora trovo il numero di occorrenze del massimo voto */

s.occorrenze=0;

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

if(voti[i]==s.massimo)

s.occorrenze++;

return s;

}

void scrivi_risultati(tipo_statistiche s)

{

FILE *fp;

fp=fopen(“output.txt”,”w”);

fprintf(fp,”%d %d\n”,s.massimo, s.occorrenze);

fclose(fp);

}

Page 4: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 4

ESERCIZIO 2

(8 punti) Scrivere un programma in linguaggio C che legga da un file “input.txt” una

sequenza di interi {vi} con i=0,…,N-1. Scriva su file “output.txt” una sequenza {si} tale

che s0=v0 e si=si-1+vi. Il primo valore intero del file è relativo al numero complessivo di interi

da leggere.

Esempio:

Input.txt 5 21 3 50 10 -4

Output.txt 21 24 74 84 80

Nello scrivere il programma si implementino ed utilizzino le seguenti strutture dati e funzioni:

(3 punti) Tipo di dato strutturato tipo_dati costituito da:

Puntatore ad intero chiamato v;

Puntatore ad intero chiamato s;

Una variabile intera n corrispondente al numero di dati contenuti in v e s;

(6 punti) Funzione leggi_dati con:

tipo in ingresso: stringa indicante il nome_file da aprire;

tipo in uscita: tipo_dati.

La funzione legge dal file chiamato nome_file una sequenza di interi, e li memorizza nello

slot v della variabile di tipo tipo_dati restituita in uscita. La funzione memorizza nello slot n il

numero di valori letti da file.

(10 punti) Funzione calcola_somma con:

tipo in ingresso: puntatore a vettore di interi v, intero chiamato n

tipo in uscita: puntatore a vettori di interi

La funzione scrive, nella componente i-esima di un vettore dinamico s, restituito in uscita,

la sequenza {si} secondo la definizione fornita dal testo, in funzione della sequenza {vi},

rappresentata da v.

(6 punti) Funzione scrivi_risultati

tipi in ingresso: tipo_dati chiamato d

tipo in uscita: vuoto

Stampa su file “output.txt” le componenti dello slot s di d.

Page 5: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 5

Soluzione.

/*Programma per il calcolo della somma cumulativa di una stringa di interi*/

#include <stdio.h>

typedef struct

{

int *v, *s;

int n;

} tipo_dati;

tipo_dati leggi_dati(char* nome_file)

{

FILE *fp;

tipo_dati d;

int i;

fp=fopen(nome_file,”r”);

fscanf(fp, ”%d”,&d.n);

i=0;

d.v=(int*)malloc(sizeof(int)*d.n);

while(i<d.n)

{

fscanf(fp,”%d”,&d.v[i]);

i++;

}

fclose(fp);

return d;

}

int* calcola_pari_dispari(int* v, int n)

{

int* s;

int i;

s=(int*)malloc(sizeof(int)*n);

s[0]=v[0];

for(i=1; i<n; i++)

s[i]=s[i-1]+v[i];

return s;

}

void scrivi_risultati(tipo_dati d)

{

FILE *fp;

int i;

fp=fopen(“output.txt”,”w”);

for(i=0; i<d.n; i++)

fprintf(fp,“%d “,d.s[i]);

fclose(fp);

}

Page 6: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 6

int main()

{

tipo_dati d;

d=leggi_dati(“input.txt”); /*Leggo*/

d.s=calcola_somme(d.v,d.n); /*Elaboro*/

scrivi_risultati(d); /*Scrivo*/

/*Ciclo della macchina di Von Neumann*/

free(d.v);

free(d.s);

return 0;

}

Page 7: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 7

ESERCIZIO 3

(7 punti) Scrivere un programma in linguaggio C che legga da un file “input.txt” una sequenza di

reali rappresentanti il saldo iniziale e la lista dei movimenti di un conto corrente (in entrata e in uscita).

Esempio:

Input.txt 1000.0 27.0 -30.0 18.0 -18.0 21.0 25.0 -18.0 30.0 -28.0 30.0 30.0

Stampi su file output.txt il saldo iniziale, quello finale, la somma delle entrate e quella delle uscite. Per

esempio:

Output.txt 1000.0 1087.0 181.0 94.0

Nello scrivere il programma si implementino ed utilizzino le seguenti strutture dati e funzioni:

(4 punti) Tipo di dato strutturato tipo_movimenti costituito da:

Un reale chiamato saldo_iniziale, un reale chiamato saldo_finale;

Due liste concatenate di reali chiamate entrate e uscite, definite secondo gli schemi illustrati

a lezione e dotate delle quattro operazioni fondamentali CONS, HEAD, TAIL e ISEMPTY. Le variabili

sono di tipo tipo_lista.

Due reali chiamati somma_entrate e somma_uscite.

(8 punti) Funzione leggi_movimenti con:

tipo in ingresso: stringa indicante il nome_file da aprire;

tipo in uscita: tipo_movimenti.

La funzione legge dal file chiamato nome_file una sequenza di reali caratterizzanti il saldo e la lista

movimenti, e memorizza negli appositi slot di una variabile m di tipo tipo_movimenti, restituita in

uscita: il saldo iniziale e la sequenza dei movimenti in entrata (positivi) e quelli in uscita (negativi)

negli slot corrispondenti entrate e uscite.

(6 punti) Funzione somma_vettore con:

tipo in ingresso: tipo_lista di nome l

tipo in uscita: reale

La funzione restituisce la somma dei valori presenti in l.

(8 punti) Funzione scrivi_risultati

tipi in ingresso: tipo_movimenti chiamata m

tipo in uscita: vuoto

Stampa su file “output.txt” ogni la sequenza di slot di m: saldo_iniziale, saldo_finale,

somma_entrate, somma_uscite.

Page 8: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 8

Soluzione.

Definizione del tipo di dato richiesto:

typedef struct

{

float saldo_iniziale, saldo_finale;

tipo_lista *entrate, *uscite;

float somma_entrate, somma_uscite;

} tipo_movimenti;

Prototipi delle funzioni assegnate:

tipo_movimenti leggi_movimenti(char *nome_file);

float somma_vettore(tipo_lista* v);

void scrivi_risultati(tipo_movimenti m);

Implementazione del programma:

/*Programma per la lettura di voti e docenti*/

#include <stdio.h>

/*Definizione del tipo*/

/*Prototipi delle funzioni*/

int main()

{

tipo_movimenti m;

m=leggi_movimenti(“input.txt”);

m.somma_entrate=somma_vettore(m.entrate);

m.somma_uscite=-somma_vettore(m.uscite);

m.saldo_finale=m.saldo_iniziale+m.somma_entrate-m.somma_uscite;

scrivi_risultati(m);

/*DA aggiungere: funzione di deallocazione delle liste concatenate in m*/

return 0;

}

Implementazione delle singole funzioni:

Page 9: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 9

tipo_movimenti leggi_interi(char* nome_file)

{

FILE *fp;

tipo_movimenti m;

float valore;

m.entrate=NULL;

m.uscite=NULL;

fp=fopen(nome_file,”r”);

fscanf(fp,”%f”, &m.saldo_iniziale);

while((!feof(fp))

{

fscanf(fp,”%f”,&valore);

if(valore>0)

m.entrate=CONS(m.entrate,valore);

else

m.uscite=CONS(m.uscite,valore);

}

fclose(fp);

return m;

}

float somma_vettore(tipo_lista* l)

{

float somma;

somma=0.0;

while(!ISEMPTY(l))

{

somma=somma+HEAD(l);

l=TAIL(l);

}

return somma;

}

void scrivi_risultati(tipo_movimenti m)

{

FILE *fp;

fp=fopen(“output.txt”,”w”);

fprintf(fp,“%f %f ”,m.saldo_iniziale,m.saldo_finale);

fprintf(fp,”%f %f\n”,m.somma_entrate,m.somma_uscite);

fclose(fp);

}

Page 10: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 10

ESERCIZIO 4

(4 punti) Scrivere un programma in linguaggio C che legga da un file “input.txt” una sequenza

di triple formate ciascuna da un intero e un float, indicanti matricola e media voti di uno

studente, e un carattere avente come possibili valori ‘R’, ‘P’, ‘B’, indicante il tipo di tesi (Ricerca,

Progetto, Bibliografica) da egli richiesta. Il programma scriva su un file “output.txt”, il numero di

matricola dello studente avente media più alta per ciascuno dei tipi di tesi di richiesto

(nell’ordine Ricerca, Progetto, Bibliografica). Se non c’è alcuno studente con tesi di un certo

tipo, l’output corrispondente dev’essere “Studente assente”.

Esempio:

File “input.txt” 19475 27.5 R

20100 30.4 B

14002 26.1 B

21002 22.2 R

10022 23.6 B

23131 30.1 R

Con l’esempio di sopra il file output.txt va scritto come segue:

File “output.txt” 23131

Studente assente

20100

Nello scrivere il programma si implementino ed utilizzino le seguenti strutture dati e funzioni:

(1 punti) Tipo dato Tesi costituito da un carattere.

(2 punti) Tipo dato strutturato Studenti costituito da un vettore statico, chiamato matricole,

di N variabili intere corrispondenti alle matricole lette, un vettore statico, chiamato medie, di N

float corrispondenti alle medie lette, un vettore statico, chiamato tesi, di N variabili di tipo

Tesi, un intero n corrispondente al numero di variabili effettivamente inizializzate.

(4 punti) Funzione leggi con:

* tipo in ingresso: una stringa nomefile

* tipo in uscita: puntatore a Studenti

Legge da file di nome nomefile una sequenza di triple costituita da un intero, un float, e un

carattere. La i-esima tripla letta è memorizza nelle corrispondenti i-esime componenti degli

slot matricole, medie e tesi, di una variabile puntatore a Studenti restituita poi in uscita.

(5 punti) Funziona calcola_massimo con

* tipi in ingresso: una variabile puntatore a Studenti e una variabile t di tipo Tesi;

* tipo in uscita: intero, ovvero la matricola corrispondente alla massima media riscontrata tra le

matricole con tesi eguali a t. Restituisce -1 se non ci sono tesi eguali a t.

(2 punti) Funzione scrivi con:

* tipi in ingresso: una stringa nomefile, un intero

* tipo in uscita: void

Scrive su file di nome nomefile, l’intero fornito in ingresso.

N.B. scegliere la modalità appropriata per la scrittura su file

Page 11: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 11

Soluzione.

Tipi da definire:

typedef Tesi char;

typedef struct

{

int matricole[N];

float medie[N];

Tesi tesi[N];

int n;

} Studenti;

Prototipi delle funzioni assegnate:

Studenti* leggi(char* nomefile);

int calcola_massimo(Studenti* l, Tesi t);

void scrivi(char* nomefile, int m);

Implementazione del programma:

/*Programma per l’analisi di vettori*/

#include <stdio.h>

#define N 100 /*esempio*/

/*Definizione del tipo*/

/*Prototipi delle funzioni*/

int main()

{

Studenti *l;

int max_matricola, i;

l=leggi(“input.txt”);

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

{

switch(i)

{

case 0: max_matricola=calcola_massimo(l,’R’); break;

case 1: max_matricola=calcola_massimo(l,’P’); break;

case 2: max_matricola=calcola_massimo(l,’B’);

}

scrivi(“output.txt”,max_matricola);

}

return 0;

}

Page 12: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 12

Implementazione delle singole funzioni:

Studenti* leggi(char* nomefile)

{

FILE *fp;

Studenti* l;

l=(Studenti*)malloc(sizeof(Studenti));

l->n=0;

fp=fopen(nomefile,”r”);

while((!feof(fp))&&(l->n<N))

{

fscanf(fp,“%d %f %c”,&l.matricole[l->n],&l.medie[l->n],&l.tesi[l->n]);

l->n++;

}

fclose(fp);

return l;

}

int calcola_massimo(Studenti* l, tipo_tesi t)

{

int i, maxmat;

float maxm;

maxmat=-1;

maxm=-1.0;

for(i=0; i<l->n; i++)

if((l->tesi[i]==t)&&(l->medie[i]>maxm))

{

maxm=l->medie[i];

maxmat=l->matricole[i];

}

return maxmat; /*restituisce -1 se non ho trovato tesi di tipo t*/

}

void scrivi(char* nomefile, int m)

{

FILE *fp;

fp=fopen(nomefile,”a”);

if(m==-1)

fprintf(fp,”Studente assente\n”);

else

fprintf(fp,”%d\n”,m);

fclose(fp);

}

Page 13: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 13

Il seguente esercizio parte da un problema rappresentato ad alto livello di astrazione, la cui sfida

consiste nel declinare la soluzione al livello basso del dettaglio di programmazione in C. Lo si può

considerare tra gli esercizi più complessi nell’ambito degl’insegnamenti impartiti nel corso.

ESERCIZIO 5

(7 punti) Nel laboratorio del Prof. Marcialis lo staff ha realizzato un robot in grado di stimare, tramite

due videocamere poste in corrispondenza degli occhi, la forma delle persone in una scena, in modo

tale da calcolare il Body Mass Index (BMI – Indice di Massa Corporea) e suggerire la dieta

maggiormente rispondente al loro stato.

Durante la fase di osservazione, il robot scrive in un file “persone.txt” i dati riferiti a peso in kg ed

altezza in m. Tuttavia, gli manca l’intelligenza per calcolare il BMI

attraverso la formula: 𝐵𝑀𝐼 = 𝑝𝑒𝑠𝑜/𝑎𝑙𝑡𝑒𝑧𝑧𝑎2.

Il Prof. Marcialis incarica voi di aggiungere tale intelligenza,

predisponendo un programma C che legga il file “persone.txt”,

calcoli il BMI e scriva su un file “dieta.txt”, per ogni persona, la

classificazione fornita dalla figura a lato. Più tardi il robot leggerà

a ciascuna persona i dati memorizzati nel file creato in seguito

all’elaborazione scritta da voi.

Il file “persone.txt” è formattato, per esempio, come segue: 64.2 1.7

80.0 1.5

40.0 1.8

Dove ciascuna coppia di valori reali per riga rappresenta rispettivamente il peso e l’altezza di un

soggetto osservato dal robot.

Nel file “dieta.txt” andrà invece scritto il relativo BMI calcolato secondo la formula di cui sopra e la

classificazione associata, come dall’esempio: 12.3 Sottopeso

35.6 Obesità di medio grado

22.2 Normopeso

1 0

Come si può notare, l’elenco dei soggetti è scritto in ordine inverso rispetto a quello fornito nel file

“persone.txt”.

A fine file andrà scritta la coppia di valori corrispondenti al numero di soggetti sottopeso (primo

valore) e affetti da obesità di alto grado (secondo valore). Nell’esempio di cui sopra, tali valori sono

rispettivamente 1 e 0.

Page 14: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 14

(6 punti) Nell’implementare il programma, definire:

un tipo di dato strutturato Biometria, contenente tre slot reali chiamati peso, altezza, BMI e

una stringa di 50 caratteri chiamata classificazione;

un tipo di lista concatenata lBiometrie, contenente una variabile di tipo Biometria per ogni

elemento di lista. Per questo tipo si considerino già implementate le funzioni CONS, HEAD, TAIL,

ISEMPTY.

Infine, scrivete le seguenti funzioni:

(6 punti) Funzione leggiDati:

Legge da file già aperto una coppia di valori di peso ed altezza associati dal robot ad un dato

soggetto, li inserisce in una variabile di tipo Biometria e la restituisce in uscita.

(8 punti) Funzione calcolaBMI:

Riceve in ingresso un puntatore a Biometria e assegna ai relativi slot la coppia BMI-classificazione in

base alla tabella fornita nel testo del problema.

(4 punti) Funzione scriviRisultati:

Riceve in ingresso una lista di tipo lBiometrie e un nome di file nomefile e vi scrive le coppie di

valori secondo il formato indicato nell’esempio, ovvero BMI e classificazione per tutti i soggetti,

calcolando anche la coppia di valori di fine file relativa a numero di soggetti sottopeso e con obesità

di alto grado.

NOTA: E’ proibito alterare i requisiti e l’elenco dei parametri forniti dal testo. Si legga attentamente il

testo dell’esercizio per non incorrere in tale errore

Page 15: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 15

Soluzione.

Definizione dei tipi.

Liste: typedef struct Lista_Biometrie

{

Biometria b;

struct Lista_Biometrie *successivo;

} lBiometrie;

typedef struct

{

float peso, altezza, BMI;

char classificazione[50];

} Biometria;

Biometria leggiDati(FILE *f)

{

Biometria b;

fscanf(f,"%f %f", &b.peso, &b.altezza);

return b;

}

void calcolaBMI(Biometria *b)

/* passaggio per variabile ovvero per puntatore necessario per alterare gli slot

della variabile b */

{

float BMI;

BMI=b->peso/((b->altezza) * (b->altezza));

if (BMI<18.5)

sprintf(b->classificazione, "Sottopeso");

/*Uso sprintf per scrivere su stringa la classificazione del soggetto*/

else

if (BMI<25.)

sprintf(b->classificazione, "Normopeso");

else

if (BMI<30.)

sprintf(b->classificazione, "Sovrappeso");

else

if (BMI<40.)

sprintf(b->classificazione, "Obesità di medio grado");

else

sprintf(b->classificazione, "Obesità di alto grado");

b->BMI=BMI;

}

Page 16: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 16

void scriviRisultati(lBiometrie* l, char *nomefile)

{

Biometria b;

FILE *f;

int ns, no;

ns=0;

no=0;

f=fopen(nomefile,"w");

while (!ISEMPTY(l)) /*Finché non arrivo a fine lista…*/

{

b=HEAD(l);

fprintf(f,"%.1f %s\n",b.BMI, b.classificazione);

if (!strcmp(b.classificazione,"Sottopeso"))

/*strcmp funzione della librerie string.h per il confronto di stringhe*/

ns++;

else

if(!strcmp(b.classificazione,"Obesità di alto grado"))

no++;

l=TAIL(l);

}

fprintf(f, "%d %d\n", ns, no);

fclose(f);

}

int main()

{

FILE *fin;

lBiometrie *lb=NULL;

Biometria b;

fin=fopen("persone.txt","r");

while(!feof(fin))

{

b=leggiDati(fin); /*leggiDati e calcolaBMI gestiscono */

calcolaBMI(&b); /* un utente alla volta */

lb=CONS(lb,b);

}

fclose(fin);

scriviRisultati(lb,"dieta.txt");

free(lb); /*completamento della deallocazione (v. TAIL)*/

return 0;

}

Page 17: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 17

Sebbene non richiesta, si fornisce l’implementazione di HEAD, CONS, TAIL e ISEMPTY:

lBiometrie* CONS(lBiometrie *l, Biometria b)

/* in questa implementazione la testa della lista contiene l’ultimo elemento

inserito */

{

lBiometrie *nuova;

nuova=(lBiometrie*)malloc(sizeof(lBiometrie));

nuova->b=b;

nuova->successivo=l;

return nuova;

}

Biometria HEAD(lBiometrie *l)

{

return l->b;

}

lBiometrie* TAIL (lBiometrie *l)

{

lBiometrie *t;

t=l->successivo;

free(l); /* inclusa funzionalità di deallocazione della testa */

return t;

}

int ISEMPTY(lBiometrie *l)

{

return l==NULL;

}

Struttura del programma:

/*Programma per la gestione di dati biometrici per il calcolo della dieta

Fornito da un robot.

Su file persone.txt sono rilevate le coppie relative ai valori di peso ed altezza.

Il programma calcola BMI e relativa classificazione associate a tali valori e li

stampa su file dieta.txt riportando anche il numero di soggetti sottopeso e con

obesità di alto grado esaminati. */

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

/*Definizione dei tipi*/

/*Funzioni di gestione della lista: CONS, HEAD, TAIL, ISEMPTY */

/*Funzioni leggiDati, calcolaBMI e scriviRisultati */

/*Funzione main*/

Page 18: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 18

Il seguente esercizio rappresenta un po’ l’essenza del corso di Elementi di Informatica: sono utilizzate

tutte le strutture e funzionalità base spiegate a lezione. Con questo esercizio potete vagliare un livello

di preparazione per così dire “semi-avanzato”, raggiunto il quale non solo siete in grado di

padroneggiare tecniche di programmazione fondamentali (il conteggio, la variabile di appoggio,

la permuta) nonché gli algoritmi di base come il massimo (minimo), la ricerca e l’ordinamento, ma

di sfruttarle tutte assieme per costruire un’applicazione completa, con tipi di dato strutturato

tutt’altro che banali, per quanto possano esisterne di enormemente più complessi.

Il programma che segue è infatti un piccolo gestore di basi di dati in forma di agenda. Le varianti

sono tantissime, da dati anagrafici generici a informazioni sanitarie e di altra natura.

Manca la gestione a liste concatenate, ma non è difficile pensare di utilizzarle in luogo della lista

dinamica semplice suggerita ed implementata nella soluzione.

ESERCIZIO 6

Siete entrati in possesso dell’agenda del vostro migliore amico. Essa è conservata in un file

“agenda.txt” nella quale ogni riga ha due elementi: il primo è la data di un certo evento, nel

formato gg mm anno con due cifre per gg e mm, quattro per anno (es. 19 12 2018), e la seconda,

separata da uno spazio, è la descrizione dell’evento. Sfortunatamente, gli eventi sono inseriti in modo

totalmente casuale, non ordinato, quindi reperire un evento particolare o capire quale sia il primo

evento inserito è molto difficile. Per questo decidete di scrivere un programma C che vi permette di

svolgere diverse operazioni, dopo aver portato l’agenda del vostro amico dal file alla memoria del

computer.

(1 punto) Definite innanzitutto il tipo strutturato voceAgenda, composto da uno slot data di tipo

strutturato TData (costituito da tre interi rappresentanti i valori di giorno, mese e anno) e una

stringa evento di massimo 50 caratteri finalizzata a contenere la descrizione dell’evento.

(1 punto) Definite un tipo lista dinamica TAgenda di strutture di tipo voceAgenda. Tale lista verrà

gestita dalle primitive CONS, TAIL, HEAD e ISEMPTY come visto a lezione. Non è necessario

implementarle.

(4 punti) Funzione leggiAgenda:

- Input: il nome del file espresso come stringa

- Output: una lista dinamica TAgenda.

(3 punti) Funzione confrontaDate:

- Ingresso: due parametri d1 e d2 di tipo TData;

- Output: -1 se d1 precede d2, 0 se contengono la stessa data, 1 se d1 segue d2.

Letta l’agenda da file, il programma deve permettere, a ciclo continuo, di poter scegliere tra diverse

funzionalità, digitando una cifra compresa tra 0 e 5. Digitando 0, si esce dal programma. Per ogni

altro valore consentito, le funzionalità sono definite come segue:

1. (5 punti) Funzione primaData:

- Input: lista dinamica TAgenda;

- Output: variabile di tipo TData contenente la prima data inserita in ordine di tempo. Tale

data viene anche stampata a video nel formato “gg/mm/aaaa”.

2. (2 punti) Funzione ultimaData: analoga nell’I/O a primaData, restituisce l’ultima data

inserita in ordine di tempo dopo averla stampata a video.

3. (8 punti) Funzione ordinaDate:

- Input: lista dinamica TAgenda;

- Output: restituisce la lista con le voci dell’agenda ordinate in ordine “crescente” di data.

4. (6 punti) Funzione stampaEvento:

- Input: lista dinamica TAgenda;

- Output: Non necessario.

Scrive su video la descrizione dell’evento o degli eventi corrispondenti ad una data fornita

da tastiera, se presente in agenda.

5. (3 punti) Funzione scriviAgenda: scrive su file “agenda.txt” l’agenda contenuta in memoria

nello stesso formato con il quale è stata letta (se presente). Sovrascrive eventualmente quella

già presente.

Esempio: Se viene digitato 3, il programma esegue la funzione ordinaDate.

Si effettui, dove ritenuto necessario, il passaggio dei parametri per puntatore.

Page 19: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 19

Soluzione

Prima di tutto, presentiamo il listato completo, da copiare riga per riga manualmente (niente

cut+paste) su un editor e poi procedure alla compilazione. E’ molto probabilmente che agendo così

facciate errori di ricopiatura, ma è molto meglio perché sarete forzati tramite il compilatore a trovare

quegli errori ed a sforzarvi di capire perché le cose non stanno funzionando.

/*Programma per la gestione di un'agenda tramite lista dinamica*/

#include <stdio.h>

#include <stdlib.h>

/* Definizione dei tipi */

typedef struct

{

int giorno, mese, anno;

} TData;

typedef struct

{

TData data;

char evento[50];

} voceAgenda;

typedef struct

{

voceAgenda *voci;

int n;

} TAgenda;

/* Definizione delle funzioni base di lista*/

TAgenda inizializza()

{

TAgenda nuova;

nuova.n=0;

return nuova;

}

TAgenda CONS(TAgenda *agenda, voceAgenda v)

{

int i;

TAgenda nuova;

nuova.voci=(voceAgenda*)malloc(sizeof(voceAgenda)*(agenda->n+1));

for (i=0; i<agenda->n; i++)

nuova.voci[i+1]=agenda->voci[i];

nuova.voci[0]=v;

nuova.n=agenda->n+1;

if (agenda->n) free(agenda->voci);

return nuova;

}

Page 20: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 20

TAgenda TAIL(TAgenda *agenda)

{

int i;

TAgenda nuova;

nuova.n=agenda->n-1;

if(nuova.n)

{

nuova.voci=(voceAgenda*)malloc(sizeof(voceAgenda)*nuova.n);

for (i=0; i<nuova.n; i++)

nuova.voci[i]=agenda->voci[i+1];

}

free(agenda->voci);

return nuova;

}

voceAgenda HEAD(TAgenda agenda)

{

return agenda.voci[0];

}

int ISEMPTY(TAgenda agenda)

{

return agenda.n==0;

}

/*Definizione delle funzioni*/

TAgenda leggiAgenda(char *nomefile)

{

FILE *f;

TData d;

voceAgenda v;

TAgenda agenda;

int n;

f=fopen(nomefile,"r");

agenda=inizializza();

while(!feof(f))

{

n=fscanf(f,"%d %d %d", &d.giorno, &d.mese, &d.anno);

if(n>0)

{

fscanf(f,"%s", &v.evento[0]);

v.data=d;

agenda=CONS(&agenda,v);

}

}

fclose(f);

return agenda;

}

Page 21: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 21

int confrontaDate(TData d1, TData d2)

{

if (d1.anno<d2.anno)

return -1;

else

if (d1.anno>d2.anno)

return 1;

if (d1.mese<d2.mese)

return -1;

else

if (d1.mese>d2.mese)

return 1;

if (d1.giorno<d2.giorno)

return -1;

else

if (d1.giorno>d2.giorno)

return 1;

return 0;

}

TData primaData(TAgenda a)

{

TData prima;

int i;

prima=a.voci[0].data;

for (i=1; i<a.n; i++)

if (confrontaDate(a.voci[i].data,prima)<0)

prima=a.voci[i].data;

printf("\n\nData meno recente: %2d/%2d/%4d\n\n",prima.giorno, prima.mese,

prima.anno);

return prima;

}

TData ultimaData(TAgenda a)

{

TData ultima;

int i;

ultima=a.voci[0].data;

for (i=1; i<a.n; i++)

if(confrontaDate(a.voci[i].data,ultima)>0)

ultima=a.voci[i].data;

printf("\n\nData piu\' recente: %2d/%2d/%4d\n\n",ultima.giorno, ultima.mese,

ultima.anno);

return ultima;

}

void scambiaVoci(voceAgenda *v1, voceAgenda *v2)

{

voceAgenda t;

t=*v1;

*v1=*v2;

*v2=t;

}

Page 22: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 22

/* Nel seguito la versione “sintetica” dell’algoritmo di selection-sort

Implementate la versione che fa uso della funzione primaData

Scrivetene una variante primaData che oltre all’agenda

riceve l’indice di partenza del vettore su cui fare la ricerca della prima

data. Vedrete che non è difficile. */

TAgenda ordinaDate(TAgenda *a)

{

int i, j;

for(i=0; i<a->n-1; i++)

for(j=i+1; j<a->n; j++)

if (confrontaDate(a->voci[i].data,a->voci[j].data)>0)

scambiaVoci(&(a->voci[i]),&(a->voci[j]));

return *a;

}

void stampaEvento(TAgenda a, TData d)

{

int i;

int trovato;

printf("\n");

for(i=0, trovato=0; i<a.n; i++)

if(!confrontaDate(d,a.voci[i].data))

{

printf("%s\n",a.voci[i].evento);

trovato=1;

}

if(!trovato)

printf("\nData non presente - eventi non trovati \n");

}

void stampaAgenda(FILE *f, TAgenda a)

{

int i;

voceAgenda v;

TData d;

for(i=0; i<a.n; i++)

{

v=a.voci[i];

d=v.data;

fprintf(f,"%2d %2d %4d %s\n",d.giorno, d.mese, d.anno, v.evento);

}

}

void scriviAgenda(TAgenda a)

{

FILE *f;

f=fopen("agenda.txt","w");

stampaAgenda(f,a);

fclose(f);

}

Page 23: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 23

int stampaMenu()

{

int opzione;

printf("\nSeleziona una delle seguenti:");

printf("\n1 Stampa data meno recente");

printf("\n2 Stampa data piu\' recente");

printf("\n3 Ordina agenda per data");

printf("\n4 Cerca un evento per data");

printf("\n5 Scrivi agenda su file");

printf("\n6 Scrivi agenda su schermo");

printf("\n0 Esci dal programma\nOpzione: ");

scanf("%d",&opzione);

return opzione;

}

int seleziona(TAgenda a)

{

TData d;

int opzione;

opzione=stampaMenu();

switch (opzione)

{

case 0: break;

case 1: d=primaData(a); break;

case 2: d=ultimaData(a); break;

case 3: a=ordinaDate(&a); break;

case 4: printf("\nInserire data utile: ");

scanf("%d %d %d",&d.giorno, &d.mese, &d.anno);

stampaEvento(a,d);

break;

case 5: scriviAgenda(a); break;

case 6: stampaAgenda(stdout, a); /*stdout è un identificativo di file

sempre aperto e*/

/* corrisponde allo schermo */

}

printf("\n");

return opzione;

}

int main()

{

TAgenda a;

int opzione;

a=leggiAgenda("agenda.txt");

do

opzione=seleziona(a);

while(opzione);

printf("\nUscita dal programma.\n");

free(a.voci);

return 0;

}

Page 24: MOTIVATE IN ANIERA HIARA LE SOLUZIONI PROPOSTE ......MOTIVATE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti) Scrivere un programma in

Elementi di Informatica 24

Dall’analisi del codice si evince la seguente strutturazione modulare, rappresentabile mediante

approccio TOP-DOWN come segue:

Pur non richieste e non necessarie, le funzioni selezione, scambia, stampaMenu e stampaAgenda

permettono una maggiore modularità e brevità dei singoli componenti funzionali consentendo una

visualizzazione immediate dell’algoritmo alla base di ciascuna funzione. A sinistra le funzioni di

gestione delle liste utili nel caso specifico sono soltanto CONS e inizializza, essendo le sei

funzionalità richieste caratterizzate da necessità di accesso diretto a più elementi della lista

contemporaneamente, e quindi non immediatamente realizzabili per mezzo di ISEMPTY, HEAD e

TAIL.

La funzione stampaAgenda consente sia la stampa su file aperto mediante approccio standard, sia

la stampa a video in quanto l’identificativo stdout è puntatore allo stream video, analogo allo

stream su file, con la differenza che non necessita l’apertura e la chiusura.

Le funzioni selezione e stampaMenu permettono infine di visualizzare la main in una forma tale che,

a parte la lettura iniziale dell’agenda da file, risalta la lettura ciclica di una variabile di opzione in

base alla quale viene associata la funzionalità da eseguire.