Linguaggio C - approfondimenti sulle variabili e sugli array
Tipi di variabili
Ci sono tre tipi di variabili standard in C:
• integer int
• floating point: float
• caratteri: char
Un int è un valore intero memorizzato in 4 byte. Un float è un valore in virgola mobile memorizzato in 4 byte. Un char è un singolo carattere che occupa un byte.
Ci sono poi una serie di tipi derivati:
• double (valori a virgola mobile memorizzati in 8 byte)
• short (interi memorizzati in solo 2 byte
• unsigned short o unsigned int (interi positivi, dove non si usa il bit per il segno)
Operatori e precedenza fra operatori
Gli operatori in C sono simili agli operatori della maggior parte degli altri linguaggi.
+ - addizione
- - sottrazione
/ - divisione
* - multiplicazione
% - operatore modulo (mod)
L'operatore / esegue la divisione intera se entrambi gli operandi sono interi, esegue la divisione fra valori in virgola mobili se gli operatori sono in virgola mobile.
void main() { float a; a=10/3; printf("%f\n",a); }
Questo codice stampa un valore in virgola mobile poiché a viene dichiarato come float, ma il valore di a sarà 3.0 proprio perchè il codice esegue una divisione fra interi. La Precedenza fra operatori in C è simile a quella di molti altri linguaggi. La divisione e la moltiplicazioni devono essere eseguiti prima, poi si esegue l'addizione e la sottrazione. Il risultato del calcolo 5+3*4 è 17, non 32, perchè l'operatore * ha una precedenza maggiore rispetto al + in C. Si possono usare le parentesi per cambiare la precedenza standard fra gli operatori. Quindi (5+3)*4 fa 32. L'operazione 5+3 viene valutata per prima perchè si trova fra parentesi. Approfondiremo in seguito la precedenza fra operatori che sarà resa più complessa dall'introduzione dei puntatori.
Casting di tipo
Il linguaggio C permette di eseguire conversioni fra tipi di dati al volo (durante l'esecuzione). Si ottiene spesso il casting di tipo quando si utilizzano i puntatori. Il casting di tipo avviene inoltre durante l'assegnazione dei risultati ottenuti da operatori. Per esempio, nel codice sopra descritto, il valore intero viene automaticamente convertito a float.
In C il casting di tipo si può anche fare esplicitamente mettendo il nome della variabile tra parentesi e anteponendo ad essa il tipo in cui fare il casting. Ad esempio, nel codice qui sopra si può scrivere a = (float)10/3 per ottenere in a un valore in virgola mobile. In questo caso il valore di a sarà quindi 3.33333 perchè 10 viene convertito in float prima della operazione di divisione.
Typedef
In C si possono dichiarare tipi di dato definiti dall'utente con la parola chiave typedef. Il seguente esempio mostra un tipo di dato che appare spesso in un codice C.
#define TRUE 1 #define FALSE 0 typedef int boolean; void main() { boolean b; b=FALSE; blah blah blah }
Con questo codice si può dichiarare un tipo di dato in C chiamato Boolean.
Se poi non gradite la parola float (che sostanzialmente copre i numeri reali), si può scrivere
typedef float real;
e poi dichiarare le variabili r1, r2, r3 real r1,r2,r3;
Strutture
Le strutture in C permettono di raggruppare le variabili in un package. Ecco qui un esempio
struct rec { int a,b,c; float d,e,f; }; struct rec r;
Come mostrato qui, ogni volta che si vuole dichiarare una struttura di tipo rec si deve scrivere struct rec. Questa linea è una linea di codice che si scorda molto facilmente e potrebbe quindi succedere che molti compilatori generino errori per via del fatto che si è dimenticata la parola struct. Per ovviare a questi problemi, quando possibile, si può comprimere i codice nella forma:
struct rec { int a,b,c; float d,e,f; } r;
dove la dichiarazione del tipo rec e della variabile r appaiono nella stessa “istruzione”. Oppure si può creare una istruzione typedef per il nome della struttura. Per esempio, se non si vuole ripetere struct rec r ogni volta che si vuole dichiarare un record si può dire;
typedef struct rec rec_type
e dichiarare poi records del tipo rec_type dicendo:
rec_type r;
Per accedere ai singoli campi della struttura si usa un punto ad esempio r.a=5 per assegnare alla struttura di tipo rec_type r nel campo a il valore 5.
Array
Per dichiarare un array basta inserire la dimensione dell'array fra parentesi quadre immediatamente dopo il nome dell'array, così come segue:
int a[10]; /* array di integers */ char s[100]; /* array di characters (una stringa in C) */ float f[20]; /* array di reals */ struct rec r[50]; /* array di records */ Operatori di incremento Forma estesa Forma compatta i=i+1; i++; i=i-1; i--; i=i+3; i += 3; i=i*j; i *= j;
Approfondimenti ed esercizi
• provare vari tipi di casting e provare come funziona la precedenza fra operatori
• creare un array di records e scrivere un po' di codice per ordinare l'array sulla base di un campo intero
Errori da evitare in C
• come sopra descritto, usare l'operatore / con due interi. Usare l'operatore / con due interi produce in genere un risultato insolito, quindi conviene soffermarsi a pensare prima di usarlo.