Uni.LabC23-24 History
Show minor edits - Show changes to output
October 09, 2007, at 09:38 PM
by
- Changed lines 251-252 from:
// 1. magia(0) vale 1;
// 2. se n>0, allora magia(n) vale (magia(n-1)+100) se n e' pari e (2*magia(n-1)) se n e' dispari;
// 2. se n>0, allora magia(n) vale (magia(n-1)+100) se n e' pari e (2*magia(n-1)) se n e' dispari;
to:
1. magia(0) vale 1;
2. se n>0, allora magia(n) vale (magia(n-1)+100) se n e' pari
e (2*magia(n-1)) se n e' dispari;
2. se n>0, allora magia(n) vale (magia(n-1)+100) se n e' pari
e (2*magia(n-1)) se n e' dispari;
Changed line 345 from:
[[!Programmazione]] | [[!UniCrema]]
to:
[[Torna al Laboratorio di C->Uni.LaboratorioC]] | [[!Programmazione]]
October 05, 2007, at 03:07 PM
by
- Changed lines 343-346 from:
\\
-----
[[Torna all'elenco delle lezioni -> LaboratorioC]]
-----
[[Torna all'elenco delle lezioni -> LaboratorioC]]
to:
----
[[!Programmazione]] | [[!UniCrema]]
[[!Programmazione]] | [[!UniCrema]]
October 05, 2007, at 03:06 PM
by
- Changed line 346 from:
[[<<Torna all'elenco delle lezioni -> LaboratorioC]]
to:
[[Torna all'elenco delle lezioni -> LaboratorioC]]
October 05, 2007, at 03:06 PM
by
- Changed lines 2-3 from:
Qui ci sono le soluzioni agli esercizi dell'ultima lezione, con tanto di commento.\\\
to:
%titolo%''':: Laboratorio C - Lezione 23-24 ::'''
Qui ci sono le soluzioni agli esercizi dell'ultima lezione, con tanto di commento.
Qui ci sono le soluzioni agli esercizi dell'ultima lezione, con tanto di commento.
June 08, 2007, at 12:05 AM
by
- Added line 156:
int flag = 0;
Changed line 168 from:
while (!feof(costituzione)) {
to:
%bgcolor=yellow%while (!feof(costituzione)) {
Changed lines 170-177 from:
fscanf(costituzione, "%c", &c);
numero_caratteri ++;
if (c == 'r') {
fscanf(costituzione, "%c", &c);
numero_caratteri ++;
if (c == 'a') numero_ra ++;
}
else if (c == 'i' || c == 'I') numero_i ++;
numero_caratteri ++;
if (c == 'r') {
fscanf(costituzione, "%c", &c);
numero_caratteri ++;
if (c == 'a') numero_ra ++;
}
else if (c == 'i' || c == 'I') numero_i ++;
to:
%bgcolor=yellow%fscanf(costituzione, "%c", &c);
%bgcolor=yellow%numero_caratteri ++;
%bgcolor=yellow%if (c == 'r') {
%bgcolor=yellow% fscanf(costituzione, "%c", &c);
%bgcolor=yellow% numero_caratteri ++;
%bgcolor=yellow% if (c == 'a') numero_ra ++;
%bgcolor=yellow%}
%bgcolor=yellow%else if (c == 'i' || c == 'I') numero_i ++;
%bgcolor=yellow%}
while(fscanf(costituzione, "%c", &c") == 1)
{
if (c == 'r') flag = 1;
else if (c == 'a' && flag == 1) {
flag = 0;
numero_ra++;
%bgcolor=yellow%numero_caratteri ++;
%bgcolor=yellow%if (c == 'r') {
%bgcolor=yellow% fscanf(costituzione, "%c", &c);
%bgcolor=yellow% numero_caratteri ++;
%bgcolor=yellow% if (c == 'a') numero_ra ++;
%bgcolor=yellow%}
%bgcolor=yellow%else if (c == 'i' || c == 'I') numero_i ++;
%bgcolor=yellow%}
while(fscanf(costituzione, "%c", &c") == 1)
{
if (c == 'r') flag = 1;
else if (c == 'a' && flag == 1) {
flag = 0;
numero_ra++;
Added lines 187-194:
else if (c=='i' || c == 'I') {
numero_i++;
flag = 0;
}
else flag = 0;
}
frequenza_i = (float) numero_i / numero_caratteri;
numero_i++;
flag = 0;
}
else flag = 0;
}
frequenza_i = (float) numero_i / numero_caratteri;
Deleted lines 195-196:
frequenza_i = (float) numero_i / numero_caratteri;
Changed lines 213-219 from:
while (!feof(costituzione)) {
fscanf(costituzione, "%c", &c);
numero_caratteri ++;
if (c == 'r') {
fscanf(costituzione, "%c", &c);
numero_caratteri ++;
if (c == 'a') numero_ra ++;
fscanf(costituzione, "%c", &c);
numero_caratteri ++;
if (c == 'r') {
fscanf(costituzione, "%c", &c);
numero_caratteri ++;
if (c == 'a') numero_ra ++;
to:
while(fscanf(costituzione,"%c", &c") == 1)
{
if (c == 'r') flag = 1;
else if (c == 'a' && flag == 1) {
flag = 0;
numero_ra++;
{
if (c == 'r') flag = 1;
else if (c == 'a' && flag == 1) {
flag = 0;
numero_ra++;
Changed lines 220-229 from:
else if (c == 'i' || c == 'I') numero_i ++;
}
Ogni volta che faccio una ''fscanf'' sul file, aumento il numero di caratteri, ed il motivo mi sembra ovvio.\\\
Se il carattere trovato è una ''r'', devo poi controllare che ci sia una ''a'', ecco perché dopo il primo
if (c == 'r')
c'è un'altra ''fscanf''.\\\
Sia che trovo una lettera che non è ''r'', sia che trovo una ''r'' non seguita da una ''a'', il programma cade automaticamente nell'
else if (c == 'i' || c == 'I') numero_i ++;
Ciò accade perché uso sempre il ''char c'' per immagazzinare il prossimo carattere da leggere.\\\
}
Ogni volta che faccio una ''fscanf'' sul file, aumento il numero di caratteri, ed il motivo mi sembra ovvio.\\\
Se il carattere trovato è una ''r'', devo poi controllare che ci sia una ''a'', ecco perché dopo il primo
if (c == 'r')
c'è un'altra ''fscanf''.\\\
Sia che trovo una lettera che non è ''r'', sia che trovo una ''r'' non seguita da una ''a'', il programma cade automaticamente nell'
else if (c == 'i' || c == 'I') numero_i ++;
Ciò accade perché uso sempre il ''char c'' per immagazzinare il prossimo carattere da leggere.\\\
to:
else if (c=='i' || c == 'I') {
numero_i++;
flag = 0;
}
else flag = 0;
}
%bgcolor = yellow% DA MODIFICARE
numero_i++;
flag = 0;
}
else flag = 0;
}
%bgcolor = yellow% DA MODIFICARE
June 04, 2007, at 11:18 PM
by
- Changed lines 328-329 from:
to:
\\
June 04, 2007, at 11:17 PM
by
- Changed lines 328-329 from:
[[<<Torna all'elenco delle lezioni -> LaboratorioC]]
to:
Changed line 330 from:
[[!Programmazione]] | [[!C]]
to:
[[<<Torna all'elenco delle lezioni -> LaboratorioC]]
June 04, 2007, at 11:13 PM
by
- Added lines 1-331:
(:title Laboratorio C - Lezione 23-24:)
Qui ci sono le soluzioni agli esercizi dell'ultima lezione, con tanto di commento.\\\
!!Esercizio 1
Data la traccia sotto riportata completare il codice in modo di aumentare di 1 tutti gli interi pari e diminuire di 1 tutti quelli dispari nell'array vettore[] di dimensione dim. Riportare come risultato il numero che comparira' a monitor. Per esempio un vettore che contiene gli elementi {4,56,3,78,23} dopo essere stato aggiornato deve contenere gli elementi {5,57,2,79,22}.
'''Aumenta interi pari'''
#include <stdio.h>
float CalcolaRisultato(int vettore[], int dim);
int main() {
int vettore[] = {4,56,3,78,23} ;
int dim = 5;
int conto;
float risultato;
//Se il tuo programma funziona correttamente, dovresti ottenere: 2573
for (conto = 0; conto < dim; conto ++) {
if ((vettore[conto] % 2) == 0) vettore[conto] ++;
else vettore[conto] --;
}
risultato = CalcolaRisultato(vettore, dim);
printf("\nrisultato da copiare ed incollare = %d \n\n" , (int) risultato );
getchar();
exit(0);
} // main
float CalcolaRisultato(int vettore[], int dim)
{
int i;
float divisore, dividendo=0;
for(i=0;i < dim; i++)
{
dividendo += i * vettore[i];
}
divisore = (dim +1)*dim/2;
return 100*dividendo/divisore;
}
!!!Note sull'esercizio
Innanzitutto, l'esercizio ti dava un vettore di 462 elementi, mentre qui il vettore ne ha solamente 5.\\\
Il cuore dell'esercizio sta nella sequenza\\\
for (conto = 0; conto < dim; conto ++) {
if ((vettore[conto] % 2) == 0) vettore[conto] ++;
else vettore[conto] --;
}
che vuol dire esattamente questo:
for (conto = 0; conto < dim; conto ++)
esamina il vettore dal primo all'ultimo elemento, ricordando che dim = numero elementi del vettore.\\\
if ((vettore[conto] % 2) == 0) vettore[conto] ++;
else vettore[conto] --;
''If ((vettore[conto] % 2) == 0)'' controlla se l'elemento conto-esimo del vettore è pari, cioè se il resto della divisione intera per due è 0.\\\
In caso positivo, esegue la riga ''vettore[conto] ++'', come da specifica; in caso contrario invece viene diminuito con ''vettore[conto] --'', sempre come da specifica.\\\
La funzione ''CalcolaRisultato'' è stata data dal professore, serve per generare il valore che va incollato etc. etc.\\\
!! Esercizio 2
Esegui le seguenti attivita':
* salva il testo sotto riportato nel file telefonate.txt ;
* scrivi il programma Contatelefonate.c che accede al file telefonate.txt e calcola il numero di telefonate effettuate a un cellulare e il numero di quelle effettuate verso un numero fisso;
* calcola come risultato il maggiore tra questi due numeri.
Per stabilire se il telefono e' un cellulare o un fisso si consiglia di utilizzare la funzione strcmp(s1,s2) che restituisce 0 se le due stringhe sono uguali, un numero negativo se s1 e' minore di s2 in ordine lessicografico e un numero positivo altrimenti. Nota bene: il file telefonate.txt e' composto da stringa tabulatore numeroconvirgola tabulatore stringa tabulatore stringa FINERIGA
!!!Note preliminari
Il file ''telefonate.txt'' fornito dal professore NON è nel formato che lui indica, cioè ''stringa tab numeroconvirgola tab stringa tab string FINERIGA'', perché non ci sono TAB ma SPAZI fra una riga e l'altra!\\\
Inoltre, il risultato che dà lui, cioè 45, è SBAGLIATO: le chiamate a cellulare sono 44, e sono maggiori delle 23 chiamate a fisso...\\\
'''Telefonate'''
#include <stdio.h>
#include <string.h>
int main() {
FILE * telefonate;
int chiamate_fisso = 0;
int chiamate_cell = 0;
int valore;
char numero[30];
char ora[30];
char tipo[30];
char durata[30];
telefonate = fopen("telefonate.txt", "r");
if (telefonate == NULL) {
printf("Errore nell'apertura del file telefonate.txt\n");
getchar();
return 1;
}
while (!feof(telefonate)) {
fscanf(telefonate,"%s %s %s %s\n", numero, ora, tipo, durata);
printf("%s\n", tipo);
valore = strcmp(tipo, "cellul");
if (valore == 0) chiamate_cell ++;
else chiamate_fisso++;
}
if (chiamate_fisso > chiamate_cell) printf("%d\n", chiamate_fisso);
else printf("%d\n", chiamate_cell);
getchar();
return 0;
}
!!!Note postliminari
L'unica stringa che ci interessa è la 3a, cioè quella che contiene scritto ''cellul'' oppure ''milano'', ''firenze'' o quel diavolo che è.\\\
La funzione ''strcmp(stringa1,stringa2)'' fa parte della libreria standard del C, e la si ottiene con la riga
#include <string.h>
in cima.\\\
''strcmp(stringa1, stringa2)'' funziona così:
* se le stringhe sono uguali, restituisce uno 0;
* se la prima stringa è MINORE della seconda, lessicograficamente parlando, resituisce -1, o comunque un valore minore di 0
* se invece la seconda stringa è MAGGIORE della seconda, restituisce un valore maggiore di 0, di solito + 1.
Che cosa vuol dire lessicograficamente parlando? Bene o male, è una specie di conto alfabetico, provate un po' per vedere che cosa voglia significare.\\\
Ai nostri fini, serve solo verificare che la terza stringa sia uguale a ''cellul'', e in quel caso aumentare il contatore di numero di chiamate a cell.\\\
Tutto ciò lo si ottiene con
valore = strcmp(tipo, "cellul");
if (valore == 0) chiamate_cell ++;
else chiamate_fisso++;
dove ''int valore'' l'ho dichiarata appositamente allo scopo.
!!Esercizio 3
Scrivi un programma che:
# conta quanti caratteri ci sono nel file COSTITUZ.TXT (63 KB) ;
# conta quante volte compare la lettera minuscola 'r' seguita dalla minuscola 'a' ;
# calcola come FLOAT la frequenza di occorrenza della lettera 'i' (e' indifferente se maiuscola o minuscola);
# restituisce come soluzione (con due decimali dopo la virgola) il FLOAT contenete il prodotto delle due quantita' appena calcolate nei punti 2.e 3.
Soluzione: risultato da copiare ed incollare = 45.23
'''costituzione.c'''
#include <stdio.h>
int main() {
FILE * costituzione;
int numero_ra = 0;
int numero_i = 0;
int numero_caratteri = 0;
float frequenza_i;
float risultato;
char c;
costituzione = fopen("costituzione.txt", "r");
if (costituzione == NULL) {
printf("Errore nell'apertura del file costituzione.txt");
getchar();
return 1;
}
while (!feof(costituzione)) {
fscanf(costituzione, "%c", &c);
numero_caratteri ++;
if (c == 'r') {
fscanf(costituzione, "%c", &c);
numero_caratteri ++;
if (c == 'a') numero_ra ++;
}
else if (c == 'i' || c == 'I') numero_i ++;
}
frequenza_i = (float) numero_i / numero_caratteri;
printf("Numero di ra = %d\n", numero_ra);
printf("Numero di i = %d\n", numero_i);
printf("Numero di caratteri = %d\n", numero_caratteri);
printf("Frequenza di i = %f\n", frequenza_i);
printf("risultato = %2.2f", numero_ra * frequenza_i);
fclose(costituzione);
getchar();
return 0;
}
!!!Note sull'esercizio
I punti dubbi sono:
* I caratteri come lo spazio o la punteggiatura vanno contati come numero_caratteri, oppure no? E le lettere accentate, vanno trasformate in lettere non accentate o che diavolo?
Ad ogni modo, il cuore dell'esercizio sta nelle righe
while (!feof(costituzione)) {
fscanf(costituzione, "%c", &c);
numero_caratteri ++;
if (c == 'r') {
fscanf(costituzione, "%c", &c);
numero_caratteri ++;
if (c == 'a') numero_ra ++;
}
else if (c == 'i' || c == 'I') numero_i ++;
}
Ogni volta che faccio una ''fscanf'' sul file, aumento il numero di caratteri, ed il motivo mi sembra ovvio.\\\
Se il carattere trovato è una ''r'', devo poi controllare che ci sia una ''a'', ecco perché dopo il primo
if (c == 'r')
c'è un'altra ''fscanf''.\\\
Sia che trovo una lettera che non è ''r'', sia che trovo una ''r'' non seguita da una ''a'', il programma cade automaticamente nell'
else if (c == 'i' || c == 'I') numero_i ++;
Ciò accade perché uso sempre il ''char c'' per immagazzinare il prossimo carattere da leggere.\\\
!!Esercizio 4
Utilizzando codoce sotto riportato come traccia si scriva un programma che contiene una funzione ricorsiva int magia(int n) che si basa sulla funzione ricorsiva magia(n):
# magia(0) vale 1;
# se n>0, allora magia(n) vale (magia(n-1)+100) se n e' pari e (2*magia(n-1)) se n e' dispari;
Il risultato e' quello restituito a monitor dal codice.
'''magia.c'''
#include <stdio.h>
int magia(int n);
int main() //NON MODIFICARE IL MAIN
{
printf("la soluzione e' --> %d", magia(13));
getchar();
return(0);
}
int magia(int n) {
// 1. magia(0) vale 1;
// 2. se n>0, allora magia(n) vale (magia(n-1)+100) se n e' pari e (2*magia(n-1)) se n e' dispari;
if (n == 0) return 1;
else if (n > 0) {
if ((n % 2) == 0) return magia(n - 1) + 100;
else return 2*magia(n-1);
}
}
!!!Note sull'esercizio
Le funzioni ricorsive si scrivono esattamente come le leggete: se ci fate caso, ho copiato pari pari la specifica data dal problema e l'ho tradotta in C.\\\
Infatti, la riga che dice:\\
''magia(0) vale 1;''\\\
si traduce letteralmente in
if (n == 0) return 1;
mentre la riga che dice:\\
''se n>0, allora magia(n) vale (magia(n-1)+100) se n e' pari e (2*magia(n-1)) se n e' dispari;''\\\
diventa
else if (n > 0) {
if ((n % 2) == 0) return magia(n - 1) + 100;
else return 2*magia(n-1);
}
!! Esercizio 5
Si utilizzi il codice sotto riportato per risolvere l'esercizio. Data il vettore di caratteri (stringa) v[] inizializzato nel codice dell'esercizio:
* si critti carattere per carattere la stringa v[] mediante il metodo di Cesare con chiave 1 memorizzando il risultato nella stringa srt[];
* La stringa srt[] deve possedere il proprio terminatore;
* il risultato finale e' il numero che compare a monitor (viene prodotto automaticamente dalla funzione CalcolaRisulato che ha gia' impostato il passaggio della stringa srt).
'''cesare.c'''
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
float CalcolaRisultato(char stringa[]);
int main()
{
char v[]="SIATTACCADOMANIALLALBA" ;
char str[1000]=""; // stringa nella quale va inserito il risultato finale
float risultato;
int i;
// ----- inzio dell'esercizo -------
for (i = 0; i < strlen(v); i ++) {
str[i] = v[i] + 1;
}
str[strlen(v)] = 0;
printf("%s\n", str);
// ----- fine dell'esercizo -------
// NON TOCCARE TUTTE LE RIGHE QUI SOTTO
risultato = CalcolaRisultato(str);
printf("\nrisultato da copiare ed incollare = %d \n\n" , (int) risultato );
getchar();
exit(0);
} // main
float CalcolaRisultato(char stringa[])
{
int i;
float divisore, dividendo=0;
int dim = strlen(stringa);
for(i=0;i < dim; i++)
{
dividendo += i * (int)stringa[i];
}
divisore = (dim +1)*dim/2;
return 100*dividendo/divisore;
}
!!!Note sull'esercizio
Mi sembra semplice: ogni lettera va incrementata di 1, cioè la ''a'' diventa ''b'' etc.\\\
Inoltre, questa modifica non va salvata nella stringa originale, bensì in str[]. Ciò vuol dire che occorre mettere il \0 alla fine della stringa, perché la teoria ci insegna che le stringhe in C sono NULL-terminated, cioè finiscono con uno 0 (non il carattere, ma proprio il valore 0).\\\
Ecco perché ho messo
str[strlen(v)] = 0;
La ''strlen(v)'' mi restituisce la lunghezza della stringa ''v''. Da notare che se la stringa ha 4 caratteri, la strlen mi restituisce il numero 4 => occorre ricordarsi che la prima posizione delle stringhe è 0.\\\
Quindi, il ciclo ''for'' è stato scritto cos':
for (i = 0; i < strlen(v); i ++) {
mentre il 5° carattere deve essere il famoso 0 di cui sopra:
str[strlen(v)] = 0;
[[<<Torna all'elenco delle lezioni -> LaboratorioC]]
-----
[[!Programmazione]] | [[!C]]
Qui ci sono le soluzioni agli esercizi dell'ultima lezione, con tanto di commento.\\\
!!Esercizio 1
Data la traccia sotto riportata completare il codice in modo di aumentare di 1 tutti gli interi pari e diminuire di 1 tutti quelli dispari nell'array vettore[] di dimensione dim. Riportare come risultato il numero che comparira' a monitor. Per esempio un vettore che contiene gli elementi {4,56,3,78,23} dopo essere stato aggiornato deve contenere gli elementi {5,57,2,79,22}.
'''Aumenta interi pari'''
#include <stdio.h>
float CalcolaRisultato(int vettore[], int dim);
int main() {
int vettore[] = {4,56,3,78,23} ;
int dim = 5;
int conto;
float risultato;
//Se il tuo programma funziona correttamente, dovresti ottenere: 2573
for (conto = 0; conto < dim; conto ++) {
if ((vettore[conto] % 2) == 0) vettore[conto] ++;
else vettore[conto] --;
}
risultato = CalcolaRisultato(vettore, dim);
printf("\nrisultato da copiare ed incollare = %d \n\n" , (int) risultato );
getchar();
exit(0);
} // main
float CalcolaRisultato(int vettore[], int dim)
{
int i;
float divisore, dividendo=0;
for(i=0;i < dim; i++)
{
dividendo += i * vettore[i];
}
divisore = (dim +1)*dim/2;
return 100*dividendo/divisore;
}
!!!Note sull'esercizio
Innanzitutto, l'esercizio ti dava un vettore di 462 elementi, mentre qui il vettore ne ha solamente 5.\\\
Il cuore dell'esercizio sta nella sequenza\\\
for (conto = 0; conto < dim; conto ++) {
if ((vettore[conto] % 2) == 0) vettore[conto] ++;
else vettore[conto] --;
}
che vuol dire esattamente questo:
for (conto = 0; conto < dim; conto ++)
esamina il vettore dal primo all'ultimo elemento, ricordando che dim = numero elementi del vettore.\\\
if ((vettore[conto] % 2) == 0) vettore[conto] ++;
else vettore[conto] --;
''If ((vettore[conto] % 2) == 0)'' controlla se l'elemento conto-esimo del vettore è pari, cioè se il resto della divisione intera per due è 0.\\\
In caso positivo, esegue la riga ''vettore[conto] ++'', come da specifica; in caso contrario invece viene diminuito con ''vettore[conto] --'', sempre come da specifica.\\\
La funzione ''CalcolaRisultato'' è stata data dal professore, serve per generare il valore che va incollato etc. etc.\\\
!! Esercizio 2
Esegui le seguenti attivita':
* salva il testo sotto riportato nel file telefonate.txt ;
* scrivi il programma Contatelefonate.c che accede al file telefonate.txt e calcola il numero di telefonate effettuate a un cellulare e il numero di quelle effettuate verso un numero fisso;
* calcola come risultato il maggiore tra questi due numeri.
Per stabilire se il telefono e' un cellulare o un fisso si consiglia di utilizzare la funzione strcmp(s1,s2) che restituisce 0 se le due stringhe sono uguali, un numero negativo se s1 e' minore di s2 in ordine lessicografico e un numero positivo altrimenti. Nota bene: il file telefonate.txt e' composto da stringa tabulatore numeroconvirgola tabulatore stringa tabulatore stringa FINERIGA
!!!Note preliminari
Il file ''telefonate.txt'' fornito dal professore NON è nel formato che lui indica, cioè ''stringa tab numeroconvirgola tab stringa tab string FINERIGA'', perché non ci sono TAB ma SPAZI fra una riga e l'altra!\\\
Inoltre, il risultato che dà lui, cioè 45, è SBAGLIATO: le chiamate a cellulare sono 44, e sono maggiori delle 23 chiamate a fisso...\\\
'''Telefonate'''
#include <stdio.h>
#include <string.h>
int main() {
FILE * telefonate;
int chiamate_fisso = 0;
int chiamate_cell = 0;
int valore;
char numero[30];
char ora[30];
char tipo[30];
char durata[30];
telefonate = fopen("telefonate.txt", "r");
if (telefonate == NULL) {
printf("Errore nell'apertura del file telefonate.txt\n");
getchar();
return 1;
}
while (!feof(telefonate)) {
fscanf(telefonate,"%s %s %s %s\n", numero, ora, tipo, durata);
printf("%s\n", tipo);
valore = strcmp(tipo, "cellul");
if (valore == 0) chiamate_cell ++;
else chiamate_fisso++;
}
if (chiamate_fisso > chiamate_cell) printf("%d\n", chiamate_fisso);
else printf("%d\n", chiamate_cell);
getchar();
return 0;
}
!!!Note postliminari
L'unica stringa che ci interessa è la 3a, cioè quella che contiene scritto ''cellul'' oppure ''milano'', ''firenze'' o quel diavolo che è.\\\
La funzione ''strcmp(stringa1,stringa2)'' fa parte della libreria standard del C, e la si ottiene con la riga
#include <string.h>
in cima.\\\
''strcmp(stringa1, stringa2)'' funziona così:
* se le stringhe sono uguali, restituisce uno 0;
* se la prima stringa è MINORE della seconda, lessicograficamente parlando, resituisce -1, o comunque un valore minore di 0
* se invece la seconda stringa è MAGGIORE della seconda, restituisce un valore maggiore di 0, di solito + 1.
Che cosa vuol dire lessicograficamente parlando? Bene o male, è una specie di conto alfabetico, provate un po' per vedere che cosa voglia significare.\\\
Ai nostri fini, serve solo verificare che la terza stringa sia uguale a ''cellul'', e in quel caso aumentare il contatore di numero di chiamate a cell.\\\
Tutto ciò lo si ottiene con
valore = strcmp(tipo, "cellul");
if (valore == 0) chiamate_cell ++;
else chiamate_fisso++;
dove ''int valore'' l'ho dichiarata appositamente allo scopo.
!!Esercizio 3
Scrivi un programma che:
# conta quanti caratteri ci sono nel file COSTITUZ.TXT (63 KB) ;
# conta quante volte compare la lettera minuscola 'r' seguita dalla minuscola 'a' ;
# calcola come FLOAT la frequenza di occorrenza della lettera 'i' (e' indifferente se maiuscola o minuscola);
# restituisce come soluzione (con due decimali dopo la virgola) il FLOAT contenete il prodotto delle due quantita' appena calcolate nei punti 2.e 3.
Soluzione: risultato da copiare ed incollare = 45.23
'''costituzione.c'''
#include <stdio.h>
int main() {
FILE * costituzione;
int numero_ra = 0;
int numero_i = 0;
int numero_caratteri = 0;
float frequenza_i;
float risultato;
char c;
costituzione = fopen("costituzione.txt", "r");
if (costituzione == NULL) {
printf("Errore nell'apertura del file costituzione.txt");
getchar();
return 1;
}
while (!feof(costituzione)) {
fscanf(costituzione, "%c", &c);
numero_caratteri ++;
if (c == 'r') {
fscanf(costituzione, "%c", &c);
numero_caratteri ++;
if (c == 'a') numero_ra ++;
}
else if (c == 'i' || c == 'I') numero_i ++;
}
frequenza_i = (float) numero_i / numero_caratteri;
printf("Numero di ra = %d\n", numero_ra);
printf("Numero di i = %d\n", numero_i);
printf("Numero di caratteri = %d\n", numero_caratteri);
printf("Frequenza di i = %f\n", frequenza_i);
printf("risultato = %2.2f", numero_ra * frequenza_i);
fclose(costituzione);
getchar();
return 0;
}
!!!Note sull'esercizio
I punti dubbi sono:
* I caratteri come lo spazio o la punteggiatura vanno contati come numero_caratteri, oppure no? E le lettere accentate, vanno trasformate in lettere non accentate o che diavolo?
Ad ogni modo, il cuore dell'esercizio sta nelle righe
while (!feof(costituzione)) {
fscanf(costituzione, "%c", &c);
numero_caratteri ++;
if (c == 'r') {
fscanf(costituzione, "%c", &c);
numero_caratteri ++;
if (c == 'a') numero_ra ++;
}
else if (c == 'i' || c == 'I') numero_i ++;
}
Ogni volta che faccio una ''fscanf'' sul file, aumento il numero di caratteri, ed il motivo mi sembra ovvio.\\\
Se il carattere trovato è una ''r'', devo poi controllare che ci sia una ''a'', ecco perché dopo il primo
if (c == 'r')
c'è un'altra ''fscanf''.\\\
Sia che trovo una lettera che non è ''r'', sia che trovo una ''r'' non seguita da una ''a'', il programma cade automaticamente nell'
else if (c == 'i' || c == 'I') numero_i ++;
Ciò accade perché uso sempre il ''char c'' per immagazzinare il prossimo carattere da leggere.\\\
!!Esercizio 4
Utilizzando codoce sotto riportato come traccia si scriva un programma che contiene una funzione ricorsiva int magia(int n) che si basa sulla funzione ricorsiva magia(n):
# magia(0) vale 1;
# se n>0, allora magia(n) vale (magia(n-1)+100) se n e' pari e (2*magia(n-1)) se n e' dispari;
Il risultato e' quello restituito a monitor dal codice.
'''magia.c'''
#include <stdio.h>
int magia(int n);
int main() //NON MODIFICARE IL MAIN
{
printf("la soluzione e' --> %d", magia(13));
getchar();
return(0);
}
int magia(int n) {
// 1. magia(0) vale 1;
// 2. se n>0, allora magia(n) vale (magia(n-1)+100) se n e' pari e (2*magia(n-1)) se n e' dispari;
if (n == 0) return 1;
else if (n > 0) {
if ((n % 2) == 0) return magia(n - 1) + 100;
else return 2*magia(n-1);
}
}
!!!Note sull'esercizio
Le funzioni ricorsive si scrivono esattamente come le leggete: se ci fate caso, ho copiato pari pari la specifica data dal problema e l'ho tradotta in C.\\\
Infatti, la riga che dice:\\
''magia(0) vale 1;''\\\
si traduce letteralmente in
if (n == 0) return 1;
mentre la riga che dice:\\
''se n>0, allora magia(n) vale (magia(n-1)+100) se n e' pari e (2*magia(n-1)) se n e' dispari;''\\\
diventa
else if (n > 0) {
if ((n % 2) == 0) return magia(n - 1) + 100;
else return 2*magia(n-1);
}
!! Esercizio 5
Si utilizzi il codice sotto riportato per risolvere l'esercizio. Data il vettore di caratteri (stringa) v[] inizializzato nel codice dell'esercizio:
* si critti carattere per carattere la stringa v[] mediante il metodo di Cesare con chiave 1 memorizzando il risultato nella stringa srt[];
* La stringa srt[] deve possedere il proprio terminatore;
* il risultato finale e' il numero che compare a monitor (viene prodotto automaticamente dalla funzione CalcolaRisulato che ha gia' impostato il passaggio della stringa srt).
'''cesare.c'''
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
float CalcolaRisultato(char stringa[]);
int main()
{
char v[]="SIATTACCADOMANIALLALBA" ;
char str[1000]=""; // stringa nella quale va inserito il risultato finale
float risultato;
int i;
// ----- inzio dell'esercizo -------
for (i = 0; i < strlen(v); i ++) {
str[i] = v[i] + 1;
}
str[strlen(v)] = 0;
printf("%s\n", str);
// ----- fine dell'esercizo -------
// NON TOCCARE TUTTE LE RIGHE QUI SOTTO
risultato = CalcolaRisultato(str);
printf("\nrisultato da copiare ed incollare = %d \n\n" , (int) risultato );
getchar();
exit(0);
} // main
float CalcolaRisultato(char stringa[])
{
int i;
float divisore, dividendo=0;
int dim = strlen(stringa);
for(i=0;i < dim; i++)
{
dividendo += i * (int)stringa[i];
}
divisore = (dim +1)*dim/2;
return 100*dividendo/divisore;
}
!!!Note sull'esercizio
Mi sembra semplice: ogni lettera va incrementata di 1, cioè la ''a'' diventa ''b'' etc.\\\
Inoltre, questa modifica non va salvata nella stringa originale, bensì in str[]. Ciò vuol dire che occorre mettere il \0 alla fine della stringa, perché la teoria ci insegna che le stringhe in C sono NULL-terminated, cioè finiscono con uno 0 (non il carattere, ma proprio il valore 0).\\\
Ecco perché ho messo
str[strlen(v)] = 0;
La ''strlen(v)'' mi restituisce la lunghezza della stringa ''v''. Da notare che se la stringa ha 4 caratteri, la strlen mi restituisce il numero 4 => occorre ricordarsi che la prima posizione delle stringhe è 0.\\\
Quindi, il ciclo ''for'' è stato scritto cos':
for (i = 0; i < strlen(v); i ++) {
mentre il 5° carattere deve essere il famoso 0 di cui sopra:
str[strlen(v)] = 0;
[[<<Torna all'elenco delle lezioni -> LaboratorioC]]
-----
[[!Programmazione]] | [[!C]]