Lezione 7 di 7 · 20 min di lettura

Riepilogo e sfida finale

Tutto il modulo in una tabella, tre quiz di controllo e una sfida con FizzBuzz, numeri primi e primi gemelli.

Da lista a programma

All’inizio del modulo i tuoi programmi erano liste di istruzioni, eseguite tutte, in fila. Adesso sai:

  • far scegliere il programma con if, else e switch;
  • far ripetere il lavoro con while, do, for e foreach;
  • fermare o saltare un ciclo con break e continue, anche su cicli esterni con un’etichetta;
  • tenere tanti valori in un array e scorrerli;
  • scrivere funzioni tue, con parametri, valori di ritorno e argomenti per nome.

Con queste cose, ed è la parte sorprendente, puoi già scrivere qualsiasi algoritmo. Decidere e ripetere è tutto ciò che serve a una macchina per calcolare: il resto del corso ti darà strumenti per farlo meglio, più in sicurezza e più comodamente, ma i mattoni fondamentali ce li hai.

La pagina da tenere accanto

CosaCome si scrive
Decisioneif (cond) { ... } else if (cond) { ... } else { ... }
If su una rigaif (n < 0) n = -n; (senza else, sulla stessa riga)
TernarioString s = n > 0 ? "pos" : "neg";
Valore di riservaint v = choice ?: 50;
Switchswitch (x) { case 1: ... case 2..5: ... default: ... }
Più valori, un casocase 6: vuoto seguito da case 7:
Proseguire nel caso doponextcase;
Switch di condizioniswitch { case x < 0: ... case x < 10: ... }
Ciclo con condizionewhile (cond) { ... }
Almeno una voltado { ... } while (cond);
Ciclo che contafor (int i = 0; i < n; i++) { ... }
Uscire / saltare un girobreak; / continue;
Uscire da un ciclo esternofor OUTER: (...) { ... break OUTER; }
Arrayint[*] a = { 1, 2, 3 }; con a[0] e a.len
Scorrereforeach (x : a), foreach (i, x : a), foreach_r (x : a)
Funzionefn int square(int x) { return x * x; }
Funzione cortafn bool is_even(int n) => n % 2 == 0;
Predefiniti e per nomefn void f(int a, int b = 1) chiamata come f(5, b: 2)

Cinque errori che ormai riconosci

Il compilatore di C3 ti ha protetto spesso, in questo modulo. Ecco i messaggi più comuni, e cosa significano:

MessaggioCosa hai fatto
if-statements with an 'else' must use '{ }'...Un if con else senza graffe
'x' would shadow a previous declaration.Hai dichiarato una variabile con un nome già in uso
'i' could not be found...Stai usando una variabile fuori dal suo blocco (o dopo il suo for)
Missing return statement at the end of the function.Una strada della funzione non arriva a un return
The same case value appears more than once.Due case con lo stesso valore, o intervalli sovrapposti

Quiz di controllo

Quiz

Cosa stampa questo ciclo? for (int i = 0; i < 5; i++) { if (i == 3) break; io::printf("%d", i); }

Quiz

Quanto vale n alla fine? int n = 1; while (n < 100) n *= 3;

Quiz

Con int x = 4;, cosa stampa? switch (x) { case 1..3: io::print("low "); case 4..6: io::print("mid "); nextcase; case 7..9: io::print("high "); default: io::print("out "); }

La sfida: numeri con carattere

Un programma intero, da zero. Usa funzioni, switch, cicli, continue e una costante.

Esercizio · sul tuo computer

Numeri con carattere

Scrivi numbers.c3 con una costante const int LIMIT = 50; e due funzioni.

1. FizzBuzz. È il più famoso esercizio dei colloqui di lavoro per programmatori. Scrivi fn void fizzbuzz(int n) che stampa, senza andare a capo: FizzBuzz se n è divisibile per 15, Fizz se è divisibile per 3, Buzz se è divisibile per 5, altrimenti il numero stesso. Usa uno switch senza espressione (attenzione all’ordine dei case!). Nel main, chiamala per i numeri da 1 a 15, separandoli con uno spazio ma senza spazio finale.

2. Numeri primi. Un numero è primo se è maggiore di 1 ed è divisibile solo per 1 e per se stesso. Scrivi fn bool is_prime(int n): prova a dividere n per ogni d da 2 in su, finché d * d <= n; se una divisione ha resto zero, non è primo.

Poi, nel main:

  • stampa Primes: seguito da tutti i primi da 2 a LIMIT, ognuno preceduto da uno spazio (usa continue per saltare quelli non primi);
  • stampa Count: con quanti sono, e , sum: con la loro somma;
  • conta le coppie di primi gemelli: primi che differiscono di 2, come 11 e 13, con entrambi ≤ LIMIT. Stampa Twin pairs: e il conteggio.

L’output atteso, carattere per carattere:

output
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz
Primes: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47
Count: 15, sum: 328
Twin pairs: 6
Mostra una soluzione (prima prova da solo!)
numbers.c3
import std::io;

const int LIMIT = 50;

fn void fizzbuzz(int n)
{
	switch
	{
		case n % 15 == 0:
			io::print("FizzBuzz");
		case n % 3 == 0:
			io::print("Fizz");
		case n % 5 == 0:
			io::print("Buzz");
		default:
			io::printf("%d", n);
	}
}

fn bool is_prime(int n)
{
	if (n < 2) return false;
	for (int d = 2; d * d <= n; d++)
	{
		if (n % d == 0) return false;
	}
	return true;
}

fn void main()
{
	for (int i = 1; i <= 15; i++)
	{
		if (i > 1) io::print(" ");
		fizzbuzz(i);
	}
	io::printn();

	io::print("Primes:");
	int count = 0;
	int sum = 0;
	for (int n = 2; n <= LIMIT; n++)
	{
		if (!is_prime(n)) continue;
		io::printf(" %d", n);
		count++;
		sum += n;
	}
	io::printn();
	io::printfn("Count: %d, sum: %d", count, sum);

	int twins = 0;
	for (int p = 2; p + 2 <= LIMIT; p++)
	{
		if (is_prime(p) && is_prime(p + 2)) twins++;
	}
	io::printfn("Twin pairs: %d", twins);
}

I punti delicati:

  • L’ordine dei case in FizzBuzz: il 15 va controllato per primo, altrimenti vincerebbe n % 3 == 0 e non stamperesti mai FizzBuzz.
  • d * d <= n in is_prime: se n ha un divisore più grande della sua radice quadrata, ne ha per forza anche uno più piccolo, già provato. Per n = 47 bastano 5 tentativi invece di 45.
  • Lo spazio senza spazio finale: lo spazio si stampa prima di ogni numero tranne il primo.

Cosa succede nel Modulo 3

In questo modulo hai visto gli array solo di sfuggita, e le stringhe solo come testo da stampare. Il prossimo modulo è dedicato proprio a loro: array, slice e stringhe. Imparerai a tagliare un array a pezzi senza copiarlo, a passare collezioni alle funzioni, a costruire e trasformare testo, e scoprirai finalmente come funzionano davvero le stringhe in memoria.

Segna questa lezione come completata e prenditi un meritato caffè (con l’accento: ormai sai che sono due byte).