Esercitazione Fondamenti di Informatica B Corso di Laurea in Ingegneria Meccanica 6 Esercitazione: 11 novembre 2005 Esercizi di riepilogo in preparazione alla prima prova intermedia Problema (tratto da un tema d esame): Esercizio 1: parole nel testo Si consideri un programma che identifica in sequenza tutte le singole parole all interno di un testo. Date le seguenti definizioni di tipo: #define MAX_NUM_CHAR 200 typedef char stringa[max_num_char]; il programma definisce una variabile chiamata testo, di tipo stringa, per ospitare il testo. Per trovare l indice della cella dell array corrispondente all inizio di ciascuna parola nel testo, il programma sfrutta la funzione che ha la seguente intestazione: int trovanuovaparola(stringa s, int prec) La funzione prende come parametri la stringa che rappresenta il testo e la posizione in cui inizia l ultima parola già considerata. Nel caso in cui non sia stata ancora considerata nessuna parola nel testo, il valore intero passato come parametro sarà pari a -1. La funzione restituisce l indice dell inizio della prossima parola nella stringa, oppure il valore -1 nel caso non ci siano ulteriori parole nella stringa. Si supponga per semplicità che il testo sia composto solo da parole (sequenze ininterrotte di caratteri alfabetici) separate da un singolo spazio, e che l ultima parola sia seguita immediatamente dall usuale carattere nullo che delimita la porzione di array occupata dal testo. Per esempio, se la variabile testo contiene Nel mezzo del cammin di nostra vita e la funzione viene chiamata nel seguente modo: x = trovanuovaparola(testo, -1) il valore restituito dalla funzione (che nell esempio viene assegnato ad x) sarà pari a 0. Se invece la chiamata è la seguente: x = trovanuovaparola(testo, 10) Il valore restituito dalla funzione sarà pari a 14 che corrisponde all indice della cella in cui inizia la parola cammin. a) Si completi lo sviluppo del seguente main in modo che calcoli, sfruttando la funzione trovanuovaparola, i valori degli indici di inizio delle parole nel testo e li stampi a video. void main() stringa testo; int indice; /* dichiarazione di eventuali altre variabili */ /* aquisizione di testo (da NON sviluppare) */... /* calcolo degli indici di inizio delle parole nel testo e stampa a video del risultato */ b) Si completi la definizione della funzione trovanuovaparola. Soluzione parte a): - 1 -
void main() stringa testo; int indice; /* dichiarazione di eventuali altre variabili */ /* aquisizione di testo (da NON sviluppare) */... /* calcolo degli indici di inizio delle parole nel testo e stampa a video del risultato */ indice = trovanuovaparola(testo, -1); while(indice>-1) printf( la prossima parola inizia all indice %d\n, indice); indice = trovanuovaparola(testo, indice); Soluzione parte b): int trovanuovaparola(stringa s, int prec) int i; i = prec+1; while(i<max_num_char && s[i]!= \0 &&s[i]!= ) i++; if(i<max_num_char && s[i]!= \0 ) return i+1; else return -1; Problema (tratto da un tema d esame): Esercizio 2: trasformazione di una matrice Si sviluppi un sottoprogramma che prende come parametro una matrice di interi ed il suo numero di righe e colonne. Il sottoprogramma trasforma la matrice in questione sostituendo a ciascun elemento che si trova a sinistra dell asse verticale della matrice, l elemento che si trova in posizione simmetrica rispetto allo stesso asse. Per esempio, la seguente matrice: Si dichiarino tutte le variabili necessarie. - 2 -
Soluzione: #define NRIGHE 6 #define NCOLONNE 7 typedef int matrice[nrighe][ncolonne]; void trasforma(matrice m, int righe, int colonne) int i, j; for(i=0; i<righe;i++) for(j=0; j<(colonne/2); j++) m[i][j]=m[i][colonne-j-1]; Esercizio 3: sottoprogrammi con passaggio di parametri di tipo struct Problema (rielaborazione di un tema d esame): Le seguenti dichiarazioni di tipo descrivono i tipi di pezzi di ricambio (pistoni, valvole,...) disponibili nel magazzino di un officina meccanica ed il magazzino stesso. #define MAX_PEZZI 100 typedef struct char codiceanagrafico [11]; /* identifica un tipo di pezzo in modo univoco */ int giacenzaminima; /* la quantità minima di pezzi che dovrebbero essere sempre disponibili in magazzino */ int quantitapresente; /* la quantità di pezzi effettivamente disponibili */ float prezzounitario; /* il prezzo unitario di ogni pezzo */ pezzoricambio; typedef struct pezzoricambio elenco[max_pezzi]; int npezzi; /* numero dei tipi di pezzi presenti in magazzino */ magazzino; Si supponga che nel main ci sia la seguente dichiarazione di variabile magazzino mag; Si scriva un primo sottoprogramma (funzione o procedura?) che inizializzi le scorte del magazzino (ossia, valorizzi la variabile mag). In particolare, il sottoprogramma deve: - 3 -
- Chiedere all utente quanti pezzi inserire nel magazzino. Il numero di pezzi deve essere inferiore a MAX_PEZZI. - Chiedere all utente di inserire, per ciascun pezzo, codice anagrafico, giacenza minima, quantità presente, prezzo unitario. Si scriva un secondo sottoprogramma infomagazzino (funzione o procedura?) che, sulla base dei valori effettivamente presenti nella variabile mag (assunti già in essa preesistenti): - Stampi a video il codice anagrafico dei tipi di pezzi da ordinare e, per ogni tipo, la quantità necessaria. Un tipo di pezzo deve essere ordinato se la quantità presente in magazzino è inferiore alla giacenza minima. In questo caso, la quantità da ordinare è pari alla differenza tra giacenza minima e quantità presente in magazzino. La stampa deve essere effettuata su una riga diversa per ogni tipo di pezzo. - Stampi infine su un ulteriore riga il costo complessivo da sostenere per l acquisto di tutti gli esemplari ordinati. Soluzione (programma completo): #include<stdio.h> #define MAX_PEZZI 5 typedef struct char codiceanagrafico [11]; int giacenzaminima; int quantitapresente; float prezzounitario; pezzoricambio; typedef struct pezzoricambio elenco[max_pezzi]; int npezzi; /* numero dei tipi di pezzi presenti in magazzino */ magazzino; // prototipo procedura per valorizzare il magazzino void riempimagazzino(magazzino *m); // notare il passaggio di parametri per indirizzo // prototipo procedura (o dichiarazione) void infomagazzino(magazzino m); int main() magazzino mag; // chiamata 1 sottoprogramma: inizializzazione merce del magazzino riempimagazzino(&mag); // passaggio di parametro per indirizzo - 4 -
// chiamata 2 sottoprogramma: valutazione magazzino (chiamata della procedura di interesse per l'esercizio) infomagazzino(mag); // passaggio di parametro per valore o copia system("pause"); return 0; // fine main // definizione della procedura per valorizzare il magazzino void riempimagazzino(magazzino *m) // notare il passaggio di parametri per indirizzo int numeropezzi; int i; // per rispettare le dimensioni massime dell'archivio do printf("quanti pezzi vuoi inserire?"); scanf("%d", &(m->npezzi)); while (m->npezzi > MAX_PEZZI); // lettura valori iniziali del magazzino for (i=0; i< m->npezzi; i++) printf("\ncodice anagrafico: "); scanf("%s", m->elenco[i].codiceanagrafico); printf("\nprezzo unitario: "); scanf("%f", &(m->elenco[i].prezzounitario)); printf("\ngiacenza minima: "); scanf("%d", &(m->elenco[i].giacenzaminima)); printf("\nquantità presente: "); scanf("%d", &(m->elenco[i].quantitapresente)); // definizione della procedura (contiene l'implementazione della procedura) - 5 -
void infomagazzino(magazzino m) int i, q; float sp = 0.0; sp; for (i = 0; i < m.npezzi; i++) q = m.elenco[i].giacenzaminima - m.elenco[i].quantitapresente; if ( q > 0 ) printf("%s %d \n ", m.elenco[i].codiceanagrafico, q); sp = sp + m.elenco[i].prezzounitario * q; printf("spesa complessiva: %f ", sp); Esercizio 4: capire cosa fa un programma completo Problema (tratto da un tema d esame): Dato il seguente programma: #include <stdio.h> #define MAX_NUM 13 int f(char a[], char b[]); void main() char vett1[max_num]; char vett2[max_num]; int i, ris; for(i = 0; i<max_num; i++) scanf( %c, &vett1[i]); for(i = 0; i<max_num; i++) scanf( %c, &vett2[i]); ris = f(vett1, vett2); for(i = 0; i<max_num; i++) printf( %c, vett1[i]); printf( \n ); for(i = 0; i<max_num; i++) printf( %c, vett2[i]); printf( \n ); - 6 -
printf( %d, ris); int f(char a[], char b[]) int cont = 0; for (i=0; i<max_num; i++) if((a[i]== 1 a[i]== x a[i]== 2 ) && a[i]==b[i]) cont++; a[i] = x ; b[i] = x ; return cont; 1) Si descriva il comportamento del programma nel caso in cui l utente fornisca in input i seguenti valori: 0 0 1 3 3 x y 2 2 0 w x a che vengono assegnati a vett1, e 0 2 0 1 3 x y 2 2 0 h x k che vengono assegnati a vett2. 2) Si specifichi quali valori vengono stampati dalle printf motivando la risposta. 3) Si modifichi il sottoprogramma f in modo che si comporti come una procedura pura eliminando quindi il valore di ritorno e sostituendolo con un parametro passato per indirizzo. 4) Si riscriva la linea di codice del main che contiene la chiamata ad f in modo coerente con le modifiche richieste nel punto precedente. Soluzione: 1) e 2) Il programma, a partire dai valori inseriti dall utente nei vettori vett1 e vett2, conta il numero di celle dei due vettori che: - si trovano nella medesima posizione AND - assumono valore pari a 1, x oppure 2. Modifica i valori di vett1 e vett2, ponendoli tutti pari a x e stampa: - vett1 con tutti i valori (fino a MAX_NUM) posti a x ; - vett2 con tutti i valori (fino a MAX_NUM) posti a x ; - il numero delle celle nei due vettori che rispettano le due condizioni in AND viste prima. Nel caso specifico proposto, i valori stampati sono: vett1: x x x x x x x x x x x x x vett2: x x x x x x x x x x x x x cont: 4-7 -
3) void f(char a[], char b[], int *cont) for (i=0; i<max_num; i++) if((a[i]== 1 a[i]== x a[i]== 2 ) && a[i]==b[i]) (*cont)++; a[i] = x ; b[i] = x ; 4) La nuova chiamata della procedura diventa: f(vett1, vett2, &ris); Esercizio 5: calcolo del quadrato di un numero intero positivo Problema (tratto da un tema d esame): È noto che il quadrato di ogni numero intero positivo n è esprimibile come somma dei primi n numeri dispari; a esempio, 42 = 16 = 1 + 3 + 5 + 7. Immaginando che il linguaggio di programmazione C non possieda alcun operatore aritmetico per il calcolo del prodotto di due numeri interi, si codifichi la funzione che ha la seguente intestazione: int quad (int n); che, ricevendo come parametro un numero intero positivo, calcoli il suo quadrato come somma dei primi n numeri dispari e lo restituisca come valore della chiamata. Si codifichi inoltre la funzione con la seguente intestazione int sommaquad (int a, int b); che calcoli e restituisca al chiamante la somma dei quadrati di tutti i numeri compresi tra a e b (assunti interi positivi, con a<b), estremi inclusi. Si noti che i programmi codificati devono operare esclusivamente per somme ripetute (eventualmente, sommaquad può operare chiamando quad). Soluzione: int quad (int n) int i, s; s = 0; for (i = 0; i<n; i++) s = s + i + i + 1; return s; /* sommaquad: versione che non usa quad */ int sommaquad (int a, int b) int i, j, s; s = 0; for (i = a; i<=b; i++) for (j=0; j<i; j++) - 8 -
s = s + j + j + 1; return s; /* sommaquad: versione che usa quad */ int sommaquad2 (int a, int b) int i, s; s = 0; for (i = a; i<=b; i++) s = s + quad(i); return s; - 9 -