• Non ci sono risultati.

FONDAMENTI DI INFORMATICA

N/A
N/A
Protected

Academic year: 2021

Condividi "FONDAMENTI DI INFORMATICA"

Copied!
5
0
0

Testo completo

(1)

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 1

FONDAMENTI DI INFORMATICA

Prof. PIER LUCA MONTESSORO Ing. DAVIDE PIERATTONI

Facoltà di Ingegneria Università degli Studi di Udine

Le trappole del linguaggio C

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 2 Questo insieme d i trasparenze ( detto nel seguito slide) è protetto dalle leggi sul copyright e dalle disposizioni dei trattati internazionali. Il titolo ed i copyright relativi alle slides (ivi inclusi , ma non limitatamente, ogni immagine, fotografia, animazione , video, audio, musica e testo) sono d i proprietà degli autori prof . Pier Luca Montessoro e ing. Davide Pierattoni , Università degli Studi di Udine.

Le slide possono essere riprodotte ed utilizzate liberamente dagli istituti di ricerca , scolastici ed universitari afferenti a l Ministero della Pubblica Istruzione e al Ministero dell’Università e Ricerca Scientifica e Tecnologica, per scopi istituzionali, non a fine di lucro . In tal caso non è richiesta alcuna autorizzazione .

Ogni altro utilizzo o riproduzione (ivi incluse , ma non limitatamente, le riproduzioni su supporti magnetici , su reti d i calcolatori e stampe) in toto o in parte è vietata, se non esplicitamente autorizzata per iscritto, a priori, da parte degli autori.

L’informazione contenuta in queste slide è ritenuta essere accurata alla data della pubblicazione . Essa è fornita per scopi meramente didattici e non per essere utilizzata i n progetti d i impianti, prodotti, reti, ecc. In ogni caso essa è soggetta a cambiamenti senza preavviso. Gli autori non assumono alcuna responsabilità per il contenuto d i queste slide (ivi incluse, ma non limitatamente , la correttezza, completezza, applicabilità, aggiornamento dell’informazione ).

In ogni caso non può essere dichiarata conformità all’informazione contenuta in queste slide.

In ogni caso questa nota di copyright e il suo richiamo in calce ad ogni slide non devono mai essere rimossi e devono essere riportati anche in utilizzi parziali.

Nota di Copyright

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 3

Le insidie del C

#include <stdio.h>

main() {

printf ("Hello world");

}

> cc -o hello.exe hello.c

> hello Hello world> _

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 4

"=" e "=="

if (x = y) /* ... */

Il codice viene eseguito se il valore di y, che viene assegnato alla variabile x, è diverso da 0.

if (x == y) /* ... */

Il codice viene eseguito se il valore di y è uguale a quello di x.

Fondamenti di Informatica -Linguaggio C - Le trappole del C

Analisi lessicale del programma

Esempi:

• a/*b è interpretato come a /* b, cioè come un commento aperto prima di b, e non come a / (*b), cioè come a diviso il dato indirizzato da b.

• a---b è interpretato come a-- - b, e non come a - --b.

Il compilatore C cerca sempre di costruire dei token di lunghezza massima.

Fondamenti di Informatica -Linguaggio C - Le trappole del C

Costanti intere

Se una costante inizia per 0 è interpretata come ottale.

struct {

int code;

char *description;

} code_table [] = {

023, "book", 072, "pencil", 112, "rubber"

};

(2)

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 7

La dichiarazione delle funzioni

• float g; variabile floating point g

• float f(); funzione che restituisce un valore float

• float *g; puntatore a float

• float *f(); funzione che restituisce un puntatore a float

• float (*f)(); puntatore a funzione che restituisce un valore float

• float *(*f)(); puntatore a funzione che restituisce un puntatore a float

Attenzione alla precedenza degli operatori!

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 8

Operatore di cast

Si mette tra parentesi la stessa espressione che si usa per la dichiarazione, ma senza l'identificatore della variabile.

float g; g = (float) x;

float *g; g = (float *) x;

float (*h)(); h = (float (*)()) x;

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 9

I tipi nei prototipi delle funzioni

Esempio: la funzione di libreria signal

void (*signal (int, void (*) (int))) (int);

Nel prototipo delle funzioni (ANSI C) si indicano i tipi degli argomenti esattamente come per il cast, ma senza le parentesi intorno.

puntatore a funzione che riceve un int come parametro e non restituisce nulla ( void )

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 10

Per usare i puntatori

Se puntatori a variabile:

float *g, f; f = *g;

Se puntatori a strutture:

list_element *lep;

lep = lep->next;

x = (*lep).data;

Se puntatori a funzioni:

float (*f)(), g; g = (*f)();

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 11

Precedenze degli operatori

Esempio:

if (flags & FLAGMASK != 0) non è equivalente a:

if (flags & FLAGMASK)

in quanto != ha la precedenza su &, e quindi risulta:

if (flags & (FLAGMASK != 0)) ovviamente sbagliato.

Non sempre sono quelle che ci si aspetta!

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 12

Precedenze degli operatori

L'operatore di shift è ancora più subdolo:

r = hi<<4 + low;

è interpretato come:

r = hi << (4 + low);

Due possibili versioni corrette sono:

r = (hi << 4) + low;

r = hi << 4 | low;

(3)

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 13

Precedenze degli operatori

Due osservazioni importanti:

- ogni operatore logico (es. && ) ha precedenza inferiore a qualsiasi operatore relazionale (es. >= ) - gli operatori di shift hanno precedenza minore degli

operatori aritmetici, ma maggiore di quelli logici.

Attenzione: " == " e " != " hanno precedenza inferiore degli operatori relazionali " > ", " < " ecc. Pertanto:

a < b == b < c significa (a < b) == (b < c)

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 14

Precedenze degli operatori

L'assegnazione viene raggruppata da destra verso sinistra:

home_score = visitor_score = 0;

è equivalente a:

visitor_score = 0;

home_score = visitor_score;

L'assegnazione ha anche minor precedenza degli operatori di relazione, e quindi nel caso seguente sono necessarie le parentesi:

while ((c = getc(file_ptr)) != EOF) ...

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 15

E il punto e virgola?

if (x[i] > big);

big = x[i];

Il compilatore accetta il ";" alla fine dell'if, e ignora l'indentazione. Quindi quanto scritto è equivalente a:

if (x[i] > big) { } big = x[i];

e non a:

if (x[i] > big) big = x[i];

!!!

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 16

E il punto e virgola?

Anche dimenticare un punto e virgola può essere pernicioso:

if (n < 3) return a[0] = p;

a[1] = q;

è interpretato come:

if (n < 3)

return a[0] = p;

a[1] = q;

Fondamenti di Informatica -Linguaggio C - Le trappole del C

Chiamata di funzione

Il C richiede che la chiamata di una funzione abbia sempre una lista di argomenti, eventualmente vuota:

f();

Tuttavia viene compilato senza errori anche:

f;

Questa espressione non chiama la funzione f, bensì ne calcola l'indirizzo, e poi lo butta via...

Fondamenti di Informatica -Linguaggio C - Le trappole del C

Else

else si riferisce sempre al più vicino if all'interno dello stesso blocco. Al solito, l'indentazione non è significativa!

if (a) if (b) f();

else

g();

(4)

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 19

Vettori

Possono essere solo unidimensionali.

Su un vettore si possono fare solo due cose:

- definirne la dimensione

- ottenere il puntatore all'elemento 0.

Tutte le altre operazioni sono realizzate mediante puntatori, anche se tramite una sintassi speciale:

v[5] è equivalente a *(v + 5)

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 20

Vettori bidimensionali

int calendar[12][31];

int *month;

int day;

Se si omette l'ultima dimensione si ottiene un vettore (il puntatore al primo elemento):

month = calendar[2];

day = month[30];

oppure

day = calendar[2][30];

o, ancora,

day = *(*(calendar + 2) +30);

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 21

char *r;

r = (char *) malloc

(strlen(s) + strlen(t) + 1);

strcpy (r, s);

strcat (r, t);

/* later... */

free (r);

I puntatori non sono vettori !

char *r;

strcpy (r, s);

strcat (r, t);

char r[100];

strcpy (r, s);

strcat (r, t);

Ancora meglio...

NO! OK

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 22

Conversione automatica di tipo

int strlen (char s[]) è equivalente a scrivere int strlen (char *s)

Tuttavia questo non si applica in altri contesti:

extern char *str;

non è equivalente a scrivere extern char str[];

come

char *str = "hello\n";

non è equivalente a

char str[] = "hello\n";

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 23

Attenzione ai limiti dei vettori

int a[10], i;

for (i = 1; i <= 10; i++) a[i] = 0;

Se la variabile i viene allocata dopo l'ultimo elemento del vettore, il programma entra in un loop infinito!

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 24

Ordine di valutazione

Il C garantisce l'ordine di valutazione delle espressioni (a differenza, per esempio, del Pascal).

Quindi si può scrivere:

if (count != 0 && sum/count < low_ awg) printf ("average < %g\n", low_avg);

senza ottenere un errore per divisione per zero se count == 0.

Uso tipico:

if (i < DIM && v[i] != 0) ...

non viene valutata se

si è raggiunta la fine

del vettore

(5)

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 25

Ordine di valutazione

Attenzione: non è definito l'ordine di valutazione per qualsiasi operatore.

Per esempio, in

if (f() < g())

può essere chiamata prima la funzione f o la funzione g indifferentemente.

I soli operatori per i quali è garantito l'ordine di valutazione sono:

&& || ?: ,

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 26

Variabili locali

char *strcat (char *s, char *t) {

char r[SIZE];

...

return r;

}

Quando la funzione termina, l'indirizzo della stringa r viene copiato come valore di ritorno, ma la stringa stessa è deallocata.

(Questo “bug” molto spesso non è individuabile durante l'esecuzione del programma...)

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 27

char *concatena (char str1[], char str2[]) {

int i, j;

char tmp[MAXSIZE];

for (i = 0; str1[i] != '\0'; i++) tmp[i] = str1[i];

for (j = i, i = 0;

str2[i] != '\0'; i++, j++) tmp[j] = str2[i];

return tmp;

}

Esempio

viene restituito il puntatore alla stringa, ma essa non esiste più

Fondamenti di Informatica -Linguaggio C - Le trappole del C

© 2001 Pier Luca Montessoro - Davide Pierattoni (vedere nota di copyright a pag. 2) 28

Variabili locali

char *strcat (char *s, char *t) {

static char r[SIZE];

...

return r;

}

Due tra le soluzioni possibili:

char r[SIZE];

char *strcat (char *s, char *t) {

...

return r;

}

Riferimenti

Documenti correlati

In ogni caso questa nota di copyright e il suo richiamo in calce ad ogni slide non devono mai essere rimossi e devono essere riportati anche in utilizzi parziali.. Nota

In ogni caso questa nota di copyright e il suo richiamo in calce ad ogni slide non devono mai essere rimossi e devono essere riportati anche in utilizzi parziali.. Nota

In ogni caso non può essere dichiarata conformità all’informazione contenuta in queste slide.. In ogni caso questa nota di copyright e il suo richiamo in calce ad ogni slide non devono

In ogni caso non può essere dichiarata conformità all’informazione contenuta in queste slide.. In ogni caso questa nota di copyright e il suo richiamo in calce ad ogni slide non

In ogni caso questa nota di copyright e il suo richiamo in calce ad ogni slide non devono mai essere rimossi e devono essere riportati anche in utilizzi parziali.. Nota

In ogni caso questa nota di copyright e il suo richiamo in calce ad ogni slide non devono mai essere rimossi e devono essere riportati anche in utilizzi parziali.. Nota

In ogni caso questa nota di copyright e il suo richiamo in calce ad ogni slide non devono mai essere rimossi e devono essere riportati anche in utilizzi parziali.. Nota

In ogni caso questa nota di copyright e il suo richiamo in calce ad ogni slide non devono mai essere rimossi e devono essere riportati anche in utilizzi parziali. Nota