Fondamenti di Informatica
Transcript
Fondamenti di Informatica
Capitolo 1 Fondamenti di Informatica Esercizi Vengono proposti alcuni esercizi relativi alla parte introduttiva della programmazione in C (Struttura ed elementi base di un programma, Ingresso e uscita dei dati (Input/output) e Strutture di controllo) e vengono presentate le relative soluzioni. 1 CAPITOLO 1. FONDAMENTI DI INFORMATICA - ESERCIZI 2 1.1 INTRODUZIONE AL C } Esercizio 1 Descrivere l’output del seguente programma #include <stdio.h> #define Saluto "salve!" main(){ printf("Saluto"); printf("\n"); printf(Saluto); printf("\n"); printf("%s",Saluto); printf("\n"); printf("%s","Saluto"); printf("\n"); printf("%c",Saluto); } } Esercizio 2 Sia data la seguente espressione logica: (A==B)&&(B!=0)&&(10/A>2) Discuterne la sua valutazione (stabilire, in particolare, se ci sono errori in esecuzione) sia con la tecnica della valutazione in corto circuito che senza. } Esercizio 3 Sia data la seguente espressione logica: !(((A<10)&&(B>=20))||(C==12)) Applicando le leggi di De Morgan, indicare quali delle seguenti espressioni è equivalente alla espressione logica data: 1. ((A>=10)&&(B<20))&&(C!=12) 2. ((A>=10)||(B<20))||(C!=12) 3. ((A>=10)||(B<20))&&(C!=12) } Esercizio 4 Scrivere un programma che acquisisca da input tre numeri interi, usando tre separate istruzioni di scanf, e, utilizzando un’unica funzione printf, li stampi in output secondo i seguenti formati a) su un’unica riga, separati dal carattere ’-’; b) su tre righe differenti; c) su tre righe differenti, ma con spaziatura doppia, cioè lasciando una riga vuota tra un numero e l’altro. 1.1. INTRODUZIONE AL C 3 } Esercizio 5 Scrivere un programma che acquisisca da input tre numeri interi e stampi in output la loro somma. } Esercizio 6 Scrivere un programma che calcola l’espressione X=(C-B)/A, dove A, B e C sono costanti di valore 4, 6 e 16 rispettivamente. } Esercizio 7 Scrivere un programma che calcoli l’orario di arrivo di un treno. Il programma deve leggere da input ora e minuto di partenza di un treno e ore e minuti di percorrenza prevista. Si visualizzerà in output ora e minuto di arrivo. } Esercizio 8 Scrivere un programma che deve da input caratteri fino a quando si digita ’#’; per ogni carattere letto il programma dice se si tratta di una lettera, oppure di una cifra, oppure di un segno di punteggiatura (specificando quale). } Esercizio 9 Descrivere un algoritmo che acquisisce tre numeri interi e determina il numero più grande; tradurre quindi l’algoritmo in un programma. } Esercizio 10 Descrivere un algoritmo e quindi tradurlo in un programma che risolve equazioni di primo grado della forma: a*x+b=0. Il programma deve essere in grado di accettare qualsiasi valore per i coefficienti a e b e di fornire un risultato corretto per ogni valore ricevuto. } Esercizio 11 Scrivere un programma che accetti l’immissione da tastiera di caratteri, fino all’immissione di un asterisco, e ne stampi il numero totale. } Esercizio 12 Scrivere un programma che accetti l’immissione di caratteri da tastiera, fino all’immissione di due asterischi consecutivi, e ne stampi il numero totale. } Esercizio 13 Che differenza c’è tra i seguenti frammenti di programma? Quali sono quelli sintatticamente corretti? Quali potrebbero essere quelli semanticamente corretti? Frammento A: if(a!=0) if(a<0) printf("a e’ negativo"); else printf("a e’ zero"); CAPITOLO 1. FONDAMENTI DI INFORMATICA - ESERCIZI 4 Frammento B: if(a!=0){ if (a<0) printf("a e’ negativo"); } else printf("a e’ zero"); Frammento C: if(a!=0) if (a<0) { printf("a e’ negativo"); else printf("a e’ zero"); } } Esercizio 14 Scrivere un programma che accetti da tastiera numeri relativi, fermandosi all’immissione di uno 0, e stampi separatamente le somme dei numeri positivi e di quelli negativi. } Esercizio 15 Scrivere un programma che acquisisca da input un numero intero N, controlli che sia non negativo e ne stampi in output il suo fattoriale. } Esercizio 16 Scrivere un programma per stampare la tabellina Pitagorica 10*10. } Esercizio 17 Il programma deve stampare una piramide (formata da caratteri ’*’) di altezza NR acquisita da input. Esempio con NR=4 * * * * * * * * * * * * * * * * } Esercizio 18 Scrivere un programma C che legge da input numeri interi positivi (fino a quando non legge zero) e determina la lunghezza della massima sequenza di numeri crescenti. } Esercizio 19 Scrivere un programma C che legge N interi da input (con N costante maggiore di 3) e verifica se esistono 3 interi n1, n2, e n3, letti di seguito, tali che n3=n2+1, n2= n1+1 e n2>0. 1.1. INTRODUZIONE AL C 5 } Esercizio 20 Realizzare un programma che, acquisita da tastiera una frase su una riga, sia in grado di: 1. contare il numero di parole (NPAR) contenute nella frase; 2. determinare la lunghezza (MAXLUNG) della parola più lunga contenuta nella frase. Si suppone che la frase inserita da tastiera sia priva di punteggiatura: pertanto le parole nella frase sono separate solo tramite uno o più caratteri spazio bianco ’ ’. Esempio: Frase acquisita da tastiera : "Questa è una prova" NPAR=4 MAXLUNG=6 CAPITOLO 1. FONDAMENTI DI INFORMATICA - ESERCIZI 6 1.2 } SOLUZIONI Soluzione Esercizio 1 L’output che si ottiene è il seguente Saluto salve! salve! Saluto e l’ultima printf("%c",Saluto); riporta un carattere non significativo, in quanto viene specificata la stampa di un carattere (%c) ma l’argomento corrispondente non è un carattere ma una stringa } Soluzione Esercizio 2 Il problema è stabilire se tale espressione è valutabile o meno con il valore di A pari a zero: infatti tale valore di A causerebbe un errore di esecuzione nel valutare (10/A>2). È facile verificare che con A uguale a zero l’espressione (A==B)&&(B!=0) è falsa per ogni valore di B. Senza la valutazione in corto circuito tutta l’espressione viene valutata quindi (10/A>2) genera un errore in esecuzione quando A ha valore zero. Con la valutazione in corto circuito quando A ha valore zero: } se B è zero allora (A==B) è vero ma (B!=0) non è vero quindi la valutazione termina senza considerare (10/A>2) e pertanto si ottiene correttamente il valore falso. se B non è zero allora (A==B) è falso quindi la valutazione termina senza considerare (10/A>2) e pertanto si ottiene correttamente il valore falso. Soluzione Esercizio 3 L’espressione equivalente è la numero 3. Infatti: partendo da: !(((A<10)&&(B>=20))||(C==12)) e applicando alle due espressioni in or la legge di De Morgan !(P || Q) equivalente a !P && !Q si ottiene: !((A<10)&&(B>=20))&&!(C==12) ora si applica alle due espressioni in and (cioè a !((A<10)&&(B>=20))) la legge di De Morgan !(P && Q) equivalente a !P || !Q si ottiene: (!(A<10)||!(B>=20))&&!(C==12) 1.2. SOLUZIONI 7 che è equivalente a: ((A>=10)||(B<20))&&(C!=12) } Soluzione Esercizio 4 Per risolvere questo esercizio è importante osservare che, per acquisire e, successivamente, riportare in output, tre valori distinti occorrono tre diverse variabili di tipo intero. #include <stdio.h> main(){ int X, Y, Z; printf("Inserire tre numeri interi"); scanf("%d", &X); scanf("%d", &Y); scanf("%d", &Z); printf("Formato a) \n"); printf("%d-%d-%d ",X,Y,Z); printf("Formato b) \n"); printf("%d\n%d\n%d ",X,Y,Z); printf("Formato c) \n"); printf("%d\n\n%d\n\n%d \n",X,Y,Z); } 2 Modificare il precedente programma in modo da utilizzare un’unica funzione scanf per acquisire i tre valori interi e un’unica funzione printf per stampare tutti e tre i formati richiesti, ottenendo lo stesso output ottenuto con il precedente programma. } Soluzione Esercizio 5 A differenza del precedente esercizio, ora sono sufficienti due sole variabili: una, diciamo X, per acquisire il valore da input e l’altra, diciamo Somma, per calcolare la somma. #include <stdio.h> main(){ int X; int Somma=0; printf("Inserire il primo numero intero"); scanf("%d", &X); CAPITOLO 1. FONDAMENTI DI INFORMATICA - ESERCIZI 8 Somma=Somma+X; printf("Inserire il secondo numero intero"); scanf("%d", &X); Somma=Somma+X; printf("Inserire il terzo numero intero"); scanf("%d", &X); Somma=Somma+X; printf("La somma vale %d", Somma); } } Soluzione Esercizio 6 Il valore di X è dato da X=(C-B)/A e quindi vogliamo ottenere 2.5: occorre quindi definire X come float; ma questo non è ancora sufficiente per otterere 2,5, in quanto nell’espressione (C-B)/A viene applicata la divisione tra interi (essendo sia il dividendo che il divisore numeri interi) che fornisce come risultato 2, che viene quindi assegnato alla variabile X. Per forzare nell’espressione (C-B)/A la divisione tra reali, occorre effettuare su uno dei due operandi il casting a float. #include main(){ const const const float <stdio.h> int A=4; int B=6; int C=16; X; X=(C-B)/(float)A; printf("Risultato : %f ",X); } } Soluzione Esercizio 7 Descrizione informale dell’algoritmo: – legge e stampa i dati di ingresso – calcola l’ora di arrivo – i minuti obbediscono ad una aritmetica ”modulo 60”, quindi quando si sommano minuti occorre calcolare quante ore sono contenute nel totale, tramite una divisione tra interi, e quanti sono i minuti residui, tramite l’operatore mod – discorso analogo per le ore ”modulo 24” – stampa i dati di uscita 1.2. SOLUZIONI 9 Il programma risultante è quindi il seguente: #include <stdio.h> /* legge due numeri che rappresentano l’orario di partenza in ore e minuti; legge il tempo di percorrenza in ore e minuti e stampa l’orario di arrivo */ main(){ int Ore, Minuti; /* orario di partenza */ int OreViaggio, MinutiViaggio; /* tempo di percorrenza */ printf("Fornire l’orario di partenza (oo mm) "); scanf("%d %d", &Ore, &Minuti); printf("\n L’orario di partenza \‘e Ore:%d" "Minuti:%d\n",Ore,Minuti); printf("Fornire il tempo di viaggio (oo mm) "); scanf("%d %d", &OreViaggio, &MinutiViaggio); printf("\nIl tempo di viaggio \‘e Ore:%d" "Minuti:%d\n",OreViaggio,MinutiViaggio); Minuti = Minuti + MinutiViaggio; Ore = Ore + OreViaggio + (Minuti / 60); Ore = Ore % 24; Minuti = Minuti % 60; printf("\nOrario di arrivo previsto \‘e Ore:%d" "Minuti:%d\n",Ore,Minuti); } } Soluzione Esercizio 8 #include <stdio.h> main() { char Ch; do { printf("digita un carattere : "); /* legge il successivo carattere stampabile */ do scanf("%c", &Ch); while (!(Ch>=32 && Ch<=127)); if ((Ch>=’A’ && Ch<=’Z’) || (Ch>=’a’ && Ch<=’z’)) 10 CAPITOLO 1. FONDAMENTI DI INFORMATICA - ESERCIZI printf("%c e’ una lettera\n",Ch); else if (Ch>=’0’ && Ch<=’9’) printf("%c e’ un numero\n",Ch); else switch (Ch) { case ’,’ : printf("%c e’ una virgola\n",Ch); break; case ’.’ : printf("%c e’ un punto\n",Ch); break; case ’;’ : printf("%c e’ un punto-virg.\n",Ch); break; case ’:’ : printf("%c e’ un due-punti\n",Ch); break; default:printf("non riconosciuto\n"); } } while (Ch!=’#’); } } Soluzione Esercizio 9 Descrizione a parole dell’algoritmo - leggi i numeri NUM1, NUM2 e NUM3 - se NUM1 > NUM2 allora se NUM1 > NUM3 allora stampa NUM1 altrimenti stampa NUM3 altrimenti - se NUM2 > NUM3 allora stampa NUM2 altrimenti stampa NUM3 L’algoritmo si traduce nel seguente programma: #include <stdio.h> /* Calcolo del massimo tra tre numeri */ main(){ int NUM1, NUM2, NUM3; /* lettura dei tre numeri */ scanf("%d", &NUM1); scanf("%d", &NUM2); scanf("%d", &NUM3); /* confronto tra i numeri */ 1.2. SOLUZIONI 11 if (NUM1>NUM2) if (NUM1>NUM3) printf("Il piu‘ grande e‘: %d", NUM1); else /* sicuramente NUM3 >= NUM2 */ printf("Il piu‘ grande e‘: %d", NUM3); else /* NUM1 <= NUM2 */ if (NUM2>NUM3) printf("Il piu‘ grande e‘: %d", NUM2); else /* sicuramente NUM3 >= NUM1 */ printf("Il piu‘ grande e‘: %d", NUM3); } } Soluzione Esercizio 10 Descrizione a parole dell’algoritmo: - leggi i coefficienti A e B - se A e B sono entrambi zero - stampa "tutti i valori di X sono corretti" altrimenti - se A e’ zero e B non e’ zero stampa "equazione impossibile" altrimenti calcola e stampa X=-B/A L’algoritmo si traduce nel seguente programma: /* Risoluzioni di equazioni di primo grado della forma: a*x+b=0. */ #include <stdio.h> main(){ int A, B; /* coefficienti dell’equazione float X; /* incognita dell’equazione */ */ printf("Risoluzioni di equazioni di primo grado"); printf("della forma:a*x+b=0\n"); printf("Inserire il valore del coefficiente a: "); scanf("%d", &A); printf("Inserire il valore del coefficiente b: "); scanf("%d", &B); if ((A==0) && (B==0)) printf("tutti i valori di X sono corretti \n"); CAPITOLO 1. FONDAMENTI DI INFORMATICA - ESERCIZI 12 else if ((A==0) && (B!=0)) printf("equazione impossibile \n"); else /* A!=0 e B qualsiasi */ { X= - (float)B/ (float)A; printf("Il valore di X e‘: %f\n", X); } } } Soluzione Esercizio 11 #include <stdio.h> main( ){ /* termina con un asterisco */ char CH; int COUNT; COUNT= 0; printf("Inserisci una stringa di caratteri\n"); do { scanf("%c", &CH); COUNT++; } while (CH != ’*’); printf("Caratteri contati : %5d\n", count-1); } 2 Modificare il precedente programma utilizzando un’istruzione while al posto dell’istruzione do ... while. } Soluzione Esercizio 12 #include <stdio.h> /* termina con due asterischi */ main( ){ char a1, a2; int trovato,count; count = 0; printf("Inserisci stringa di caratteri \n"); scanf("%c", &a2); 1.2. SOLUZIONI 13 trovato = 0; while (trovato == 0) { a1 = a2; scanf("%c", &a2); count++; if (a1 == ’*’ && a2 == ’*’) trovato = 1; } printf("Caratteri contati : %5d\n",count-1); } 2 Modificare il precedente programma in modo da risolvere il problema senza far uso della variabile trovato. } Soluzione Esercizio 13 La differenza consiste nell’uso delle parentesi graffe che modifica le associazioni tra la clausola else e le clausole if. I frammenti A e B sono sintatticamente corretti, mentre il frammento C non lo è in quanto, a causa delle parentesi graffe, la clausola else non è associata a nessuna clausola if. Il frammento A non è semanticamente corretto: infatti per un valore di a positivo produce come risultato ”a e’ zero” mentre se a assume il valore zero non produce niente in output. Il frammento B è semanticamente corretto: infatti per un valore di a positivo non produce niente in output mentre se a assume il valore zero produce come risultato ”a e’ zero” } Soluzione Esercizio 14 #include <stdio.h> /* Numeri Relativi */ main( ){ int totpos=0, totneg=0, a; printf("Inserisci numero: "); scanf("%d", &a); while (a != 0) { if (a > 0) totpos = totpos + a; else CAPITOLO 1. FONDAMENTI DI INFORMATICA - ESERCIZI 14 totneg = totneg + a; printf("Inserisci numero: "); scanf("%d", &a); } printf("Totale Numeri Positivi = %5d\n", totpos); printf("Totale Numeri Negativi = %5d\n", totneg); } 2 Modificare il precedente programma utilizzando un’istruzione do ... posto dell’istruzione while. while al } Soluzione Esercizio 15 In base alla definizione di fattoriale di un numero N N! = 1 2 : : : (N 1) N se N se N = 0 oppure N = 1 > 1 il calcolo del fattoriale avviene utilizzando una variabile chiamata fattoriale inizializzata a uno e calcolando il prodotto fattoriale = fattoriale * I per I che va da 2 a N. /* Calcolo del fattoriale */ #include <stdio.h> main(){ int N; /* numero da acquisire */ int fattoriale; int I; /* variabile di conteggio */ printf("Inserire il valore N (non negativo) -->"); do scanf("%d",&N); while (N<0); /* controllo che N non sia negativo */ fattoriale = 1; for (I=2; I<=N; I++) fattoriale = fattoriale * I; printf("Il fattoriale di %d vale %d", N,fattoriale); } 1.2. SOLUZIONI 15 2 Considerando la definizione alternativa di fattoriale di un numero N : N! = 1 (N 1)! N se N se N = 0 > 0 risolvere il problema del calcolo del fattoriale senza far uso della variabile di conteggio I. } Soluzione Esercizio 16 Per stampare la tabellina Pitagorica 10*10 si utilizzano due cicli innestati: quello interno serve per calcolare e stampare una riga, cioè per calcolare e stampare la tabellina di un cero numero R, e quello esterno per ripetere tale calcolo per R da 1 a 10. La struttura dell’algoritmo sarà la seguente: - per tutti i valori di R da 1 a 10 per tutti i valori di C da 1 a 10 stampa R*C vai a capo L’algoritmo si traduce nel seguente programma: /* Calcolo e stampa della tabellina pitagorica */ #include <stdio.h> main(){ int R,C; printf("Tabellina Pitagorica 10*10:\n"); for (R=1; R<=10; R++){ for (C=1; C<=10; C++) printf("%5d", R*C); printf("\n"); } } } Soluzione Esercizio 17 Descrizione informale: - acquisisci e controlla che il valore NR sia positivo per tutti i valori di I da 1 a NR stampa (NR - I) spazi bianchi stampa (2*I - 1) caratteri ’*’ vai a capo CAPITOLO 1. FONDAMENTI DI INFORMATICA - ESERCIZI 16 /* Stampa Piramide */ #include <stdio.h> main(){ int I, J; int NR; printf("numero righe piramide (intero positivo) :"); scanf("%d", &NR); while (NR<=0) { printf("\n Il numero righe deve essere positivo :"); scanf("%d", &NR); } for (I=1; I <= NR; I++) { /* ognuno di questi cicli equivale ad una riga */ for (J = 1; J <= NR-I; J++) /* stampa NR - I spazi bianchi /* printf(" "); for (J = 1; J<=2*I-1; J++) /* stampa 2I-1 asterischi /* printf("*"); printf("\n"); /* va a capo */ } /* fine del ciclo for esterno con I */ } 2 Modificare il precedente programma in modo da stampare una piramide vuota. Esempio con NR=4 * * * * * * * * * } * * * Soluzione Esercizio 18 Una sequenza X1 ; X2; X3; : : : Xn è crescente se Xi < Xi+1 , per 1 i n 1. Allora per controllare che una sequenza immessa da input sia crescente sono sufficienti solo due variabili, diciamo C e P (Corrente e Precedente) che rappresentano X i e Xi+1, rispettivamente. Descrizione informale: - Inizializza P a zero Inizializza Count a zero 1.2. SOLUZIONI - Inizializza MaxLung a zero Leggi C Finche’ C e’ diverso da 0 Se (C>P) incrementa Count Altrimenti - Se (Count > MaxLung) MaxLung=Count - Inizializza Count a uno P=C Leggi C - Se (Count > MaxLung) MaxLung=Count Stampa MaxLung #include <stdio.h> main(){ int C,P=0; int Count=0; int MaxLung=0; scanf("%d",&C); while (C!=0) { if (C>P) Count++; else { if (Count>MaxLung) MaxLung=Count; Count=1; } P=C; scanf("%d",&C); } if (Count>MaxLung) MaxLung=Count; printf("Massima Lunghezza %d", MaxLung); } } Soluzione Esercizio 19 #include <stdio.h> #define N 10 17 CAPITOLO 1. FONDAMENTI DI INFORMATICA - ESERCIZI 18 main(){ int n1,n2,n3; int I; int trovato=0; for(I=1;I<=N;I++){ scanf("%d",&n3); if ((I>=3) && (n3==n2+1) && (n2==n1+1) && (n2>0)) trovato=1; n1=n2; n2=n3; } if (trovato) printf("OK"); } 2 Modificare il precedente programma in modo tale che l’acquisizione dei numeri termini non appena sia stata letta una sequenza con le caratteristiche richieste, senza arrivare necessariamente ad N acquisizioni. } Soluzione Esercizio 20 Si legge la frase carattere per carattere e due caratteri consecutivi vengono memorizzati due variabili, Ch1 e Ch2: Q u e s t a è u n a p r o v a Ch1 Ch2 In questo modo è possibile individuare quando inizia e quando finisce una parola: Ch1 Ch2 Significato !=’ ’ ==’ ’ è terminata la parola corrente: incrementare di uno il numero delle parole e controllare se la lunghezza della parola appena terminata è quella massima azzerare la lunghezza della parola corrente successiva !=’ ’ !=’ ’ continua la parola corrente: incrementare di uno la sua lunghezza ==’ ’ !=’ ’ è iniziata la parola corrente: incrementare di uno la sua lunghezza ==’ ’ ==’ ’ non ci sono parole: non fare nessuna azione Si noti che All’inizio della frase: il numero di parole e la lunghezza della parola corrente sono zero Ch2 è il primo carattere della frase, mentre Ch1 viene inizializzato a ’’ 1.2. SOLUZIONI 19 Alla fine della frase: la parola corrente può terminare anche con Ch1!=’ ’ e Ch2==’\n’ Pertanto i casi da considerare sono sostanzialmente due: se (Ch2!=’ ’ && Ch2!=’\n’) la parola comincia (nel caso in cui Ch1==’ ’) oppure continua (se Ch1!=’ ’): in entrambi i casi occorre aumentare di uno la sua lunghezza altrimenti (cioè Ch2==’ ’ || Ch2==’\n’) se (Ch1!=’ ’) la parola è terminata - Inizializzare a zero NPAR e MAXLUNG Inizializzare con il carattere spazio bianco Ch1 Ripeti leggi un carattere in Ch2 effettua i controlli e le azioni riportate in precedenza poni Ch1 uguale a Ch2 Finche’ il carattere Ch2 e’ diverso dal fine riga \n Stampa i risultati Il programma risultante sarà quindi il seguente: #include <stdio.h> main() { char Ch1=’ ’,Ch2; int NPAR=0; /* numero parole */ int MAXLUNG=0; /* massima lunghezza di una parola int LUNG=0; /* lunghezza della parola corrente */ int i; */ printf("Inserire la frase \n "); do { scanf("%c",&Ch2); if (Ch2!=’ ’ && Ch2!=’\n’) /* la parola comincia o continua */ LUNG = LUNG +1; else if (Ch1!=’ ’) /* e’ terminata una parola */ { NPAR = NPAR +1; CAPITOLO 1. FONDAMENTI DI INFORMATICA - ESERCIZI 20 if (LUNG>MAXLUNG) MAXLUNG=LUNG; LUNG=0; } Ch1=Ch2; } while (Ch2!=’\n’); printf("\n Numero parole --> %d \n",NPAR); printf("\n Lunghezza parola piu’ lunga" "--> %d \n",MAXLUNG); }