Laboratorio di Linguaggi lezione VI Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea in Informatica Anno Accademico 2004/05
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Laboratorio di Linguaggi docente: Marco Tarini ricevimento: Martedì 14: :30 o anche su appuntamento libro di testo consigliato: Kelley Al, Pohl Ira: "C Didattica e Programmazione" ("A Book on C") quarta edizione - anche la terza va bene
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Puntatori: operazioni a basso livello Esercizio: Sappiamo che un double occupa 8 bytes. Dato un double, quale è il valore di questi 8 bytes? Per esempio, quali 8 bytes compongono il valore ? un numero in virgola mobile a doppia precisione di solito, ma dipende dall'implementazione
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Puntatori: operazioni a basso livello A casa, provate questo programma, e scopriamo: –quali sono gli 8 bytes che compongono il double –quali sono gli 8 bytes che compongono il double x e, adattando il programma agli interi: –quali sono i 4 bytes che compongono l'int –quali sono i 4 bytes che compongono l'int + 1 –quali sono i 4 bytes che compongono l'int - 1 a seconda di quale architettura viene usata, potremmo trovare risposte diverse! –domanda: sarebbe potuto succedere in Java?
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Nota per i prossimi progetti Usare l'opzione da riga di comanda per il compilatore –ansi –Cosi facendo, il compilatore diventa più restrittivo In Dev-C++ :
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Nota per i prossimi progetti Usare l'opzione da riga di comanda per il compilatore –ansi –Cosi facendo, il compilatore diventa più restrittivo In Dev-C++ : scrivere: " -ansi "...e magari anche " -pedant "
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Input / Output
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Printf Scrittura formattata int printf( const char* formato [, lista parametri...] )
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Input / Output Scrittura formattata int x=10;... printf("Il valore di x e' %d \n", x); Scrive sullo schermo: Il valore di x e' 10 carattere '\n' : End Of Line (accapo) %d è un format tag : significa, scrivi il valore di un parametro intero
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Input / Output Scrittura formattata int x=10, y=0;... printf("Posizione [%d,%d] ! ", x, y); Scrive sullo schermo: Posizione [10,0] !
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Format Tags Vi ricordate che 'A' e 65 sono entrambi costanti (literals) di tipo char ? Usando il format tag appropriato, posso far scrivere uno o l'altro: char ch='A';... printf("Posso scrivere %c o %d a piacare ! ", ch, ch); Scrive sullo schermo: Posso scrivere A o 65 a piacere !
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Format Tags Il format tag definisce –come interpretare –con che formato scrivere il parametro corrispondente un array di caratteri terminato da '\0' %i%d %u%x%X %c %f%e%E %p format tag: interpreta il parametro come: un intero con segno un intero senza segno un numero in virgola mobile un carattere una stringa un puntatore %s %o
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a %i%d %u%x%X %c %f%e%E %p format tag: interpreta il parametro come: un intero con segno un intero senza segno un numero in virgola mobile un carattere una stringa un puntatore %s %o Format Tags Il format tag definisce –come interpretare –con che formato scrivere il parametro corrispondente in decimale in esadecimale (es. 12ac3a ) in esadecimale (es. 12AC3A ) in base otto (es )
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a %i%d %#u%#u%#x%#X %c %f%e%E %p format tag: interpreta il parametro come: un intero con segno un intero senza segno un numero in virgola mobile un carattere una stringa un puntatore %s %#o Format Tags Il format tag definisce –come interpretare –con che formato scrivere il parametro corrispondente in decimale in esadecimale (es. 0x12ac3a ) in esadecimale (es. 0X12AC3A ) in base otto (es )
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a %i%d %c %f%e%E %p format tag: interpreta il parametro come: un intero con segno un numero in virgola mobile un carattere una stringa un puntatore %s Format Tags Il format tag definisce –come interpretare –con che formato scrivere il parametro corrispondente in notazione comune (es. 1.2e12 ) in notazione esponenziale (es. 1.2E12 )
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Format Tags Esempio printf("Scrivo %d %d e %d !\n\nah!\n", 1, 2, 3); Risultato: Scrivo 1 2 e 3 ah!
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Risultato: Scrivo 1 2 e 3 ah! Format Tags Esempio printf("Scrivo %-5d %5d e %5d !\n\nah!\n", 1, 2, 3); "5 caratteri di lunghezza"
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Risultato: Scrivo: e anche +1e+000 Format Tags etc... printf("Scrivo: %+6.3lf e anche %+.0e\n", 1.1, 1.2 ); 6 cifre prima della virgola 3 cifre dopo virgola l : è un "float lungo", cioè un double + : specifica il segno anche se pos
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Risultato: Totale (in euro): 130 Format Tags etc... char* stringa= "Totale (in euro): "; int res;... printf("%s%d\n", stringa, res );
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Format Tags Attenzione ai tipi printf("Torna %f euro\n", 150 ); Sullo schermo: Torna 0 euro Errore! Ha interpretato un valore intero come un float! Se i due tipi hanno dimensione diversa, può anche causare un crash (errore di accesso in lettura).
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Format Tags Attenzione ai tipi printf("Torna %f euro\n", 150.0f ); Sullo schermo: Torna 0 euro
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Format Tags Attenzione ai tipi int x=150; printf("Torna %f euro\n", x ); Sullo schermo: Torna 0 euro float int
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Funzionamento di printf Come si scrive un programma che ci dice quale e' il codice ascii del simbolo '!' ? printf( "%d", '!' ); E se lo vogliamo in esadecimale? printf( "%X", '!' );
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Funzionamento di printf Come si scrive un programma che risolve il quiz del banner misterioso? char msg[]= {78,111,119,32,72,105,110,103,0}; testo del quiz printf(%s,msg);
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Dove scrive printf? sull' output standard di solito, significa: sul monitor ma, ad esempio... –al momento di eseguire il programma posso utilizzare la sintassi: programma >> file
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Scrivere non solo sullo schermo int printf( const char* format [, lista param...] ) printf : scrive sull'output standard int fprintf( const char* format [, lista param...] ) fprintf : scrive su un File int sprintf( const char* format [, lista param...] ) sprintf : scrive su un'altra Stringa (che deve essere già allocata) FILE* stream, char* output,
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Esempio con sprintf concatenazione di stringhe char[] stringa1 = "cacio"; char[] stringa2 = "cavallo"; char *concat; sprintf(concat,"%s%s",stringa1, stringa2); NON vi siete ancora accorti dell'errore?!
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Esempio con fprintf scrittura in un file float x,y,z; FILE* file_di_output= fopen ("ciao.txt", "wt"); fprintf( file_di_output,"(%f %f %f)",x,y,z ); fclose(file_di_output); FILE* : il puntatore a una struttura che contiene tutto quello che c'è da sapere su un file aperto. Cosa contiene questa struttura? Non importa! (è platform dependent) Gestiamo i file utilizzando solo puntatori a questa struttura... fopen : apri un file. resitutisce un FILE* (alloca la struttura & apre il file) Primo parametro: nome del file Secondo parametro: stringa con 1- r ead o w rite o a ppend, 2- modo t esto o b inario Restituisce NULL se non è riusicto ad aprire il file fclose : chiudi un file. (chiude il file & disalloca la struttura) solo un certo numero di files può essere aperto in un dato momento consente ad altre applicazioni di usare il file
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Input / Output
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a scanf da printf a scanf –per leggere dalla tastiera invece che scrivere sul monitor int x;... printf("%d", x); scanf & ora vuole un puntatore! (perchè?) deve essere un puntatore a qualcosa di allocato (in questo esempio, è allocato automaticamente) e' ancora + importante che il tipo del puntatore corrisponda al format tag! (errori in scrittura invece che lettura, fa più male)
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a scanf Tutto il resto come printf Restituisce il numero di target tag che è stato corettamente assegnato int x,y, n; unsigned int z;... n = scanf("%d-%d:%X", &x, &y, &z); n sarà uguale a 3 se l'utente avrà digitato, ad esempio: 5-5:A0A111 n sarà uguale a 2 se l'utente avrà digitato, ad esempio: 5-5pippo n sarà uguale a 0 se l'utente avrà digitato, ad esempio: >:-P
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a scanf Tutto il resto come printf Restituisce il numero di target tags che sono stati corettamente assegnati int g,m,a; do { printf(\nInserisci giorno/mese/anno: " ); } while ( scanf("%u/%u/%u", &g, &m, &a)!=3 );
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Leggere non solo dalla tastiera int scanf( const char* format [, lista punt.] ) scanf : legge dall'input standard int fscanf( const char* format [, lista punt.] ) fscanf : legge da un File int sscanf( const char* format [, lista punt.] ) sscanf : legge da una Stringa FILE* stream, char* input,
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Esempio di fscanf FILE* file_di_output= fopen ("ciao.txt", "wt"); sprintf( file_di_output,"(%f %f %f)",x,y,z ); fclose(file_di_output); FILE* file_di_output= fopen ("ciao.txt", "rt"); sscanf( file_di_output,"(%f %f %f)",&x,&y,&z ); fclose(file_di_output); float x,y,z;
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Uso tipico di sscanf : Lettura degli argomenti da riga di comando di un programma. int main(int argc, char *argv[]) argv[0] : nome del programma argv[1] : primo argomento... argv[argc-1] : ultimo argomento numero di argomenti + 1 C:> pippo.exe –a –o:zap argv[0] argv[1] argv[2]
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Uso tipico di sscanf (compito per casa) : /* mostra le istruzioni di uso da riga di comando */ void show_usage(){... } int main(int argc, char *argv[]) { int x; if (argc<2) { /* nessun argomento: mostra l'aiuto e esci */ show_usage(); return 0; } if (sprintf("%d", argv[1], &x) != 1) { /* il primo argomento non e' un numero: mostra l'aiuto e esci */ show_usage(); return 0; } /* mostra i byte che compongono il numero... in base 16. Due cifre a byte, separate da uno spazio es: */... return 1; }
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Per provare il programma su Dev-C++ Impostare gli argomenti su Dev-C++ 21|
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 5 U n i v e r s i t à d e l l I n s u b r i a Definizione del C sul dizionario degli hacker C: (noun). 1.ASCII A language that combines all the elegance and the power of the assembly language with all the readability and the maintanability of the assembly language tra " bytesexual " e " calculator "