Tipi, operatori e controllo del flusso in C
In questa pagina 6
Tipi fondamentali
| Tipo | Dimensione tipica | Intervallo tipico |
|---|---|---|
char |
1 byte | −128…127 (o 0…255) |
short |
2 byte | −32 768…32 767 |
int |
4 byte | circa ±2,1 miliardi () |
long |
4 o 8 byte | |
long long |
8 byte | circa |
float |
4 byte | 7 cifre significative |
double |
8 byte | 15–16 cifre significative |
- Le dimensioni dipendono dalla piattaforma:
sizeof(tipo)le dà in byte; i limiti sono in<limits.h>(INT_MAX,INT_MIN). unsigneddavanti a un tipo intero: solo valori non negativi, intervallo doppio ( perunsigned int).- Gli interi con segno sono in complemento a 2 (vedi Rappresentazione binaria dei datiBasi 2, 8 e 16; interi senza segno e in complemento a 2 con overflow; virgola mobile IEEE 754 e sue approssimazioni; caratteri ASCII, Unicode e UTF-8.Rappresentazione binaria dei dati →). Overflow su
int= comportamento indefinito; suunsignedil risultato è modulo . charè un intero piccolo:'A'vale 65,'A' + 1 == 'B',c - '0'converte una cifra carattere nel suo valore.- Booleani:
0è falso, qualunque altro valore è vero; i confronti valgono1o0. Con#include <stdbool.h>si hannobool,true,false.
Operatori
Aritmetici + - * / %, confronto == != < <= > >=, logici && || ! (con corto circuito, come and or not in Python), assegnamento = += -= *= /= %=.
Divisione
- Tra due interi
/è divisione intera, troncata verso zero:7 / 2 == 3,-7 / 2 == -3,-7 % 2 == -1. - Basta un operando reale per avere la divisione reale:
7 / 2.0 == 3.5,(double)a / b.
int a = 7, b = 2;
double m1 = a / b; /* 3.0: la divisione intera avviene PRIMA della conversione */
double m2 = (double)a / b; /* 3.5 */Conversioni
- Implicite: negli operatori aritmetici il tipo "più piccolo" viene promosso al più grande (
int→long→float→double);chareshortdiventanoint. Nell'assegnamento il valore si converte al tipo della variabile, con possibile perdita (int i = 3.99;→ 3). - Esplicite (cast):
(tipo)espressione. - Mescolare
inteunsignednei confronti dà sorprese:-1 < 0uè falso perché-1diventa ununsignedenorme.
Incremento e decremento
i++; /* i = i + 1 */
x = i++; /* x prende il valore VECCHIO di i, poi i aumenta */
x = ++i; /* prima i aumenta, poi x prende il nuovo valore */Non usare la stessa variabile più volte in un'espressione che la incrementa (i = i++ + 1; è indefinito).
Operatori bit a bit
& (and), | (or), ^ (xor), ~ (not), <<, >> (spostamenti): x << k vale per valori non negativi senza overflow; x & 1 è il bit meno significativo (pari/dispari). Non confondere & con &&.
Espressione condizionale
max = (a > b) ? a : b; equivale al a if a > b else b di Python.
if
if (voto >= 18) {
printf("promosso\n");
} else if (voto >= 15) {
printf("orale\n");
} else {
printf("respinto\n");
}Condizione sempre tra parentesi. Senza graffe, al ramo appartiene una sola istruzione: usare sempre le graffe.
switch
Confronta un'espressione intera (o char) con costanti.
switch (op) {
case '+':
r = a + b;
break;
case '-':
r = a - b;
break;
case '*':
case 'x': /* due etichette, stesso codice */
r = a * b;
break;
default:
printf("operatore sconosciuto\n");
}Senza break l'esecuzione prosegue nel case successivo (fall-through).
Cicli
while (n > 0) { /* come in Python */
n /= 10;
cifre++;
}
do { /* corpo eseguito almeno una volta */
printf("valore positivo: ");
scanf("%d", &x);
} while (x <= 0);
for (int i = 0; i < n; i++) { /* inizializzazione; condizione; aggiornamento */
somma += v[i];
}Il for del C è un while compatto: for (init; cond; agg) corpo equivale a init; while (cond) { corpo agg; }. Corrisponde a for i in range(0, n) di Python. break e continue come in Python; non esiste l'else dei cicli.
Errori tipici
if (x = 5)invece diif (x == 5): assegna 5 e la condizione è sempre vera (il compilatore con-Wallavvisa).;subito dopoif (...),while (...)ofor (...): il corpo diventa l'istruzione vuota.- Divisione intera inattesa (
1 / 2 == 0), ad esempio nel calcolo di una media. switchsenzabreak.- Overflow di
intin prodotti o fattoriali: usarelong longo controllare i limiti.