Dispense linguaggio C

download Dispense linguaggio C

of 49

Transcript of Dispense linguaggio C

  • 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