Upload
ful90
View
229
Download
1
Embed Size (px)
Citation preview
7/24/2019 Dispense linguaggio C
1/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 1
Programmazione in lingu aggio C
Antonio Lio y( lioy @ polito.it )
Politecnico di TorinoDip. di Automatica e Informatica
Informazioni generali sul cor so
sito web del corso: http://security.polito.it/~lioy/12bhd/ nota: si pu sostituire la tilde con %7e ossia
http://security.polito.it/%7elioy/12bhd/ slide del cor so (PDF, richiede Acrobat) s r umen sv uppo u ncy- , or an . vecchi temi desame risultati degli esami
esame: scritt o (2 ore) = programma in C pi tre dom ande di
teoria
Testi
copia dei lucidi usati nel corso (sul sito web del corso) copia dei lucidi usati nelle videolezioni (sul portale) videolezioni del Prof. Mezzalama (sul portale) [ teoria ] P.J.Deitel, M.H.Deitel
C - Corso completo di programmazione,
(teoria) [ teoria ] B.W.Kernighan, D.M.Ritchie
Il linguaggio C. Princip i di programmazione e manuale diriferimentoPrentice Hall, 2004
[ esercizi ] S.Nocco, S.Quer Guida alla programmazione in linguaggio CClut, 2009
LAIB
orario: dal 28/3/11 in via Boggi o (LAIB 2B) 3 sq uadre 14:30-16, 16-17:30, 17:30-19 rispettare tassativamente la suddivisione in sq uadre, non
sono permessi cambi a vaz one u ncy- :
Men Avvio > Programmi Vari > Compilatori
2 assistenti (borsis ti) + Sanchez attivit:
prova dei programmi sviluppati in aula esercizi proposti sul sito dellesame
Strumenti di sviluppo strumento semplice
Quincy 2005 , sul sito web del cors o (16.0 MB) freeware, pienamente integrato in Windows
strumento pi complesso (e completo) Code::Blocks (www.codeblocks.org, scaricare la
vers one comp e a con comp a ore disponi bile per Windows, Mac e Linux
per i veri programmatori: compilatore / linker gcc e debugger gdb da linea di comando (per Linux, Windows e Mac) gcc/gdb installato automaticamente sia con Quincy-
2005 sia con Code::Blo cks
Caratteristiche dei linguaggi di p rogrammazione ogni ling uaggio di prog rammazione ad alto livello (HLL)
caratterizzato da: tipi di dato (primit ivi), es. int tipi di dato (complessi), es. vettori operazioni base, es. + c on r o o e u ss o e e o per az o n , es .
ogni HLL ha una precisa grammatica e sintassi darispettare: parole chiave o keyword
riservate ad uno scopo specifico identificatori
nomi logic i per dati o operazioni
7/24/2019 Dispense linguaggio C
2/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 2
Scrittura di un programma C
il file sorg ente di un progr amma in linguaggio C deve esserecostitu ito da caratteri US-ASCII (non sono con sentiti icaratteri ASCII estesi, quali le lettere accentate)
il linguaggio C "case-sensitive" ossia distingue tramaiuscole e minuscole ad esempio, le parole "Totale" e "tot ale" identificano
entit diverse in C
Struttura di un progr amma C
un prog ramma C deve contenere almeno una funzion echiamata main( ) la parte principale del programma attivata dal loader quando si esegue il programma
la funzione deve essere di tipo: n
restituis ce al S.O. un valore intero qu ale flag di statosulla terminazione del programma
le istruzioni che costit uiscono il main vanno elencatesequenzialmente tra graffe { }
vuoto_i.c
Return ?
per restituire un valore al S.O. si pu u sare listruzionereturn codice_di_uscita ;
il codice di usci ta deve essere un numero intero per convenzione un codic e di uscita pari a zero indica che il
programma terminato normalmente, mentre si usa uncodice diverso da zero nel caso di termin azione dovuta adun errore
il valore pu essere visualizzato a livello di S.O. con
comandi che dip endono dal S.O. esempi: (MS-DOS/Windows)
variabile %errorlevel% nei file batch (Unix/Linux/Mac)
variabile $? negli script bashvuoto.bat
Uso di Quincy-2005
creazione di un file sor gente (e salvataggio!): File > New > (C source file) File > Save as > (scegliere cartella e dare nome xxx.c)
uso di un pro gramma gi presente in un file; File > Open > (scegliere cartella e f ile)
far eseguire il programma direttamente in un passo solo : Project > Execute
far eseguire il programma passo passo: Debug > Step / Step Over / Step To Cursor
creare un file eseguibile: Project > Build eseguo il programma lanciando il suo fil e .EXE da una
finestra di comando
Uso di gcc usando un editor d i testo (es. notepad, blocco note) creo il
file sorgente: prova.c
traduco il file sorgente in file oggetto: gcc -c prova.c
v ene genera o e ogge o prova.o creo il file eseguibile tramite il linker:
gcc -o prova.exe prova.o
viene generato il fi le oggetto prova.exe
oppure faccio tutto in un passo solo: gcc o prova.exe prova.c
Commenti un commento uninfo rmazione per chi legge il progr amma,
non per il computer normalmente inserito a scopo di docu mentazione commenti (originali):
sono racchiusi tra /* e */ possono compren ere var e r g e non possono essere annidati (un commento non pu
contenere al suo interno un altro commento) commenti (nuo va forma, C99):
iniziano con // terminano a fine riga
7/24/2019 Dispense linguaggio C
3/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 3
Esempi di c ommenti
/*
un primo commento valido*/
// un secondo commento valido (solo in C99)
nullprog.c
/* commento che causa /* errore */ ... */
iniziocommento
???finecommento
Identificatori
un identificator e serve per far riferimento simbol icamente adun oggetto, ossi a tramite un nome invece che tramitelindir izzo della cella di memoria in cu i conservato
identificatori sono usati per identificare: costanti (dati che non posson o cambiare) tipi di dati (codif ica dei dati) funzioni (insiemi di istruzioni) file (una sequenza di dati esterni al prog ramma) etichette o label (punti del programma)
Caratteristiche di un identificatore
composto da uno o p i caratteri inizia con carattere alfabetico o _ contiene caratteri alfabetici, numerici o _
esempi:
PagaOraria
paga_oraria _24
PIGRECO
Caratteristiche variabili di un identificatore
identificatori interni: distinzione tra caratteri minuscoli e maiuscoli signif icativi almeno i primi 31 caratteri
identificatori esterni: nessuna distinzione tra caratteri minuscoli e maiuscoli signif icativi almeno i primi 6 caratteri
identificatori riservati:
tutte le keyword del linguaggio(es. int, float, while, if) gli elementi globali della libreria C standard
(es. putchar, sin, cloc k)
Keyword C standard (K&R):auto double int struct
break else long switchcase enum register typedefchar extern return unionconst float short unsigned
il C99 ne aggiunge altre cinque:
cont nue or s gne vodefault goto sizeof volatiledo if static while
inline restrict _Bool _Complex _Imaginary
Definizione di variabili ogni variabile rappresenta simbolic amente delle celle di
memoria a lettura / scrittura: il tipo di u na variabile indica la codifica binaria da usarsi
per memorizzarne il valore il nome di u na variabile indica l'indir izzo della cella di
memoria ove memorizzato il dato co rrispod ente si possono dichiarare pi variabili dello stesso tipo
separandole con una virgola sintassi:
tipo nome_variabile [ = valore_iniziale ] ; esempi:
int totale = 0;float PrezzoLordo, PrezzoNetto;
7/24/2019 Dispense linguaggio C
4/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 4
Tipi base
i tipi base del linguaggio C sono: char (caratteri ASCII) in t (numeri interi con segno) float (numeri floating-point in singola precisione) double (numeri floating-point in doppia precisione) _Bool (valori Booleani) solo in C99
Modificatori
i tipi poss ono essere preceduti da un modificatore: signed (numeri con segno) unsigned (numeri senza segno) short (occupazione ridotta di memoria) long (occupazione maggiore di memoria)
nel C99 anche: long long (occupazione molto maggiore di memoria) _Complex (numeri complessi) _Imaginar y (numeri immaginari)
il tipo int p u essere sottinteso quando preceduto da unmodific atore (es. unsigned invece di unsigned int )
Appl icazione dei modifi cator i
[ signed | unsigned ] char [ signed | unsigned ] short [ int ] [ signed | unsigned ] int [ signed | unsigned ] long [ int ] [ signed | unsigned ] long long [ int ] float [ long ] double
float _Complex [ long ] doub le _Complex float _Imaginary [ long ] double _ Imaginary
Costanti (letterali)
tipo esempi
numeri interi 26 -26
numeri interi (long) 26L -26L
numeri interi (unsigned) 26U
numeri ottali 032
numeri esadecimali 0x1a 0X1A numeri floating-point 230.4 -230.42.304e2 2.304E2
singolo carattere 'a'
stringhe di caratteri "alfabeto"
Costanti speciali di tipo caratterecarattere formato
BEL (beep) \a
BS (backspace) \b
FF (form feed) \f
CR (carriage return) \r
HT (horizontal tab) \t
carattere ASCII (ottale) \nnn
carattere ASCII (esadecimale) \Xnn
Ritorno a capo la codifica dei file di testo usa schemi diversi per indi care
che una riga terminata e ne inizia una nuo va: MS-DOS / MS-Window s = CR+LF UNIX = LF MACINTOSH = CR
per convenz one n nguagg o s usa sempre e so o ,ossia il c arattere \n , lasciando alla libreria di I/O (stdio.h) ilcompito d i inserire i caratteri giu sti a seconda del S.O. sucui il prog ramma eseguito
ci vale sia in output sia in inpu t
7/24/2019 Dispense linguaggio C
5/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 5
Problema: saluta
Fare un programma che: scriva in output un saluto
Sottoproblema: come si produce un testo in output?
Come si produce in output un risultato?
si usa la funzione printf il primo argomento la stringa di formato che contiene:
i caratteri da scrivere direttamente le direttive di conversione per indicare il formato da
usare per stampare dei valori g a r argomen sono va o r c e s v og ono s ampare a
esempio una variabile o unespressione) attenzione: ad ogni direttiva di conversione DEVE
corrisp ondere un valore altrimenti lo utput generato impredicibile
sintassi:int printf (" formato_di_stampa ", variabili );
Direttive di conversione per la printf
%d, %i (int, short, char interpretato come numero interodecimale)
%ld (long) %u (unsigned) %lu (unsigned long) oa %lf (double)
%c (char, interpretato c ome carattere ASCII) %s (char[ ] = strin ga di caratteri ASCII) %x, %X (numero intero i nterpretato come esadecimale) %o (numero intero interpretato com e ottale) %% genera il c arattere '%'
Corrispondenza direttive : valori
printf ("totale = %d arrivederci\n", tot );
tot deve essere una variabile di tipo intero+
il suo valore verr presentato in outputcome numero decimale
La libreria stdio per poter usare le funzioni di I/O standard del linguaggio C
come printf( ) e getchar( ) occorre infor mare il sistema ditraduzione affinch: il compi latore ne capisca la sintassi il linker agganci le opportune librerie
,testa al file (N.B. il carattere # deve essere in pr ima colo nna):
#include
Soluzione: saluta (v1, v2)/* saluta (v1) */#include
int main (){
printf ("Buona giornata!");return 0;
}
/* saluta (v2) */#include
int main (){
printf ("Buona giornata!\n");return 0;
}
7/24/2019 Dispense linguaggio C
6/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 6
Soluzione: saluta (v3, v4)
/* saluta (v3) */
#include
int main (){
printf ("Buona ");" " * *
return 0;}
#include
int main (){
printf ("Buona "); printf ("giornata!"); printf ("\n");
return 0;}
Esempio stampa anno
Scrivere un programma che: memorizzi in una cella di memoria lanno attuale indichi in output di quale anno si tratta
#include
int main (){
unsigned anno = 2009;
printf ("Buon %u!\n", anno);
return 0;}
anno.c
Assegnazion i
per memorizzare un dato in u na cella di memoria si usaloperatore =
a sinistra del simbolo si i ndica la cella destinazione a destra del simbolo si scrive lespressi one che genera il
valore da memori zzare, terminata con ;
esempi:
a = 5.3; b = 2 * 7;
c = a + b / 2;d = c;
variabile = espressione ;
Operazioni aritmetiche
operatori aritmetici: somma ( + ) sottrazione ( ) moltipl icazione ( * ) division e ( / ) modulo ( % ) (=resto della divi sione intera)
loperazione di divisione eseguita tra numeri interi fornisc eun risult ato intero, ossia il quoziente (scartando il resto) esempio di divisi one su operandi interi: 10 / 4 = 2 esempio di divi sione su o perandi float: 10.0 / 4 = 2.5
l'operazione di modulo possibil e solo tra variabili intere
Espressioni aritmetiche le operazioni seguono le normali regole di pr ecedenza si posso no usare le parentesi tonde per alterare lordi ne di
precedenza
2 + 3 * 7 diverso da (2 + 3) * 7
Rango dei tipi numerici le operazioni avvengono dopo aver trasformato tutt i gli
operandi al tipo di rango pi alto presentenellespressione
gli operandi includono tutti gli elementi dellespressione: costanti risultati di funzioni
unica eccezione: tutti i calcoli che coinvolg ono almeno unnumero reale (non impo rta se float o doub le) avvengonotrasformando prima tutti gli operandi in double
7/24/2019 Dispense linguaggio C
7/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 7
Rango dei tipi numerici
_Bool
charshortunsigned shortint
minore
longunsigned longlong longunsigned long longfloatdoublelong doublemaggiore
Rango dei tipi numerici
prestare attenzione quando listruzione coinvol ge tipi interi ereali
esempio di comportamento inaspettato:
float num;
num = ; num =
num = 7 / 2.0; /* num = 3.5 */
char: intero o carattere?
le variabili di tipo char poss ono essere considerateindifferentemente come caratteri ASCII o com e numeri interi
linterpretazione dipende dalluso che ne fa il progr amma (adesempio con un formato "%c" o " %d" in unop erazione dioutput)
char.c
Input di dati
una delle fasi pi complesse e pi sogg ette ad erroriperch comporta unin terazione con un essere umano
il quale non sempre si comporta come il programmatoresi aspetta
il C rende disponibili varie funzioni per leggere dati da input: , , input di dati generici (scanf, )
La funzione SCANF una delle pi p ericolose .Viene qui intro dotta solo per permettere di svolgerealcuni esercizi prima di aver imparato il modo correttoper acquisire dati da input.Luso di SCANF in un tema di esame comporta unavalutazione pesantemente negativa.
Input tramite scanf ( ) legge caratteri da input cercando di identi ficare e convertire
i dati specificati nella direttiva di conversione i dati letti vengono memorizzati nelle variabili in dicate come
parametri: i nomi d elle variabili devono essere preceduti da & stesse direttive d ella printf (es. %d, %f)
la funzione ritorna il numero di dati identif icati e convertiticon successo
prototipo:
int scanf ( " direttive_di_conversione ",&var1 , & var2 , ... );
Direttive di conversione (scanf) in generale si usano le stesse direttive che si usano co me
formato di stampa nella funzione printf (%d, %c, %s, ) es. %d %f legge e memorizza un numero i ntero ed uno
reale con la specifica %* si indi ca che il dato deve essere
saltato ossia letto ma non memorizzato; non occorrequindi in dicare una variabile per esso es. %d %*d %d l egge tre numeri interi ma ne
memorizza solo due (il primo ed il terzo) un numero prima del tipo di dati da convertire indica che il
dato occupa esattamente quel numero di caratteri nellastringa di input es. "%4d%2d%2d" per leggere i campi della data
"20071107" e memorizzarli in tre variabili (anno, mese,giorno)
7/24/2019 Dispense linguaggio C
8/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 8
Indirizzi delle variabili
in C quando si scrive il nom e di una variabile si indic a ilvalore memorizzato in essa
eccezioni: quando la variabile compare come termine sinist ro di
unassegnazione (es. a = )
in questi casi si int ende lindirizzo della cella di memoriacorrisp ondente alla variabile
eccezione: i nomi delle variabili vettoriali (come le strin ghe)indicano sempre lindi rizzo della variabile
quindi nella scanf i nomi delle variabili devono essere tuttipreceduti da & (a meno che si tratti di s tringhe) perch nonindicano il valor e della variabile ma la cella di memoria ovedepositare il valore letto
Problema (area di un pavimento piastrellato)
scrivere un programma che: richieda ed acquisisca il lato d i una piastrella quadrata
(espresso in cm) richieda ed acquisisca il numero di piastrelle presenti sul
pavimento
algoritmo risolutivo (pseudo-linguaggio): leggere lato (lato) e numero di piastrelle (n_piastrelle) area = n_piastrelle * lato * lato presentare area in metri quadri (area/10000)
Soluzione (area di un pavimento piastrellato)#include
int main (){
unsigned n_piastrelle;float lato;float area;
printf ("Lato piastrella [cm]? ");scanf ("%f", &lato);
printf ("Numero piastrelle? ");scanf ("%u", &n_piastrelle);area = n_piastrelle * lato * lato;
printf ("Area del pavimento = %f mq\n",area/10000);
return 0;} pavimento.c
Esempio: pro blemi usando scanf
Chi volesse rendersi conto dei problemi generati dalluso discanf, esegua il programma pavimento fornendo i seguentiinput:
Lato piastrella [cm]? ventiNumero piastrelle? cento Lato piastrella [cm]? 20
Numero piastrelle? cento
Lato piastrella [cm]? 7,5Numero piastrelle? 100
Lato piastrella [cm]? 20 cmNumero piastrelle? 100
Lato piastrella [cm]? 2 0Numero piastrelle? 100
Problema (classificazione di un numero) scrivere un programma che:
richieda ed acquisisca un numero intero indichi se il numero positivo o negativo
nota: ai fini del presente probl ema, lo zero si cons ideracome un numero positivo
sottoproblema: come si pu sapere se un numero positivo?
Come determinare se una variabileha un certo valore?
si usa listruzione if se la condizione vera, si esegue lazione specificata se la condizione falsa, si esegue lazione specificata dopo
la clausola else (se presente) implementa il blocco IF-THEN-ELSE (o IF-THEN) della
sintassi:
if ( condizione_Booleana )azione_da_fare_se_la_condizione_e_vera
if ( condizione_Booleana )azione_da_fare_se_la_condizione_e_vera
elseazione_da_fare_se_la_condizione_e_falsa
7/24/2019 Dispense linguaggio C
9/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 9
Operatori relazionali
operatori che: effettuano un confront o tra due dati omogenei di tipo
base producono un valore Booleano
operatori: ugua e == diverso ( != ) maggiore ( > ) maggiore o ugu ale ( >= ) minore ( < ) minore o ugu ale ( = 0) printf ("%d e' un numero positivo\n", numero);
else printf ("%d e' un numero negativo\n", numero);
return 0;}
numero.c
Blocchi di istruzioni
un gruppo di istruzioni pu essere racchiuso tra parentesigraffe per costituire un blocco
tipicamente usato quando a seguito del verificarsi di unacondizione (es. if, while) bisogna eseguire pi diunistruzione
esempio:
/* sconto 20% solo se costo maggiore 10 Euro */
if (prezzo > 10){
sconto = prezzo * 0.2; printf ("prezzo finale = %f\n",prezzo-sconto);
}else
printf ("prezzo finale = %f\n",prezzo);
b l o c c o
= o == ?
attenzione alla differenza tra: loperatore di assegnazione ( = ) loperatore relazionale di u guaglianza ( == )
A = 5 sign if icaas seg na a a var a e va o re
ossia memorizza il valore 5 nella cella di memoria chi amata A
A == 5 sig ni ficacalcola il risultato delloperazione Booleana
il valore di A uguale a 5? ossia
la cella di memoria chiamata A contiene il valore 5?
Dati Booleani in C non esiste il ti po dati Boo leano (esiste in C99) per questo scopo si us a qualunque tipo di dato intero con la
convenzione: FALSE se pari a zero TRUE se diverso da zero
Operatori Booleani sono operatori che:
agiscono su dati Booleani generano un valore Booleano
operatori: AND ( &&) OR ( || ) EX-OR ( ^ ) NOT ( ! )
utili per scrivere espressioni Booleane complesse esempio:a && ( b || ( !c ) ) /* a AND (b OR (NOT c)) */
7/24/2019 Dispense linguaggio C
10/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 10
Esempio: bool e
scrivere un programma che: riceva in input i valori d i tre variabili Booleane (a b c) calcoli il valore dellespression e Booleana
a AND ( b OR c )
boole.c
Esercizio: funzione "buc o"
scrivere un programma che: riceva in input il valore dell'ascissa calcoli il valore della funzione cos definita
(se | x | >= 1) y = 2(se | x | < 1) y = x 2 + 1
nota: non si pu fare uso della funzione "valore assoluto"presente nella libreria matematica
Come si visualizza un messaggio di errore?
preferibile mandare i messaggi di errore sulluni t dioutput dedicata agli errori: stderr
si usa la funzione fprintf che ha la stessa sintassi dellafunzione printf ma ha come primo parametro lunit dioutput su cui operare
sintassi:
esempio:fprintf (stderr,
"errore nella lettura dei dati.\n");
int fprintf ( unita ," formato_di_stampa ", variabili );
Perch usare stderr?
se un programma genera molto output in cui sono mischiatidati normali e segnalazioni di errore, diventa difficil e notaregli errori
meglio quindi isolare gli errori su un flusso di outputseparato
in Unix, MS-DOS ed in una finestra di comandi di Windows eMac possibile indirizzare stderr su un fil e (e quindi vedereimmediatamente se e quali errori si s ono verificati) tr amite lasintassi:
prog 2> U
esempio di redirezione completa (stdin, stdout, stderr):
prog.exe risult.txt 2>errori.txt
Come si termina di colpo un programma? si usa la funzione exit che termina lesecuzione del
programma e restituisce il contro llo al sistema operativo la funzione pu ricevere come parametro un codice di uscita
(numero intero) da restituire come info rmazione al sistemaoperativo
per convenzione un codice di u scita pari a zero indica che ilprogramma terminato normalmente, mentre si usa uncodice diverso da zero nel caso di termin azione dovuta adun errore
richiede la dichi arazione #include esempi:
exit(0); /* tutto OK */exit(1); /* errore!!! */
Exit o return? al posto della funzione
exit ( codice_di_uscita )si pu usare listruzione
return codice_di_uscita ; nel main, hanno signific ato equivalente ma spesso si
preferisce exit per la terminazione anomala (es. bug) mentres usa re urn per un erm naz one norma e e programma
nei sottoprog rammi, exit e return hanno effetto moltodiverso e per bu ona programmazione sarebbe sempremeglio usare return e lasciare al chiamante la decisione seterminare il programma o meno
7/24/2019 Dispense linguaggio C
11/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 11
Programmazione difensiva
il test sullo stato inesistente nel programma maiuapic.c un esempio di programmazione difensiva
bisogna sempre cercare di scrivere programmi che: tollerino e segnalino errori di input contro llino anche ci che pu apparire scontato (es.
essere possibili)
Its so hard to make fool-proof programsbecause fools are so ingenious!
Problema: operazioni
Fare un programma che: legga dallinput unoperazioni aritmetica nella forma
operando operazione operandosenza spazi tra gli operandi e loperatore
esegua loperazione richiesta e ne stampi il ris ultato
addizione ( + ) sottrazione ( ) moltipl icazione ( * , x, X ) divisio ne ( / , : ) modulo ( % )
switch
listruzione switch si pu usare in sosti tuzione di unacascata di if ... else quando i test so no tutti : condotti sulla stessa variabile o espressione su numeri interi (o equivalenti, come nel caso di variabili
di tipo enum o caratteri) con condizioni mutuamente esclusive
tramite listruzione case si indicano i valori con cuieffettuare il confronto
tramite listruzione break si esce dallo switch con listruzione default (opzionale ma fortemente
consigl iata) si indic ano le istruzioni da fare quando non si caduti in nessuno dei casi indicati
Sintassi dellistruzione switch
switch ( espressione ){case valore-X :
/* istruzioni nel caso espressione == X */. . .
break;case va ore- :case valore-Z :
/* istruzioni nel caso espressione == Y
oppure espressione == Z */. . . break;
default:/* istruzioni per tutti gli altri casi */. . .
}
Soluzione: o perazioni si leggono i dati (A, OP, B) tramite scanf si esegue loperazione, tramite switc h (oppure cascata di if-
else), e si genera il ris ultato R si presenta il ri sultato (A OP B = R)
op_if.c
op_sw.c
Problema (conteggio c aratteri)Fare un programma che:
legga caratteri finch ce ne sono in input e produca in output il numero di caratteri introdotti
Sottoproblemi: come si legge un carattere? come si capisce quando non vengono pi introdotti
caratteri? come si ripete unazione? come si tiene il conto dei caratteri introdotti?
7/24/2019 Dispense linguaggio C
12/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 12
Come si legge un carattere?
si potrebbe usare scanf con formato %c ma inefficiente si preferisce quindi usare la funzione getchar ( ) quando viene eseguita restituis ce il codi ce ASCII del
carattere fornito in in put, ossia un num ero 0 ... 255 quando il fluss o di dati in input terminato (oppure si
, quindi restit uisce un numero intero: sbagliato (e provoca
errori) memorizzare il risul tato in una variabile di tip o char
prototipo:
int getchar(void);
EOF (End-Of-File)
indica che non ci sono pi dati in input il modo in cui si produc e un EOF dipende da molti fattori esempi:
automaticamente, se si sta leggendo un f ile battere ^Z per indicare EOF in Windows, MS-DOS o VMS battere ^D per indic are EOF in Unix, Li nux, Mac-OS
N.B. il simbol o ^ indi ca di tenere premuto il tasto Contro l(es. CTRL, CNTL) e quindi premere anche il tastocorrisp ondente alla lettera indicata
Come si ripete unazione?
si usa listruzione while se la condizione vera, allora viene svolta lazione e poi s i
ri-verifica se la c ondizione vera per eventualmente rip eterelazione
se la condizione falsa, lazione non verr mai svol ta - - - -
chart della programmazione strutt urata sintassi:
while ( condizione_Booleana )azione_da_ripetere
Come si tiene il conto di una quantit?
si usa una variabile (intera) con funzione di accumulatoreo contatore
la si azzera allinizio la si incrementa come necessario
esemp o:
int tot = 0;
tot++; /* incremento di ununita */
tot += 3; /* incremento di tre unita */
Soluzione (conteggio caratteri)int totc = 0; /* totale caratteri */int xc; /* carattere letto */
xc = getchar();while ( xc != EOF ){
totc++;xc = getchar();
} printf ("Caratteri trovati: %d\n", totc);
Flow-chart (conteggio c aratteri)totc = 0 leggo uncarattere ( xc )
carattere xc
START
F non EOF?
incremento totc
leggo uncarattere ( xc ) STOP
stampo totc
V
7/24/2019 Dispense linguaggio C
13/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 13
Ottimizzazione (conteggio caratteri)
in C si pu sostit uire ad un valore unespressione (traparentesi tonde) che generi tale valore
le parentesi indicano lordine di calcolo poich nel flow-chart precedente entrambi i rami in ing resso
al test svolg ono la stessa operazione (lettura di un carattere)essa pu essere incorpo rata nel test stesso, quindi il c iclowhile della soluzione pu essere cos ottimizzato:
while ( (xc = getchar()) != EOF ){
totc++;}
contaC.c
Pattern lettura di tutti i caratteri in input
Ogni volta che occorre leggere tutti i caratteri in input - uno pervolta - si usa la seguente struttura base:
int xc; /* carattere letto */...
= = {
/*inserire qui le operazioni dasvolgere sul carattere letto (xc)*/...
}...
Problema (copia caratteri da input a output)
Fare un programma (chiamato copiac) che: legga caratteri finch ce ne sono in input e li copi in output
Sottoproblemi: come si produce un carattere in output?
Come si produce un carattere in output?
si potrebbe fare con la direttiv a %c nella funzione prin tf ma inefficiente
meglio usare la funzione putchar ( ) il parametro il carattere che si desidera produrre in outp ut la funzione restituisce EOF in caso di errore
prototipo:
int putchar (int carattere );
Soluzione (copia caratteri)int xc; /* carattere letto */
while ( (xc = getchar()) != EOF ){
putchar(xc);}
copiac.c
Appl icazione del programma copiacIl programma copi ac pu essere usato per vis ualizzare un fil e,per generarlo o per copiarlo su un altro file:
(visualizza) copiac < a.txt (crea) copiac > a.txt (copia) copiac < a.txt > b.txt
Nota 1: questi comandi f unzionano in Unix , in MS-DOS o in unafinestra di co mando di MS-Windows o MacOS.
Nota 2: la visualizzazione e la creazione funzionano meglio s e siopera con un file di t esto (ossia contenente solo caratteri ASCII).
7/24/2019 Dispense linguaggio C
14/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 14
I canali di I/O standard i n C
il linguaggio C ipoti zza luso di un calcolatore virtuale dotatodi tre canali standard di I/O
unit di input standard( stdin )
unit di output standard( stdout )
unit di errore standard( stderr )
programma
Ridirezione dellI/O
in Unix, MS-DOS ed in una finestra di c omando di Windows possibile cambiare le unit standard di I/O a cui unprogramma fa riferimento
prog > Udirige loutput sullunit U se U contiene gi dei dati, essi vengon o cancellati se U non esiste (es. file) allora viene creata
prog < Uprende linput dallunit U
prog >> Uappende loutput (ossia lo aggiun ge in coda) allunit U
Esercizio (conteggio lettera Z)
Fare un prog ramma che conti quante volte comp are in input lalettera Z (maiuscol a).
Riformulazione del probl ema = fare un pr ogramma che: legga caratteri n c c e n e s on o n n pu conti il numero di oc correnze della lettera Z
produca in outp ut il numero di oc correnze della lettera Z
Esercizio (conteggio lettere Z)
Fare un prog ramma che conti quante volte comp are in input lalettera Z (maiuscola o minusco la).
Riformulazione del problema = fare un pro gramma che: legga caratteri n c c e n e s on o n n pu conti il numero di oc correnze delle lettere Z e z
produca in ou tput il numero di oc correnze delle lettere Z e z
Come si ripete unazione? si pu usare listruzione do while (che implementa un
ciclo repeat-until) viene svolta lazione e poi s i verifica se l a condizione vera
per eventualmente ripetere lazione lazione verr svolta almeno una volta - -
programmazione strutturata, avendo per la condizione diuscita invertita
sintassi:
doazione_da_ripetere
while ( condizione_Booleana )
Problema: leggere una ris postaChiedere la risposta ad una domanda e ripetere la domanda sela risposta non ha uno dei valori possibili.
Soluzione (astratta e non st rutturata):1. fare la domanda
. eg ger e a r s po s a3. se la risposta non una di quelle possibili, ripetere da 14. fornire un commento alla risposta
7/24/2019 Dispense linguaggio C
15/49
7/24/2019 Dispense linguaggio C
16/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 16
Algori tmo di Eucl ide per il calcolo del MCD
algoritmo di Euclide per trovare il MCD di due numeri interipositivi A e B: sia A>0, B>0 ed A >= B si effettui la divi sione intera A / B se il resto R della divisio ne nullo, allora B il MCD a r men s app ca nuovamen e proce men o usan o
B come dividendo e R come divisore
Flow-chart dellalgorit mo di Euclide (I)
R = A % B
R == 0 ? MCD = BV
ENTER( A >= B )
A = BB = R
R = A % B
F
EXIT
Flow-chart dellalgorit mo di Euclide (II)
sfruttando la possibilit del C di combinare calcolo di unvalore e suo test
ENTER
R (=A%B) == 0 ?
A = BB = R
MCD = BV
FEXIT
Flow-chart d ellalgoritmo di Euclide (III)
poich il ci clo whil e termina quando la condizione falsa,occorre invertire il test
ENTER
R (=A%B) != 0 ?
A = BB = R
MCD = BF
VEXIT
Codifica dellalgoritmo di Euclide/* verifico ed impongo la condizione base a>=b */if ( a < b ){
tmp = a;a = b;
b = tmp;
/* calcolo il MCD */while ( (r = a % b) != 0){
a = b; b = r;
}/* ecco il risultato */
mcd = b;
Soluzione: MCD si richiede lintro duzione dei dati si leggono da inp ut i due num eri interi X e Y tra cui calcolare
il MCD per rispettare la condizione iniziale dellalgoritmo di Eucl ide
(dividendo >= divisore) si pone: B pari al minor e tra X e Y
si esegue lalgoritmo di Euclide su A e B si scrive il risultato
mcd.c
7/24/2019 Dispense linguaggio C
17/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 17
Problema: tavola dei quadrati (v1)
Stampare la tavola dei quadrati di tutti i numeri int eri positivifino ad un valore massimo introdotto dallutente.
Sottoproblema: come effettuare un ciclo che generi la sequenza degli interi
Come generare tutti gli interi fino a N?
si usa un contatore inizializzato al valore 1 ad ogni iterazione (while) si controlla che sia mino re del
limite al termine di ogni i terazione gli si aggiunge 1
esemp o:
int i, limite;. . .i = 1;while (i
7/24/2019 Dispense linguaggio C
18/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 18
Soluzione: tavola dei quadrati (v1)
richiedo il limite (NMAX) leggo il limite (scanf) e controllo che sia stato inserito e sia
un numero int ero positivo (NMAX) genero tutti g li interi da 1 a NMAX (pattern: sequenza
numerica)
tavquad1.c
Problema: tabella Pitagorica
Calcolare e stampare la tabella Pitagorica (ossia la tabella dellamoltipl icazione tra interi) relativa ai numeri da 1 a N, essendo Nun valore introdotto dallutente.
Soluzione: , per ogni riga R da 1 a N [ pattern: ciclo numerico ]
per ogni col onna C da 1 a N [ pattern: ciclo nu merico ]calcolo P = R * Cstampo P
vado a capo (riga terminata) programma terminato
pitagora.c
Modifica dellesecuzione dei cic li
possibi le modificare il normale flusso di esecuzione di unqualunque ciclo (whi le, do-while, for)
due possibilit: break
termina il cicloesecuz one con nua opo a ne e c c o
continue
termina literazione correnteesecuzione continua con la pross ima iterazione trasformano i cicli in blocchi non strutturati (!)
usare con cautela si pu s empre evitare luso di break/continue ma
talvolta molto comodo usarli
Esempio break/continue (su while)
Fcondizione
Fcondizione
V
struttura
break
V
struttura
continue
Costanti simboliche (const) una costante rappresenta un dato non modi ficabile (ossia
una zona di memoria a sola lettura, protetta in tal senso dalsistema operativo)
utile assegnare un identificatore mnemonico ad unacostante per: ricord are la sua semantica cambiare facilmente il suo valore ovunqu e sia usata
sintassi:const [ tipo ] costante = valore ;
esempi:
const float PiGreco = 3.1415;const int PuntiPerVittoria = 3;
Costanti simbolic he (#define) una costante definita tramite una variabile con attribut o
const: occupa comunq ue una cella di memoria richiede un trasferimento da memori a a registro per i
calcoli (fatte salve possibili ottim izzazioni)
ugualmente un identificatore mnemonico associato ad unvalore costante si pu definire una sostituzion e tramite ilseguente costrutto:
esempio:
#define identificatore valore_costante
#define PiGreco 3.1415#define EOL '\n'
7/24/2019 Dispense linguaggio C
19/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 19
Variabili mult idimensionali
possibile definir e variabili diverse ma correlate che: contengono lo stesso tipo di dati hanno lo stesso nome (base) sono dist inte in base ad un indice numerico (prima,
seconda, terza, , N-esima variabile) ques e var a s c amano ve or e s c arano me en o
dopo il n ome una coppia di parentesi quadre che contiene ladimensione del vettore (=numero totale di variabili diverse)
sintassi:tipo variabile [ dimensione ];
esempio:float punto[3]; // coordinate in 3Dint voto[35]; // voto di ogni studente (max 35)
Accesso agl i elementi di un vettore
non esistono operazioni che si applicano automaticamente atutti gli elementi di un vettore (a meno che sia una stringa)
normalmente si opera sui singoli elementi del vettore per accedere ad un singo lo elemento di un vettore si
specifica il nome del vettore e tra parentesi quadre lindic e dellelemento desiderato
attenzione! gli elementi di un vettore con dimensione N sono
numerati da 0 a N-1 quindi l i-esimo elemento del vettore V si indica con
V [ i 1 ]
Inizializzazione (statica) di un vettore
quando si dic hiara un vettore possibi le assegnare valoriiniziali ai suoi elementi creando una lista racchius a tra parentesi graffe composta di valori separati da virgola
se un vettore viene inizializzato, possibil e non dichiararne,
da poter ospitare tutti i valori sp ecificati (ma nessuno in pi)
esempi:
float x[3] = {1.0, 2.1, 3.2};long y[] = {1, 0, 1, 0};float z[5] = {1.0, 2.1, 3.2}; // z[3]=0, z[4]=0int h[2]; // valori casuali
Lettura di un vettore (dimensione nota)/* lettura vettore di dimensione nota,
dati forniti uno per r iga su stdin */
#define NDIM 3. . .double x[NDIM];. . .for (i=0; i
7/24/2019 Dispense linguaggio C
20/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 20
Stampa di un vettore
si usa un ciclo numerico su tutti gli indici degli elementipresenti
attenzione ai limiti degli i ndici: da ZERO a N-1 esempio:
* stam a vettore contenente NX elementi *
double x[...];int nx; // numero di elementi presenti in x. . .for (i=0; i maxv) maxv = val;
}
Pattern calcolo della media aritmetica
il valore medio la somma di tutti valori diviso il numero divalori
occorre quindi: un accumulatore dove sommare tutti i valori un contatore per contare il numero di valori
double val, totv = 0;int nval = 0;
. . ./* dopo la lettura di un valore (val) ...*/nval++;totv += val;
/* alla fine ... */ printf ("media = %lf\n", totv / nval);
Soluzione: statistiche sui voti si leggono i valori dei voti si applicano i pattern per la ricerca di minimo, massimo e
media osservando che in un vettore il primo valore quello con
indice zero
NOTA: si po ssono fare cicl i separati per calcolare minimo,massimo e media (vstat1.c) oppure fare un unic o ciclo(vstat2.c)
vstat1.c
vstat2.c
La libreria math contiene funzioni matematiche:
esponenziali e logaritmic he trigono metriche (dirette, inverse, iperboliche) miscellanea (valore assolu to, ceiling, )
attenzione: le funzioni trigonometri che (sia dirette sianverse operano su ango espress n ra an
per usarla:
#include
7/24/2019 Dispense linguaggio C
21/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 21
math.h (I)
funzione definizionedouble sin (double x)
double cos (double x)
double tan (double x)
double asin (double x)
double acos (double x)
double atan (double x)
double atan2 (double y, double x) atan ( y / x )
double sinh (double x)
double cosh (double x)
double tanh (double x)
math.h (II)funzione definizione
double pow (double x, double y) xYdouble sqrt (double x) radice quadrata
double log (double x) logaritmo naturale
double log10 (double x) logaritmo decimale
double exp (double x) e X
double ldexp (double m, int esp) m 2 esp
double frexp (double x, int *esp) mantissa =frexp (x, &esponente)
Nota: ldexp crea un nu mero reale date la sua mantissa edesponente, mentre frexp estrae da un numero reale la suamantissa ed esponente
math.h (III)
funzione definizione
double ceil (double x) ceiling(x)
double floor (double x) floor(x)
double fabs (double x) valore assoluto
double fmod (double x, double y) resto di x / y
double modf (
double x, double *ipart)
restituisce frac(x) ememorizza int(x) inipart
testmath.c
Funzioni matematiche in s tdlib.h
funzione definizione
int abs (int n) valore assoluto
long labs (long n) valore assoluto
div_t div (int numer, int denom) quoto e resto delladivisione intera
ldiv_t ldiv (long numer, longdenom)
quoto e resto delladivisione intera
Nota: div_t e ldiv_t sono struct co n due campi (int o long aseconda della funzione us ata):
quot /* quoto */rem /* resto */
Type cast per trasformare temporaneamente un valore da un tip o ad
un altro si pu us are un cast basta premettere alla variabile (o espression e) il tipo
desiderato, tra parentesi tonde esempio: (double) n
funzioni matematiche esempio:
int n;double x;. . .x = sqrt ( (double) n );
EsercizioScrivere un programma che richi eda allutente il valore di u nangolo (espresso in gradi, come numero in tero) e ne calcoliseno, coseno e tangente.
Nota: se G un angolo espresso i n gradi e R il suo valore inradianti, allora vale la relazione
G : 180 = R :ossia
R = G * / 180G = R * 180 /
trigo.c
7/24/2019 Dispense linguaggio C
22/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 22
Pattern calcolo della media geometrica
la media geometrica la radice N-esima del prod otto degli Nvalori
occorre quindi: un accumulatore dove moltiplicare tutti i valori un contatore per contare il numero di valori
double val, totv = 1;int nval = 0;. . ./* dopo la lettura di un valore ...*/nval++;totv *= val;
/* alla fine ... */ printf ("media = %lf\n",pow(totv,1.0/nval);
Verifica di pro priet su un ins ieme di dati
universalit vero che tutti i dati verificano la propriet P? x : P(x) = true
esistenza vero che almeno un dato verifica la proprietP? x : P(x) = true
nes s en za v ero c e n es su n a o ver c a a p ro pr e x : P(x) = false
non universalit vero che almeno un dato non verific a lapropriet P? x : P(x) = false
Verifica di pr opriet su un ins ieme di dati
per semplicit faremo gli esempi: su un vettore v[N] ipotizzando che la prop riet cercata sia rappresentata
dalla funzione P(x) che restituisce 0 se la prop riet non soddis fatta, 1 in caso contrario
,quando si voglion o trattare dati Booleani senza far ricorso altipo _Bool, ossia per definire una variabile di tipo FLAG utile
per tenere traccia se un certo evento o condizione si verificata o meno:
#define BOOLEAN int#define FALSE 0#define TRUE (!FALSE)
Verifica di universalit
si contro lla se tutti gli elementi soddisfano la propri et P
BOOLEAN ok = TRUE; /* ipotesi: tutto OK */. . .for (i=0; i
7/24/2019 Dispense linguaggio C
23/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 23
Sottoprogrammi, procedure e funzioni
sottoprogramma (subroutin e) = insieme di istruzioni a cui viene assegnato un identific atore definite una sola volta usabili varie volte
funzione (function) = sottoprogramma che restituiscere amen e un r su a o
procedura (procedure) = sottoprogramma che nonrestituisce direttamente un risultato
in C esistono solo le funzioni; l e procedure si realizzano conuna funzione che restituisce un risultato di tipo void
Funzioni (definite dallutente)
si deve definire: il nome della funzione il risultato (tipo) i parametri forniti alla funzione (tipo e nome) le istruzioni che la compongono
sintassi:
[ tipo ] nome_funzione ( [ parametri_formali ] ){
/* istruzioni */. . .return [ valore ] ;
}
Note sulle funzioni se una funzione non h a parametri, si usa mettere void tra le
parentesi tonde per indicarlo se una funzione non restituisce esplicitamente alcun
risultato (ossia una proc edura) allora: lo si indica col tipo void si usa return senza alcun valore si pu anche non usare return (la procedura termina
quando finiscono le sue istruzioni)
il main un a particolare funzione: quella che viene attivataper prima alla partenza del programma nel main si pu us are indifferentemente return o exit( ) nelle funzioni:
return termina solo la funzione exit( ) termina tutto i l programma
Posizionamento delle funzioni
per semplicit, le funzioni sono definite prima delle parti diprogramma che le usano
in particolare normalmente tutte le funzioni sono definiteprima del main( )
nota : il main() stesso una funzione
int f1 (int x, int y){
/* istruzioni della funzione */}
int main(){/* istruzioni del main */}
Esempio di funzione: volume di un cilindr oDdefinire una funzione che calcoli il vol ume di un cilin dro dato ilraggio d ella base e laltezza.Usare quindi tale funzione per un programma che chieda raggioed altezza di un cili ndro e calcoli il volume.
volcil.c
Problema: tri angolo rettangoloDisegnare in output u n triangolo rettangolo c on cateti uguali eparalleli ai bordi dello schermo:
disegnato tramite un carattere passato come primoparametro sulla linea di comando
con lungh ezza del cateto indicata da un numero interopassato come secondo parametro sulla linea di comando
esempio
C:\> trett1 * 5***************
7/24/2019 Dispense linguaggio C
24/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 24
Come dis egnare una figura geometrica?
procedere riga per riga; occorr e quindi : calcolare quante righe occorrono procedere col pattern d ella sequenza numerica (prima
riga, seconda riga, ) per ogni riga stampare i caratteri che occorrono:
proce ere co pa ern e a sequenza numer ca pr mocarattere, secondo carattere, )
Triangolo rettangolo (soluzione 1)
control lare che il numero di parametri sia corretto acquisire dagli argomenti:
il carattere da usare per la stampa (CS) la lunghezza del cateto (LCATETO)
control lare che la dimensione del triangolo sia compatibil econ que a e spos vo ou pu v eo n mo atesto t ipicamente 24x80)
(per la stampa si noti che la prima riga deve contenere unsolo carattere, la seconda riga due caratteri e cos via)
generare LCATETO righe e per ogni riga RIGA stampare RIGA volt e il c arattere CS andare a capo
trett1.c
Triangolo rettangolo (soluzione 2)
per chiarezza (e per poterla riutili zzare in altri pr ogrammi)pu essere utile defini re ed usare una funzione chedisegna una riga con un determinato carattere
void riga_piena (int lriga, char x){
n nco ;
for (ncol=1; ncol qpieno 5 *********************
qpieno2.c
qpieno.c
7/24/2019 Dispense linguaggio C
25/49
7/24/2019 Dispense linguaggio C
26/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 26
Passaggio dei parametri by reference
se il risultato di una funzion e: uno solo un dato semplice
allora possib ile restituirlo tramite return( ) se invece:
i risultati sono tanti e/o sono dati strutturati i parametri sono dati strutturati
allora necessario agire direttamente sui parametripassando alla funzione non il valore ma un riferimento :
lindirizzo di memoria
Indirizzo di memoria
loperatore & premesso al nome di una variabile permette diconoscere l indirizzo di memoria in cui conservata talevariabile
eccezione: nel caso di variabili struttu rate (es. vettori) usando il
nome della variabile si ha automaticamente leffetto diprenderne lindirizzo
quindi superfluo (ma non sbagliato) usare & in fronte diuna variabile strutturata
se si vuole memorizzare un indirizzo di memoria, occorredichiarare una variabile di tipo puntatore a memoria , ossia ilcui nome sia preceduto dal simbolo *
Esempio indirizzi di memoria
#include
void main(){
char alfa = 'a';char *aptr = &alfa;
printf ("alfa = mem(%x) = '%c'\n",&alfa,alfa); printf ("aptr = mem(%x) = %x\n", &aptr,aptr);
*aptr = 'b';
printf ("alfa = mem(%x) = '%c'\n",&alfa,alfa); printf ("aptr = mem(%x) = %x\n",&aptr,aptr);
}
eptr.c
Esempio 3 parametri by reference
void raddoppia (int *x){
*x = (*x) + (*x);}
{
int a = 5;
printf ("a = %d\n", a);raddoppia(&a);
printf ("a = %d\n", a);}
radd3.c
Esercizio: radtri scrivere una funzione RADTRI che:
riceve in input un valore intero X fornisca in output il doppio ed il triplo del valore X
radtri.c
Esercizio - conta cifreFare un prog ramma che conti (e presenti in outpu t) quante voltecompaiono in in put delle cifre (ossia dei caratteri numerici).
7/24/2019 Dispense linguaggio C
27/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 27
La libreria ctype
contiene funzioni per: classific are i caratteri (es. maiuscolo ? minuscol o?
una cifra?) fornendo una risposta Booleana convertire caratteri da maiuscolo a minuscolo
per usar a:
#include
ctype.h (I)
funzione definizioneint isalpha(int c); a..z A..Z
int isdigit(int c); 0..9
int isalnum(int c); 0..9 a..z A..Z
int isxdigit(int c); 0..9 a..f A..F
int iscntrl(int c); DEL '\0'...'\37'
int isprint(int c); carattere stampabile
int isgraph(int c); isprint isspace
int isspace(int c); SP HT CR LF VT FF
int ispunct(int c); isprint isspace - isalnum
ctype.h (II)
funzione definizione
int islower(int c); a...z
int isupper(int c); A...Z
int tolower(int c); A...Z -> a...z
int toupper(int c); a...z -> A...Z
nota: le funzioni tolow er e toupper restitui scono il carattereinalterato se non uno di qu elli da trasformare.
Conteggio lettere Z: soluzione n.4
In relazione al problema gi visto d i contare quante voltecompare la lettera Z (maiuscola o minu scola) si pu ora usare lafunzione tolower( ) oppure toupper( ) per convertire ilcarattere letto e quindi effettuare un solo test:
if ( tolower(xc) == 'z' )
contaZz4.c
if ( toupper(xc) == 'Z' )nZ++;
Esercizi contare (separatamente) quante virgole, quanti punti, quanti
due-punti e quanti punto-e-virgola compaiono in input
[ contaCnoEOL ] contare quanti caratteri sono forniti ininput, escludendo dal conteggio i terminatori di linea
[ contaOper ] definire una funzione
int isoper (int c)
che restituisce vero o falso se il carattere ricevuto unoperatore aritmetico ( + - * / ); usare poi tale funzioneper scrivereun programma che conti quante operazionisono presenti in input.
Esercizio - vocaliFare un prog ramma che legga tutti i caratteri in in put e dicaquante vocali sono presenti.Nota: si desidera minimizzare il numero di test effettuati.
7/24/2019 Dispense linguaggio C
28/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 28
Esercizi - no vocali / consonanti
Fare un programma (chiamato novoc ) che copi tutto linputsulloutput, tranne le vocali.
Fare un programma (chiamato nocon) che copi tutto linputsulloutput, tranne le consonanti.
Esercizio - conta righe
Fare un progr amma che conti il n umero di righe forni te in input.
contaR.c
Problema: valor medio d i tre nu meri
Vengono fornite in input r ighe che contengono tre numeri reali(qui indi cati con N1, N2 e N3).Fornire in output ri ghe che contengano il valor medio dellacorris pondente riga di input, nel seguente formato:
media (N1, N2, N3) = valore_della_media ,
terminare il pro gramma, a meno che la riga sia comp letamentevuota (nel qual caso si deve generare una riga vuot a anche in
output e proseguire).
Sottoproblema: come si leggono numeri da input? come ci si accor ge che una riga vuota?
Valor medio di tre numeri pseudo-codice
leggere una rigawhile ( riga letta con successo ){
if ( riga vuota )stdout
7/24/2019 Dispense linguaggio C
29/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 29
Come si legge una riga di caratteri da input?
si usa la funzione gets la funzione legge caratteri dallunit di input s tandard
sino a quando in contra il termin e della riga (\n) e memorizza i caratteri in una str inga (detta buf fer ),
passata come parametro alla funzione no a: ge s egge cara ere n ma o nser sce ne a
stringa la funzione ritorna la costante predefinita NULL in caso di
errore o fi ne dei dati (EOF)
prototipo:
char *gets ( char * buffer )
Stringhe di caratteri
una st ringa di caratteri una sequenza di caratteriterminata dal carattere NUL ossia '\0'
una variabile di tipo stringa si crea dichiarando il tip o base(char) e tra parentesi quadrate la quantit massima dicaratteri che potr contenere
attenzione a lasciare sempre una spazio disp onibile per ilterminatore
si pu om ettere la dimensione solo se si inizializza la stringacon una costante
esempi:char x[32]; /* stringa
7/24/2019 Dispense linguaggio C
30/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 30
Lettura di tutto lin put: getchar o gets?
quando il probl ema richiede di leggere tutti i dati da input, sipotrebbe indifferentemente usare il pattern con getchar oquello con gets
conviene per scegliere il pattern con l a funzione orientataal tipo di calcolo che si deve poi comp iere sui dati letti dainput: se si deve operare su singoli c aratteri (es. metterli tutti i n
maiuscolo) allora conviene operare con getchar se si deve operare su righe o strin ghe o estrarre dei dati
(es. lettura di dati numeric i) allora conviene operare congets, seguita dallopportuna sscanf
attenzione: luso di gets (o fgets) presuppo ne di poterdefinire una lunghezza massima delle righe di inp ut
Come si estraggono dati da una string a?
si usa la funzione sscanf la funzione esamina la stringa cercando di identifi care e
convertire i dati specificati nella direttiva di conversione i dati letti vengono memorizzati nelle variabili in dicate come
parametri
successo
prototipo:int sscanf ( stringa_dati ,
" direttive_di_conversione ",indirizzi_delle_variabili );
Soluzione: valor medio d i tre nu meri
finch ci sono righe in input (gets, buf) se la riga vuota
si stampa una riga vuota in output altrimenti
tento di estrarre tre numeri dalla riga (sscanf)se lestrazione ha avuto su ccesso
si calcola e si stampa la media dei tre numeri
altrimentisi segnala erroresi termina il programma
media3n.c
Esercizi
scrivere un programma che riceva in input tre numeri perriga e scriva in output il t otale di ciascuna colonna; righeerrate devono essere scartate, indicandone il numero di r iga
scrivere un programma che riceva in input un num ero perriga ed effettui la somma solo dei num eri positivi; r ighe cheiniziano col punto esclamativo ( ! ) sono dei commenti edevono essere scartate silenziosamente
sumpos.ctot3col.c
Esercizi [ oper2n ] scri vere un programma che legga due numeri
interi (sulla stessa riga) e calcoli il ris ultato delle quattrooperazioni aritmetiche su questi due operandi
scrivere un prog ramma che legga una riga contenente unnumero intero e lo pr esenti in output aumentato del 20%
[ tot3fil ] scr ivere un programma che riceva in input righecontenenti il codice di un fi liale (13) seguito senza spazidal ricavo di quella filiale e presenti in outp ut il totale deiricavi di ci ascuna filiale (righe errate sono scartatesilenziosamente)
tot3fil.c
Soluzione (oper2n.c)leggere una rigaif ( riga non letta )
return 0;
estrarre dalla riga i due numeri (a, b)if ( numeri estratti con successo )
s tdout
7/24/2019 Dispense linguaggio C
31/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 31
La libreria string
contiene funzioni per la manipol azione di: string he (= vettori di caratteri terminati da \0 ) aree di memoria (= vettori di byte)
il tipo size_t che compare nelle dichi arazioni delle suefunzioni assimilabil e ad in t
per usar a:
#include
string.h (I)
funzione definizioneint strlen (char *s) lunghezza(escluso \0)
char *strchr (char *s, int c) cerca il carattere cpartendo dallinizio
char *strrchr (char *s, int c) cerca cara ere cpartendo dalla fine
char *strstr (char *s1, char *s2)
cerca la sottostringas2 allinterno di s1
int strcmp (char *s1, char *s2) confronto alfabetico
int strncmp (char *s1, char *s2,size_t maxl)
confronto alfabeticolimitato al massimo amaxl caratteri
string.h (II)
funzione definizione
char *strcat (char *dst, char *src)
concatena (=append) srca dst
char *strncat ( concatena (=append) src , ,
size_t maxl)
caratteri
char *strcpy (char *dst, char *src) copia src in dst
char *strncpy (char *dst, char *src,size_t maxl)
copia src in dstlimitandosi a maxlcaratteri
string.h - note
le funzioni di ricerca restituiscono: il punt atore alla prima occor renza del carattere (o
sottost ringa) se stato trovato NULL se il carattere (o sottostr inga) non presente nella
stringa
( 0 ) se le stringh e sono uguali ( >0 ) se la prima stringa maggiore della seconda,
ossia viene dopo nellordin e alfabetico ( 5
strcat (alfa, beta)--> alfa = "superpippo" beta ="pippo"strncat (alfa, beta, 8)--> alfa = "superpip" beta = "pippo"
strcpy (alfa, beta)--> alfa = "pippo" beta = "pippo"strncpy (alfa, beta, 3)--> alfa = "pip" beta = "pippo"
La libreria string esempi fare un programma che stampi in output il nu mero di
caratteri di cui composta la parola scritta come primoparametro sulla linea di comando
estrlen.c
fare un programma che: legga dalla riga di com ando due parole e (opzionalmente)
un numero massimo di c aratteri su cui effettuare ilconfronto
dica se le parole sono uguali o di verse se le parole sono diverse, le stampi in output i n ordine
alfabetico crescenteestrcmp.c
7/24/2019 Dispense linguaggio C
32/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 32
Esercizio: cambio f ormato data
Si scriva un programma che riceva in input rif erimenti temporali(anno, mese, giorno, or e, minuti e secondi ) nella forma:
AAA AMMGGhhmmsse generi in output riferimenti del tipo
hh:mm:s s GG/MM/AAAAg n r g a n pu co n en e u n u n c o r er m en o em po ra e.
Il programma non deve terminare in caso di error e masegnalarlo in output.
Esempio: 20110513111234 >>> 11:23:34 13/05/2011
Soluzioni: cambio formato data
cdata1.c = schema base, con lettura di n umeri interi cdata2.c = (cdata1) + miglioramento del fo rmato di o utput
(dimensione fissa dei campi) cdata3.c = schema base, con lettura di stringh e invece che
numeri interi =.
(riempimento con zeri) note:
la soluzione migliore quella fornita dal programmacdata3.c perch ricopia in output esattamente i varicampi come sono presenti in input ma ha problemicon input errati
se per fossero da cont rollare i valori dei vari c ampi (es.mese = 112) allora sarebbe da p referire la so luzionecdata4 cdata3.ccdata1.c cdata2.c
Compilazione c ondizionale
le direttive #ifdef e #ifndef permettono di condi zionare lacompilazione di una parte di prog ramma alla circostanza chesia stata fatta o meno un a certa definizione ( #define )
la parte di programma compil ata condizionalmente tuttaquella compresa sino alla direttiva #endif
esempio (per evitare errori dovut i a doppia definizione):
#ifndef FALSE#define FALSE 0#define TRUE (!FALSE)#define BOOLEAN int#endinf
Pattern: i flag
un flag una variabile Booleana che viene usata daiprogrammatori per ri cordare se si verificata unadeterminata condizione
occorre: definirla
lipotesi base) cambiarne il valore quando si verifica la condizione
cercata eventualmente ri-inizializzarla quando si ric omincia il
lavoro
Problema: pigrecoCalcolare e visualizzare il valore di con 9 cifre dopo la virgol a.
Sottoproblemi: come calcolare il valore di ? come richiedere una certa dimensione del formato di
ou pu
Come calcolare il valore di ? si pu sf ruttare una relazione trigonometrica inversa,
sfruttando l a rappresentazione degli angoli in radianti ad esempio:
tan( /4) = 1 e quindi = 4* atan(1)
7/24/2019 Dispense linguaggio C
33/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 33
Direttive di conversione in prin tf
sintassi delle direttive:% [ flag ] [ ampiezza ] [ .precisione ] [ size ] tipo
ampiezza: minima dimension e del campo di stampa
precisione: (per float/double) numero di c ifre frazionarie da stampare (per stringhe) massimo numero di caratteri da stampare
size: h (short int), l (long int), L (long double)
Direttive di conversione in pri ntf
flag: indicati in tabella possibile combinare pi flag
flag funzione
-
+ per dati numerici, premettere sempre il segno(default: segno solo ai numeri negativi)
ai numeri positivi premettere sempre uno spazio
# per numeri ottali/esadecimali, premettere 0 / 0x
# per numeri frazionari, inserire sempre la parte frazionarieanche se nulla
0 fare padding con 0 (zero) invece che con spazi
Direttive di conversione in prin tf
t ipo v ariab ile
i d (intero) formato decimale, con segno
u (intero) formato decimale, senza segno
o (intero) formato ottale
intero formato esadecimale con letterealfabetichex ,minuscole / maiuscole
c (carattere) formato ASCII
s (string a) sequenza di caratteri ASCIIf (reali) formato frazionario decimale
e E (reali) formato frazionario esponenziale, con e / E
g G (reali) formato frazionario pi corto tra f ed e/E
Soluzione: p igreco
calcolo il valore di pigreco, tramite atan(1) stampo il valore di pigreco con 9 cifre decimali tramite
unopportuno formato in printf
pigreco.c
Problema: equazione di II gradoSi scriva un pro gramma per trovare le radici di un equazione disecondo grado, considerando tutti i casi possibili.
A x 2 + B x + C = 0
Soluzione: equazione di II grado siano A, B e C i coefficienti se A nullo (equazione di primo grado):
se B nullose C nullo, equazione indeterminataaltrimenti, equazione impossib ie
altrimenti X = C / B altrimenti, se il discr iminante D :
(nullo) radici reali coincidentiX1 = X2 = B / 2 A
(positivo) radici reali distinteX1 , X2 = ( B + / sqrt(D) ) / 2 A
(negativo) radici comp lesse coniugateRe = B / 2 A Im = sqr t(-D) / 2 A
eq2g.c
7/24/2019 Dispense linguaggio C
34/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 34
Dichiarazione di variabili dentro ai blo cchi
in C possibile dichiarare variabili e costanti non solo intesta al programma ma anche allint erno di un blo cco (=qualunque sequenza di istruzioni racchius a tra parentesigraffe)
NOTA (vita delle variabili ): le variabili dichiarate dentro ad unblocco: vengono create (=la memoria viene occupata) quando
si inizia lesecuzione del blocco sono accessibili solo allinterno del blocco vengono distrut te (=la memoria viene liberata) quando
termina lesecuzione del blocco
Esercizio: tavola numerica (v1)
Stampare la tavola dei quadrati, cubi, radici quadrate e radicicubiche di tutti i numeri interi positivi fino ad un valore massimointrodo tto dallutente (non superiore a 1000).La stampa deve essere ben incolonnata.I numeri frazionari devono essere stampati con 6 cifre nellaparte frazionaria.
tavnum1.c
Problema: tavola dei quadrati (v2)
Si vuole produrre in outpu t la tavola dei quadrati di tutt i i numericompresi tra 1 e N, ove N un numero in dicato sull a riga dicomando (ossia subito dop o il nome del programma).
Sottoproblemi:
Come leggere dati dalla riga di comando?
si usano le variabili argc e argv per usarle devono essere dichi arate come parametri del
main argc indica il numero di str inghe presenti sulla linea di
comando, incluso il nome del programma
argv[0] il nome del programma argv[ n ] la stringa n-esima dopo il nome del programma
sintassi:
int main (int argc, char *argv[])
args.ctest2arg.c
Soluzione: tavola dei quadrati (v2) control lo che ci siano due argomenti sulla linea di comando
(argc) leggo il primo parametro ( sscanf, argv[1] ), control lo che sia
un numero i ntero e lo m emorizzo (IMAX) genero tutti g li interi sino a IMAX (pattern: sequenza
numerica) per ogni intero I scrivo il suo quadrato I*I
tavquad2.c
Esercizi(r4.c) Scrivere un programma che calcoli l a radice quarta di unnumero (floating-point) passato sulla riga di comando.
(r4s.c) Scrivere un pr ogramma che calcoli la radice quarta ditutti i numeri (floating-point) passati sulla riga di comando.
Scrivere un programma che calcoli la somma di due numeri(floating-point) passati come argomenti sulla riga di comando.
Scrivere un programma che riceva sulla riga di c omando duenumeri (floating-poin t) ed unoperazione (+ o ) e calcoli i lrisultato delloperazione.
7/24/2019 Dispense linguaggio C
35/49
7/24/2019 Dispense linguaggio C
36/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 36
Pattern: apertura di un file in l ettura
si usa una fopen con parametro read se la rispost a NULL si segnala errore
FILE *afh;char fname[] = "prova.txt";. . .a = o pen name, "r" ;if (afh == NULL){
fprintf (stderr, "errore non riesco adaprire il file '%s' in lettura\n", fname);
exit (1);}. . ./* faccio accesso al file afh */. . .
Chiusura di un file
si usa la funzione fclose che ha come parametri: la handle del file da chiudere
la funzione restituisce: zero se loperazione riusci ta un numero di verso da zero se la chiusura fallita
sintassi:
int fclose ( FILE * file_handle )
Pattern: chiusura di un f ile
si usa una fclose se la risposta non zero, si emette un warni ng
FILE *afh;char fname[] = "prova.txt";. . .
c ose a ={
fprintf (stderr,
"avviso chiusura del file '%s' non riuscita\n",fname);}
Lettura di caratteri da un f ile
si usa la funzione fgetc che ha come parametri: la handle del file su cui op erare
la funzione restituisce: il carattere letto, se loperazione riusci ta EOF se c stato error e o si arrivati alla fine del file
sintassi:
int fgetc ( FILE * file_handle )
Scrittura di caratteri su un file si usa la funzione fputc che ha come parametri:
il carattere da scrivere la handle del file su cui op erare
la funzione restituisce: il carattere scritto, se lop erazione riuscita EOF se c stato errore
sintassi:
int fputc ( int c , FILE * file_handle )
Lettura di una stri nga (riga) da un fil e si usa la funzione fgets che ha come parametri:
la stringa (buf) ove memor izzare i dati letti la dimensione massima della stringa (max), di solito pari
alla lunghezza del buffer la handle del file su cui op erare
a u n z o n e m em or zza n e u er a m as s m o m ax - c ar a erletti (incluso il termin atore di riga) ed aggiunge quindi ilterminatore di stringa
la funzione restituisce: NULL se c stato errore o si arrivati alla fine del file
(EOF) sintassi:
char *fgets (char * buf , int max , FILE * file_handle )
7/24/2019 Dispense linguaggio C
37/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 37
Nota: uso di f gets su stdin
si noti che la funzione gets non contr olla che la dimensionedel buffer sia suffi ciente a contenere tutti i caratteri letti
questo contro llo viene invece fatto dalla fgets pu qui ndi essere utile usare la fgets (invece della gets)
anche per la lettura di righe da input i nvece che da file notare che stdin, a differenza delle altre variabili di ti po
FILE*, non necessita di essere aperto e chiusoesplicitamente
Scrittura di stringh e (righe) su file
si usa la funzione fputs che ha come parametri: la stringa (buffer) contenente i dati da scrivere la handle del file su cui op erare
in caso di error e restituisce EOF attenzione: fputs( ) non mette automaticamente il ritorno a
capo, come nvece a pu s si pu inserire \n al fondo della stringa oppure fare fputs ( buf,afh ) + fputc( \n, afh )
sintassi:
int fputs (char * buffer , FILE * file_handle )
Scrittura di dati su un file
si usa la funzione fprintf che ha la stessa sintassi efunzionalit della printf ma come pri mo parametro ha lahandle del file su cui op erare
la funzione restituisce: EOF se c stato errore
sintassi:
int fprintf (FILE * file_handle , formato , variabili )
Copia file in maiuscolo (soluzione)
control lare il numero di argomenti (argc == 3?) aprire il primo f ile (A) in lettura (argv[1], fopen) aprire il secondo fil e (B) in scrittura (argv[2], fopen) finch ci sono caratteri nel file A
leggere un carattere (fgetc, XC) dal file A scrivere il carattere (fputc, XC) sul file B dopo averlo
trasformato in maiusc olo (se necessario)
chiudere il file A chiudere il file B
maiuf.c
EserciziNATALEFare un progr amma che aggiunga la riga Buon Natale! in co daad un file il cui nome specificato come primo parametro sull ariga di comando
Fare un prog ramma che aggiunga in coda ad un file (il cui nome specificato come primo parametro sulla riga di comando) unariga contenente la stringa passata come secondo parametrosulla linea di comando
Esercizio: copia N rig heScrivere un programma che:
copi le prime N righe da un fi le ad un altro il numero N di righe da copiare specificato come primo
parametro sulla linea di comando i nomi dei due file su cui operare sono passati come
emetta un avviso nel caso che siano state copiate meno di Nrighe (a causa di un errore o per mancanza di dati nel file diinput)
7/24/2019 Dispense linguaggio C
38/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 38
Copia N righe (soluzione 1)
control lo che ci siano 3 parametri ( argc == 4 ) control lo che argv[1] sia un numero intero e lo leggo (N) apro il pr imo fil e ( argv[2] ) in lettura (AFH) apro il secondo fi le ( argv[3] ) in scrittur a (BFH) (contatore) righe_copiate = 0 finch (ci son o righ e nel file A) e (righe_copiate < N)
leggo una riga (BUF) dal file A scrivo la riga sul file B righe_copiate++
chiudo i fi le A e B se (righe_copiate < N) segnalo lerrore
copiaN1.c
Copia N righe (soluzione 2)
la soluzione 1 non funziona correttamente quando una riga pi lunga di MAXBC
una soluzione miglio re quella che copia i caratteriindividu almente, in modo da non porre li miti alla lunghezzamassima di una riga
conviene quindi s crivere una funzione copia_riga che: _ copia caratteri dal fil e F1 al file F2 si arresta dopo aver copiato il carattere \n si arresta anche nel caso di EOF ritorna 0 in caso di co pia terminata a fine riga, EOF se ha
letto EOF
copiaN2.c
Esercizi (totali)
TOT1DFare un progr amma che sommi tutti i numeri int eri presenti (unoper riga) nel file specificato come primo argomento sulla riga dicomando e presenti il totale in output.
Fare un progr amma che sommi per colonne tutti i num eri interipresenti (tre per riga) nel file specificato come prim o argomentosulla riga di comando e presenti in output il totale di ciascunacolonna.Il programma deve segnalare le righe con meno di tre dati e nonconsid erarle nel calcolo del tot ale.
Esercizi (concatenazione di file)
CONCATENAZIONE DI FILE (v1)Fare un prog ramma che legga il file A ed il file B (secondo eterzo parametro sulla riga di comando) e metta il loro c ontenutouno in co da allaltro nel file DEST (primo parametro sulla riga dicomando).Nota: se il fil e DEST contiene gi dei dati, questi devono esserecancellati.
CONCATENAZIONE DI FILE (v2)Fare un programma che legga tutti i file A, B, C, (cheoccupano il secondo , terzo, quarto, posto sul la riga dicomando) e metta il loro co ntenuto uno in co da allaltro nel fileDEST (primo parametro sulla rig a di comando)
Esercizio un file contiene su ogni riga i voti di quattro studenti
(quattro numeri interi s eparati da uno spazio), una riga perogni giorno di scuola
il nome del file specificato come primo parametro sullalinea di comando
il programma deve produrre in output il voto mediogiornaliero di ciascuno dei quattro studenti
loutpu t deve essere scritto nel file il cui no me passatocome secondo parametro sulla linea di com ando
Esercizio scrivere un prog ramma che legga un file di caratteri (il cui
nome passato come primo argom ento sulla riga dicomando) e calcoli la dimensione della sua riga pi lu nga edindichi il numero dordine di tale riga
nota: svilupp are la soluzione nei due casi (A) che non sianota a priori la massima lunghezza di una riga e (B)po zzan o c e nessuna r ga s a p unga cara er .
7/24/2019 Dispense linguaggio C
39/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 39
Ricerca caratteri
Fare un programma che: dato un file specificato come primo p arametro sulla linea di
comando dato un carattere specificato come secondo p arametro sulla
linea di comando
dato stampi il numero di ri ghe che contengono il carattere dato
Si assuma che ogni riga del file non sia lunga pi di 132caratteri.
Ricerca caratteri soluzione
control lo dei parametri ( argc==3, strlen(argv[2])==1 ) apertura del fil e (fopen(argv[1])) lettura di tutte le rig he del file (while + fgets) per ogni riga, se essa contiene il carattere dato
( strchr ( buf, argv[2][0] ) != NULL ): s ampare a r ga pr n incrementare un con tatore (NR)
alla fine, stampare il valore del contatore (NR)
csearch.c
Ricerca caratteri con opzioni
Fare un programma che: dato un file specificato come penultim o parametro sulla
linea di comando dato un carattere specificato come ultimo parametro sulla
linea di comando se il primo parametro -v il programma deve anche
visualizzare tutte le righe del fil e che contengono il c aratteredato
Si assuma che ogni riga del file non sia lunga pi di 132caratteri.Esempi di uso:
csearch2 W dati.txt csearch2 v W dati.txt csearch2.c
Esercizio quotazioni di borsa
Fare un programma che: legga da un file (il cui nome fornito c ome primo parametro
sulla linea di comando) le quotazioni in euro di un n umeroimprecisato di azioni (massimo: 100 azioni) una per riga
fornisc a in output la quotazione delle azioni il cui numerodordine fornito in input
azioni.c
Lavorare su vettori o su file?Quando dei dati si trovano in un file ha senso caricarli in unvettore se e solo se:
sono in quantit nota o limitata a priori (altrimenti non siriesce a dimensionare il vettore)
devo usarli pi di una volta (altrimenti si perde temporispetto a lavorare direttamente sul file)
Esempi (varianti del pr oblema delle azioni): fornire il valor e dellazione il cui indice passato come
secondo parametro sulla riga di c omando [ azioni1.c ] non noto il numero massim o di azioni presenti nel file
Problema conversione del meseScrivere un programma che riceva in inpu t date nella formanumerica
GG.MM.AAAAe le trasformi in output n el formato alfabetico
GG nome-del-mese AAA A o me n om e m es s ev on o u sar e enn a o , e r a o ,
Marzo,
7/24/2019 Dispense linguaggio C
40/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 40
Conversione del mese - soluzione facile
int g, m, a;
char mese[64];
gets (buf);sscanf (buf, "%d.%d.%d", &g, &m, &a);switch (m)
case 1: strcpy (mese, "Gennaio"); break;case 2: strcpy (mese, "Febbraio"); break;...case 12: strcpy (mese, "Dicembre"); break;default: strcpy (mese, "(mese sconosciuto)");}
printf ("%d %s %d\n", g, mese, a);
Tabella dei mesi
Pu essere utile scrivere una funzion e che: riceva come parametro di input il numero di un mese restituisc a una stringa col nome del mese
Tabella dei mesi
char *nome_mese (const int n_mese){
static char *mtab[] = {"(mese inesistente)","Gennaio","Febbraio",. . ."Dicembre"};
if (n_mese > 0 && n_mese < 13)return mtab[n_mese];
elsereturn mtab[0];
}
Static?
normalmente le variabili vengono: create ed inizializzate quando inizia l esecuzione del
blocco che le definisce cancellate e distrutte quando termina lesecuzione del
blocco che le definisce
create ed inizializzate quando inizia l esecuzione delprogramma
cancellate e distrutte quando termina lesecuzione delprogramma
se sono definite allinterno di una funzione, mantengonoil loro valore anche tra chiamate diverse della funzione
Tabella dei mesi(con calcolo automatico della dimensione)
char *nome_mese (const int n_mese){
static char *mtab[] = {"(mese inesistente)","Gennaio","Febbraio",. . ."Dicembre"};
static int max_mtab =sizeof(mtab) / sizeof(mtab[0]);
if (n_mese > 0 && n_mese < max_mtab)return mtab[n_mese];
elsereturn mtab[0];
}
sizeof( ) la funzione sizeof restituis ce il numero di byte occupati in
memoria da una variabile pu ric evere come parametro:
il nome di una variabile il nome di un tipo di dati
esizeof.c
7/24/2019 Dispense linguaggio C
41/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 41
Conversione del mese soluzione
leggere tutte le righe in input (wh ile + gets) per ogni riga:
leggere la data control landone il formato (sscanf) stampare la data in output dop o aver convertito il mese
tramite la fun zione nome_mese( )
cmese.c
Pattern: da numero a dato
Lesempio della tabella per la conversion e da numero a nomedel mese tipico d i tutti i p roblemi dove bisog na accedere ad undato (in questo caso una stri nga alfabetica) partendo da unnumero (un indic e).In generale, per risolvere questi probl emi:
si crea un vettore, con tipo base pari al tipo dei dati damemorizzare
si inizializza il vettore coi dati direttamente in modo statico se i dati sono not i a priori oppure din amicamente (ad esempio leggendo i dati da
file)
Problema ricavo totale
Nel file PREZZI.TXT sono indicati i prezzi in Euro di ventiprodotti.Sullunit di input standard vengono fornite righe checontengono due elementi: il numero identificativo del prodotto(compreso tra 1 e 20) e la quantit venduta.Scrivere un programma che calcoli e presenti in output il ric avototale.
Ricavo totale (soluzione)
pattern: corrispondenza indice dati: usare un vettore che memorizzi il prezzo dei prodotti
(PREZZO) inizializzare il vettore leggendolo d al fil e PREZZI.TXT
pattern: leggere tutte le righe in input per o gn r ga e a:
estrarre i campi (IPROD, QPROD) e verificarne lacongruenza
calcolare il ricavo del prodot to (RIPROD) e sommarlo altot ale (RITOT)
alla fine stampare in outpu t il ricavo totale
ricavo.c
Problema conversione del mese(con lettura dei nomi da file)
Scrivere un programma che riceva in inp ut date nella formanumerica
GG.MM.AAAAe le trasformi in output n el formato alfabetico
GG nome-del-mese AAA Aome nom e mes s evono usare o c nom spec ca
(uno per riga) nel file N.DAT; garantit o che ciascun nomepresente in questo file non pi lungo di qu indici caratteri.
Al p rogram ma pu ess ere pas sato opzionalm ente un par ametr osulla linea di comando p er richiedere che il nome del mese siascritt o tutto in min uscolo (L ) o in maiuscolo (U).
Definizione di un vettore di vettori (matrice) per definire un vettore il c ui tipo base a sua volta un
vettore (come capita nel caso di vettori di stringh e) suffici ente usare pi volte le parentesi quadre per indicare ladimensione degli indici
un vettore di vettori anche detto matrice nel caso di due indici, il primo in dica le righe ed il secondo
indica le colonne della matrice
esempi:
char nomi_delle_stagioni[4][32];float matrice2x3[2][3];
7/24/2019 Dispense linguaggio C
42/49
7/24/2019 Dispense linguaggio C
43/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 43
Esempio: gestione anagrafe studenti
typedef enum {gen, feb, mar, , dic} tipoMese;
typedef enum {1,2,3,4,5,6,,31} tipoGiorno;typedef enum {M, F} tipoSesso;
struct personaAnagrafica {char nome[32];
tipoGiorno giorno_di_nascita;tipoMese mese_di_nascita;unsigned int anno_di_nascita;tipoSesso sex;
};
struct personaAnagrafica studente1, studente2;struct personaAnagrafica corso[MAXSTUDENTI];
Esempio: geometria in R 2
/* definizione della struttura base */
struct _puntoR2 {double x;double y;
};
/* definizione tipo per le variabili */
typedef struct _puntoR2 puntoR2 ;
/* definizione di alcune variabili */
puntoR2 a, b; puntoR2 origine = {0,0};
Accesso ai campi d i una struct
riguardo ad una struct, lecito: trattarla come un dato unic o (assegnarla, confron tarla,
passarla come parametro) prenderne lindirizzo prendere lindirizzo di un campo acce ere a s ngo camp :
con notazione . per le variabili
con notazione -> per i puntatori esempi:
puntoR2 alfa = {5, 5}; puntoR2 *aptr = &alfa;
alfa.x = 0;aptr->y = 0;
Esempio: calcolo d istanza tra due punti in R 2
passando direttamente i punti:double distanzaR2 (puntoR2 p1, puntoR2 p2){
double dx = p1.x - p2.x;double dy = p1.y - p2.y;return sqrt( dx*dx + dy*dy );
oppure passando i puntatori ai punti:
}
double distanzaR2 (puntoR2 *p1, puntoR2 *p2){
double dx = p1->x - p2->x;double dy = p1->y - p2->y;return sqrt( dx*dx + dy*dy );
}
Esame del 11-lug-2000Programma che legga un file di testo e ne produc a una copiacon le righe centrate.
Arg omen ti su lla rig a di c omando : il nome del file in ingresso il nome del file di uscita a ung ezza mass ma una r ga ne e usc a
Il programma legga il file in ingresso e lo copi sul fi le di uscitacentrando il testo di ogn i singola riga rispetto alla lunghezzamassima LM.In pratica, le righe pi lunghe di LM vanno t roncate allalunghezza LM e la rimanente parte deve essere consideratacome una nuova riga.Invece le righe pi cort e di LM devono essere centrateaggiungendo un'op portuna sequenza iniziale di spazi.
Esame del 11-lug-2000: soluzione controllo gli argomenti apro i file leggo e contro llo la lun ghezza massima della riga (LM) leggo il file di input u na riga per volta e per ogni rig a:
se la sua lunghezza < LMstampo la rig a centrata (ossia preceduta da unnumero di sp azi pari a (LM LRIGA) / 2
altrimenti:finch LRIGA > LM
ne stampo i primi LM caratteriavanzo lind ice di inizio rig a di LM caratteri
stampo centrata la restante partee000711.c
7/24/2019 Dispense linguaggio C
44/49
Programmazione in linguaggio C (mar'11)
A.Lioy - Politecnico di Torino (2011) 44
Esame del 23-set-2000
Un file di testo co ntiene operazioni di acquisto e vendita diazioni. Ogni riga ri porta una singol a operazione, nel formato:
n. azioni acquistate o vendute (se n. negativo) valore di una azione in Euro (n. frazionario coi centesimi) sigla dell'azionecr vere un programma c e a come pr mo argomen o n