Tipi, operatori e controllo del flusso in C
In questa pagina 6
In questa pagina 4
Tipi fondamentali
Definizione (tipi fondamentali del C)
Tipo Dimensione tipica Intervallo tipico char1 byte −128…127 (o 0…255) short2 byte −32 768…32 767 int4 byte circa ±2,1 miliardi () long4 o 8 byte long long8 byte circa float4 byte 7 cifre significative double8 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).
Esempio. Sulla piattaforma di prova sizeof(int) vale 4, INT_MAX vale 2147483647 e 'A' + 1 == 'B'.
- 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
Definizione (divisione intera e reale in C)
- 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.
Esempio. 7 / 2 vale 3, -7 / 2 vale -3, -7 % 2 vale -1 e 7 / 2.0 vale 3.5.
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
Definizione (conversioni implicite ed esplicite)
- 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.
Esempio. Con int a = 7, b = 2, double m1 = a / b; vale 3.0 mentre (double)a / b vale 3.5; -1 < 0u vale 0 (falso).
Incremento e decremento
Definizione (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 */
Esempio. Con i = 5, x = i++ dà x = 5 e i = 6; con i = 5, x = ++i dà x = 6 e i = 6.
Non usare la stessa variabile più volte in un'espressione che la incrementa (i = i++ + 1; è indefinito).
Operatori bit a bit
Definizione (operatori bit a bit).
&(and),|(or),^(xor),~(not),<<,>>(spostamenti):x << kvale per valori non negativi senza overflow;x & 1è il bit meno significativo (pari/dispari). Non confondere&con&&.
Esempio. 5 << 2 vale 20 (), 6 & 3 vale 2, 6 ^ 3 vale 5 e 7 & 1 vale 1 (numero dispari).
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");
}Proprietà (fall-through dello switch). Senza
breakl'esecuzione prosegue nelcasesuccessivo (fall-through).
Esempio. Con switch (2) senza break dopo case 2, partendo da r = 0 con case 1: r = 1; case 2: r += 10; case 3: r += 100; break; si ottiene r = 110.
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.
Versione ripasso
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 |
- Dimensioni con
sizeof(tipo)in byte; limiti in<limits.h>. unsigned: solo valori non negativi, intervallo doppio.- Interi con segno 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; suunsignedmodulo . - Booleani:
0falso, altro vero;#include <stdbool.h>perbool,true,false.
Operatori
Aritmetici + - * / %, confronto == != < <= > >=, logici && || ! (con corto circuito), assegnamento = += -= *= /= %=.
Divisione e conversioni
- Tra interi
/è divisione intera troncata verso zero:7 / 2 == 3,-7 / 2 == -3,-7 % 2 == -1. Operando reale per divisione reale ((double)a / b). - Implicite: promozione al tipo più grande (
int→long→float→double). Esplicite (cast):(tipo)espressione. - Mescolare
inteunsignednei confronti dà sorprese (-1 < 0uè falso).
Incremento, bit a bit e condizionale
i++(restituisce il vecchio valore e incrementa),++i(incrementa e restituisce il nuovo).- Bit a bit:
&,|,^,~,<<,>>(x << kvale per non negativi). - Condizionale:
max = (a > b) ? a : b;.
Controllo del flusso
if: condizione tra parentesi, usare sempre le graffe.switch: confronta espressione intera/charcon costanti. Senzabreakl'esecuzione prosegue (fall-through).- Cicli:
while (cond) { ... }do { ... } while (cond);(eseguito almeno una volta)for (init; cond; agg) { ... }
Errori tipici
if (x = 5)invece diif (x == 5).;subito dopoif,whileofor.- Divisione intera inattesa (
1 / 2 == 0). switchsenzabreak.- Overflow di
intnon gestito.