Vai al contenuto
Appunti di InformaticaUniTo · 2026/27

Riassunto settimanale · Programmazione I · Canale B · 12/10 – 16/10/2026

Settimana 3: operatori e tipi, scambi, numeri reali, condizioni e if

Il laboratorio e le quattro lezioni della settimana in poche pagine: le divisioni che ingannano, lo scambio fatto bene, come si scrive una condizione che compila con -Wall -Werror, come si segue un programma con gli if, e le domande per controllarti.

Lezioni
Lab02 lun 12/10 (B2) e mar 13/10 (B1) · 03A e 03B mar 13/10 · 03C e 03D mer 14/10
Tempo di ripasso
45 minuti
  • Definizione o risultato da sapere
  • Trappola / errore tipico
  • Conta all'esame
  • Oltre le slide
  • Da ricordare

La settimana in 7 punti

  • Tra due interi / dà la parte intera e % il resto: 99 / 50 fa 1. Basta un reale per avere la divisione con la virgola: 99 / 50.0 fa 1.98.
  • Per scambiare due variabili serve una variabile d'appoggio: temp = x; x = y; y = temp;, in quest'ordine.
  • float ha circa 7 cifre giuste, double circa 15. Un double si stampa con %f e si legge con %lf.
  • Mettere un reale in un int taglia la parte dopo la virgola. Il cast (double)a converte quando lo decidi tu.
  • Un confronto vale 1 se è vero e 0 se è falso. Le condizioni si uniscono con &&, || e !; «x tra 18 e 30» si scrive 18 <= x && x <= 30.
  • Cortocircuito: se la prima parte di && o || basta a decidere, la seconda non viene calcolata.
  • if esegue un blocco solo se la condizione è vera; else dà l'altra strada; else if mette in fila più domande.
§1

Lab02 · Operatori e tipi (lun 12/10, mar 13/10)

Il laboratorio ha sei programmi di partenza da leggere, provare e correggere, poi tre programmi nuovi. Le cose da portarsi via:

Che cosaEsempioRisultato
divisione tra interi99 / 50 e 99 % 501 e 49
basta un reale99 / 50.01.98
overflow di un intx + 1 con x che vale 2147483647un numero negativo, senza avvisi
precedenze2 + 3 * 414: *, /, % prima di + e -
media di tre interi(a + b + c) / 3 con 4, 5, 54: serve 3.0, che dà 4.67
approssimazione(int)(8.136 * 1000)8135, non 8136
dimensione di un puntatoresizeof(int*), sizeof(double*)8 byte tutti e due, su 64 bit
  • const dichiara una costante: const double PI = 3.14159; non si può più cambiare.
  • Per arrotondare ci sono floor, ceil e round di math.h; il cast a int taglia e basta.
  • In errori.c gli errori sono 8: il compilatore li segnala uno alla volta, e conviene correggere sempre il primo.

Prova tu

Quanto valgono 17 / 4, 17 % 4 e 17 / 4.0?

4, 1 e 4.25: tra interi la divisione taglia, con un reale no.

Da ricordare

  • Tra interi la divisione è intera. Una media si divide per 3.0.
  • L'overflow degli int non dà avvisi: il risultato è sbagliato in silenzio.
§2

03A · Scambiare due variabili (mar 13/10)

Lo scambio «ovvio» x = y; y = x; non funziona: il primo assegnamento cancella il vecchio valore di x, e alla fine le due variabili valgono uguale. Come con due tazze di tè da scambiare, serve una terza tazza vuota.

8 → 33 → 88xytemp123
Lo scambio con la variabile d'appoggio, partendo da x = 8 e y = 3. Prima si mette da parte x (1), poi si copia y in x (2), infine si rimette in y il valore messo da parte (3).
  • temp deve avere lo stesso tipo delle due variabili.
  • L'ordine conta: con gli stessi tre assegnamenti in un altro ordine un valore si perde di nuovo. La regola: si copia per primo il valore che sta per essere sovrascritto.
  • Per scambiare in giro più variabili, come nell'esercizio scambio4.c, basta una sola variabile d'appoggio.

Prova tu

Con int a = 1, b = 2;, quanto valgono le due variabili dopo temp = a; b = a; a = temp;?

Tutte e due 1. L'ordine è sbagliato: b = a cancella il 2 prima che qualcuno l'abbia messo da parte.

Da ricordare

  • temp = x; x = y; y = temp;: ogni variabile, a sinistra, è stata letta prima di essere riscritta.
  • Il compilatore non avvisa se lo scambio è sbagliato: va controllato a mano.
§3

03B · Numeri reali, conversioni e cast (mar 13/10)

I numeri con la virgola in C hanno due tipi, che cambiano per spazio occupato e precisione:

TipoByteCifre giusteprintfscanf
float4circa 7%f%f
double8circa 15–16%f%lf
  • %f stampa 6 cifre dopo la virgola, %.2f due, %e usa la notazione scientifica, %g sceglie la più corta.
  • Sui reali non c'è %. Radici e potenze sono in math.h: sqrt, pow.
  • I reali sono approssimati: non si confrontano con ==.
  • Promozione: in un'espressione con tipi diversi il più piccolo diventa il più grande, e un intero con un reale dà un reale.
  • La divisione che inganna: in float z = 5 / 2; la divisione è tra interi e fa 2; solo dopo il 2 diventa 2.000000.
  • Il cast va messo prima della divisione: (double)a / b divide con la virgola, (double)(a / b) converte un risultato già tagliato.

Prova tu

Con int a = 9, b = 4;, quanto valgono (double)a / b e (double)(a / b)?

2.25 e 2.0: nel secondo la divisione tra interi è già stata fatta, e il cast converte il 2.

Da ricordare

  • Un double si legge con %lf.
  • Il tipo di una divisione lo decidono i due operandi, non la variabile a sinistra dell'uguale.
§4

03C · Espressioni booleane (mer 14/10)

Un'espressione booleana è una domanda con risposta sì o no: in C vale 1 se è vera e 0 se è falsa. Si confronta con ==, !=, <, >, <=, >=; == confronta, = assegna. Il tipo bool, con true e false, viene da stdbool.h.

aba && ba \|\| b!a
veroveroveroverofalso
verofalsofalsoverofalso
falsoverofalsoverovero
falsofalsofalsofalsovero

Trappola · Due errori che con -Wall -Werror non compilano

  • 0 <= x <= 10 si calcola da sinistra e vale sempre 1: gcc lo rifiuta, «comparisons like 'X<=Y<=Z' do not have their mathematical meaning». Si scrive 0 <= x && x <= 10.
  • && dentro || senza parentesi: gcc chiede le parentesi. Le condizioni lunghe si spezzano in variabili bool con un nome chiaro.
  • Cortocircuito: in d != 0 && n / d > 5, se d vale 0 la divisione non viene mai fatta. L'ordine dei pezzi conta.
  • Per negare una condizione si usa De Morgan: il contrario di a && b è !a || !b. Il ! si attacca a una cosa sola: !x > 5 vuol dire (!x) > 5.
  • Ternario: max = a > b ? a : b; vale a se la condizione è vera, altrimenti b.

Prova tu

Come si scrive la condizione «n non è tra 1 e 100»?

n < 1 || n > 100: per De Morgan è il contrario di 1 <= n && n <= 100.

Da ricordare

  • Vero è 1, falso è 0. Un intervallo si scrive con due confronti e &&.
  • Il cortocircuito protegge la seconda parte: prima il controllo, poi l'operazione.
§5

03D · Decisioni: if ed else (mer 14/10)

Ogni programma si costruisce con tre strutture: sequenza, selezione e iterazione. Per il teorema di Böhm-Jacopini (1966) bastano per qualunque algoritmo. Questa lezione è la selezione.

a > b ?verofalsomax = amax = b
Il massimo di due numeri con if … else: dalla domanda partono due strade, ne viene percorsa una sola, e poi le strade si riuniscono.
  • if (condizione) { … } esegue il blocco solo se la condizione è vera.
  • else è l'altra strada; con else if si entra nel primo blocco con la condizione vera, e gli altri si saltano. All'esame niente switch.
  • Gli errori più comuni: = al posto di == e le graffe dimenticate (con -Wall -Werror tutti e due non compilano), le condizioni nell'ordine sbagliato.
  • Una variabile dichiarata dentro un blocco esiste solo lì: alla } sparisce dallo stack.
  • Gli esempi delle slide con void main() non compilano con -Wall -Werror: si scrive int main(void).
  • Schemi che tornano sempre: il massimo di due numeri, il controllo del valore restituito da scanf, la divisione protetta, il controllo di un intervallo.

Prova tu

Con int voto = 24;, quale blocco esegue if (voto >= 18) { … } else if (voto >= 24) { … } else { … }?

Il primo: voto >= 18 è già vera, e gli altri si saltano. Il secondo blocco non viene mai eseguito, perché le condizioni sono nell'ordine sbagliato: la più stretta va messa prima.

Da ricordare

  • Con else if le condizioni si controllano in ordine, e conta solo la prima vera.
  • Per seguire un programma con gli if, scrivi i valori delle variabili prima di ogni domanda.
§6

Verso l'esame

esame
  • Correttezza di una sequenza di assegnazioni: si ragiona all'indietro dalla post-condizione. Lo scambio con temp è un esercizio perfetto per allenarsi.
  • Stato della memoria: una riga per variabile, i valori aggiornati a ogni assegnamento. Attenzione alle conversioni: un double messo in un int perde la parte dopo la virgola.
  • Programmazione: i test di CodeRunner confrontano le stampe. Una media divisa per 3 invece che per 3.0, o un %f al posto di %lf in scanf, fanno fallire i test.
  • Appelli 2026/27: lunedì 25/01/2027 e giovedì 11/02/2027, alle 9:00.
§7

Domande di ripasso

autoverifica

Rispondi a voce alta o per iscritto, poi apri la risposta.

Quanto valgono 99 / 50, 99 % 50 e 99 / 50.0?

1, 49 e 1.98.

Perché x = y; y = x; non scambia le due variabili?

Perché il primo assegnamento cancella il vecchio valore di x: alla fine tutte e due valgono il vecchio y.

Con quale specificatore si legge un double con scanf?

%lf. Con %f scanf scriverebbe un float nella casella di un double.

Che cosa vale float z = 5 / 2;?

2.000000: la divisione è tra interi e fa 2, poi il 2 viene convertito.

Come si scrive in C «x è tra 0 e 10»?

0 <= x && x <= 10.

Perché d != 0 && n / d > 5 non divide mai per zero?

Per il cortocircuito: se d vale 0 la prima parte è falsa, e la seconda non viene calcolata.

Quali sono le tre strutture del teorema di Böhm-Jacopini?

Sequenza, selezione e iterazione.

§8

Quiz d'esame

come all'esame

L'esame di Programmazione I non ha domande a crocette. Ha due esercizi di teoria su CodeRunner, «correttezza di una sequenza di assegnazioni» e «stato della memoria», e tre di programmazione. Le domande qui sotto sono sul modello di questi esercizi, con gli argomenti della settimana: le prime due come l'esercizio «Corr. Ass. 1» della pagina Moodle 2023/24, le altre come lo stato della memoria e gli errori che fanno fallire i test. Ho compilato e provato tutto con gcc 16.1 e -Wall -Werror.

  1. Sul modello di «Corr. Ass. 1», ragionamento all'indietro. Il programma esegue temp = x;, poi x = y;, poi y = temp;. Alla fine deve valere x == 3 && y == 8. Quale pre-condizione serve all'inizio?
  2. Sul modello di «Corr. Ass. 1», con lo scambio sbagliato. Il programma esegue x = y; e poi y = x;. Alla fine deve valere x == 5 && y == 5. Qual è la pre-condizione più debole?
  3. Sul modello dello stato della memoria. Dopo int a = 7, b = 2; double m = a / b; double n = (double)a / b; int k = n; quanto valgono m, n e k?
  4. Sul modello dello stato della memoria. Dopo questo codice quanto valgono x e y? int x = 7, y = 3; if (x > y) { int t = x; x = y; y = t; } if (x % 2 == 0) { x = x + 10; } else if (y > 5) { y = y - 5; } else { x = 0; }
  5. Sul modello degli errori che fanno fallire i test. Con int d = 0, n = 10; bool ok = d != 0 && n / d > 5;, che cosa stampa printf("%d", ok);?
  6. Sul modello degli errori di compilazione. Con int x = 50;, che cosa succede compilando con gcc -Wall -Werror un programma che contiene printf("%d", 0 <= x <= 10);?
  7. Sul modello degli errori che fanno fallire i test. Dopo int a = 4, b = 5, c = 5; double m = (a + b + c) / 3;, che cosa stampa printf("%.2f", m);?
  8. Sul modello del Laboratorio 02. Che cosa stampa printf("%d", (int)(8.136 * 1000));?