Lezione 03 di Programmazione 1, 11 settembre 2026. Slide: 2.2 Introduzione al C, slide 1-56 e 64-65. Prima: Architettura hardware e software di un calcolatore. Dopo: Espressioni, operatori e costanti, che copre il resto del deck (slide 57-76: espressioni, precedenze, ++ e --, costanti, caratteri e ASCII).
Il filo della lezione:
linguaggio di programmazione sintassi (forma) + semantica (significato)
|
v
livelli di astrazione linguaggio macchina -> assembly -> C
|
v
compilare o interpretare il C si compila
|
v
macchina astratta C memoria a celle, standard input e output
|
v
dal sorgente all'eseguibile editor -> preprocessore -> compilatore -> linker -> loader
|
v
lessico case sensitive, spazi, commenti, identificatori, keyword
|
v
struttura di un programma main { istruzioni; }
|
v
variabili nome, tipo, l-value (dove), r-value (cosa)
|
v
assegnazione valuta a destra, scrivi a sinistra
1Concetti
1.1Linguaggio di programmazione
Un algoritmo scritto in linguaggio naturale va tradotto in un linguaggio che l’esecutore, il computer, capisce (slide 2-3). La sequenza di istruzioni in quel linguaggio è il programma. Per non lasciare ambiguità il linguaggio deve essere preciso e rigoroso su due piani.
Le due cose sono indipendenti:
x = x + 1;ex = 1 + x;sono stringhe diverse, entrambe sintatticamente corrette, e hanno la stessa semantica: aumentano di uno.x = x + 1senza punto e virgola ha un errore di sintassi: il compilatore lo rifiuta.media = somma / 0;è sintatticamente corretta ma semanticamente sbagliata: si compila, e il problema esce quando la esegui.
La grammatica completa del C sta nell’appendice E del libro di testo (slide 39).
1.2Livelli di astrazione
Fra il programmatore, che conosce il problema, e la macchina, che capisce solo circuiti a due valori (0 e 1), c’è il linguaggio di programmazione. Il suo livello di astrazione è una scelta (slide 4-6): troppo vicino alla macchina e programmare è difficile, troppo vicino al programmatore e i programmi diventano inefficienti.
La stessa istruzione, “il totale è la paga più gli straordinari”, a tre livelli:
C TOT = PAGA + STRAORD; alto
|
assembly LOAD PAGA |
ADD STRAORD |
STORE TOT |
v
linguaggio 0100001111 basso
macchina 1100111001
0110001111
In assembly si vede il lavoro della CPU visto in Architettura hardware e software di un calcolatore: carica un valore, somma, salva in una cella. In C basta una riga.
Cosa chiediamo a un linguaggio (slide 9):
- astrazione della memoria: riferirsi alle celle con nomi simbolici (
totale) invece che con indirizzi binari; - astrazione delle istruzioni: scrivere operazioni complesse, come un’espressione aritmetica, in una forma leggibile;
- astrazione dell’algoritmo: poter esprimere direttamente sequenza, scelta e ripetizione.
Macchina fisica (slide 8). Una macchina fisica esegue istruzioni nel suo linguaggio, il codice macchina. A una macchina corrisponde un linguaggio (il suo), ma un linguaggio in generale può essere eseguito da più macchine. Il cuore della macchina fisica è il ciclo fetch-decode-execute, che fa da interprete del codice macchina.
1.3Il linguaggio C
(slide 14-17)
- Creato nel 1972 da Dennis Ritchie ai Bell Labs, evoluzione dei linguaggi BCPL e B. La slide 14 dice “inventato da Brian Kernighan e Dennis Ritchie”: è sbagliato, il linguaggio è di Ritchie. Kernighan è coautore con Ritchie del libro di riferimento, The C Programming Language (1978, seconda edizione 1988, citato nella slide 15).
- Nato come linguaggio di sistema per scrivere Unix, oggi usato per sistemi operativi (Linux, Windows, macOS), compilatori, editor, e in generale ovunque serva efficienza.
- Standard ANSI nel 1989 (C89, detto anche ANSI C), aggiornato nel 1999 (C99). Le slide si fermano qui, ma dopo sono usciti C11 (2011, quello che usiamo con
-std=c11), C17 (2018, solo correzioni) e C23 (2024). - Portabile: lo stesso codice si compila su macchine diverse.
- Linguaggio di medio livello: più astratto dell’assembly, più vicino alla macchina di Pascal o Ada. Efficiente, ma a volte “troppo” vicino alla macchina.
| Livello | Linguaggi |
|---|---|
| alto | Ada, Pascal, BASIC |
| medio | C, FORTH |
| basso | assembly |
Il C++ (Stroustrup, Bell Labs) è un’evoluzione del C: aggiunge astrazione sui dati, programmazione a oggetti e la Standard Template Library.
1.4Compilazione e interpretazione
Un programma scritto in un linguaggio si può eseguire in due modi (slide 19):
| Compilazione | Interpretazione | |
|---|---|---|
| cosa fa | traduce tutto il programma in un altro linguaggio (per esempio codice macchina), senza eseguirlo | esegue direttamente il codice sorgente, un’istruzione alla volta |
| esecuzione | veloce: la decodifica è già stata fatta | più lenta: ogni istruzione va decodificata mentre gira |
| costo | la traduzione può richiedere tempo | nessuna traduzione a parte |
| pro | efficienza, ottimizzazioni | flessibilità, portabilità, interattività (debug a run-time) |
| contro | poca flessibilità, si perde informazione sulla struttura del sorgente | scarsa efficienza |
Il C è un linguaggio compilato. Python, per confronto, è interpretato.
Macchina astratta (slide 21-23). Dato un linguaggio , la macchina astratta è un qualsiasi insieme di strutture dati e algoritmi capace di memorizzare ed eseguire programmi scritti in . È un’astrazione del calcolatore e delle sue risorse: memoria (dati e programma), controllo della sequenza, controllo dei dati, gestione della memoria, operazioni. Il componente essenziale è l’interprete:
start
|
v
+-> acquisisci la prossima istruzione
| |
| v
| decodifica
| |
| v
| acquisisci gli operandi
| |
| v
| seleziona l'operazione ---------------------+
| | | | |
| v v v v
| esegui OP1 esegui OP2 ... esegui OPn esegui HALT
| | | | |
| +----------+------------+ v
| | stop
| v
+-- memorizza il risultato
È lo stesso ciclo fetch-decode-execute della CPU, scritto per un linguaggio qualsiasi.
La macchina astratta C (slide 26). Il programma C non gira direttamente: il compilatore lo traduce nel linguaggio della macchina ospite , che poi lo esegue interpretandolo con il suo ciclo fetch-decode-execute.
programma C --compilazione--> binario per Mo --interpretazione (CPU)--> esecuzione
1.5Dal sorgente all’eseguibile
(slide 27-29)
| Fase | Chi | Cosa succede |
|---|---|---|
| Edit | editor | scrivi il programma e lo salvi su disco (ciao.c) |
| Preprocess | preprocessore | elabora le direttive che iniziano con #: per esempio #include <stdio.h> viene sostituito dal contenuto del file. Il risultato è un sorgente “espanso” |
| Compile | compilatore | traduce il sorgente in codice oggetto (ciao.o) e lo salva su disco. Qui escono gli errori di sintassi |
| Link | linker | collega il tuo codice oggetto con altro codice già disponibile, le librerie (per esempio quella che contiene printf), e produce l’eseguibile |
| Load | loader | carica l’eseguibile dal disco nella memoria centrale |
| Execute | CPU | prende un’istruzione alla volta e la esegue, eventualmente scrivendo nuovi valori in memoria |
Su Linux con gcc un solo comando fa preprocessore, compilazione (con l’assemblatore, che le slide non nominano a parte) e link. L’editing lo fai tu prima, il caricamento e l’esecuzione partono quando lanci il programma:
gcc -std=c11 -Wall -Wextra -Wpedantic ciao.c -o ciao
./ciao
-Wall -Wextra -Wpedantic accendono gli avvisi (warning): il compilatore segnala anche cose che si compilano ma sono probabilmente sbagliate.
1.6Il primo programma
Le slide propongono di provarlo su onlinegdb.com scegliendo il C (slide 10):
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("Hello World!\n");
}
| Pezzo | Significato |
|---|---|
#include <stdio.h> | direttiva per il preprocessore: include la libreria di input/output standard, dove sono dichiarate printf e scanf |
int main(int argc, char *argv[]) | intestazione: main è il punto da cui parte l’esecuzione. argc e argv sono gli argomenti passati da riga di comando |
{ ... } | il corpo: la sequenza di istruzioni |
printf("Hello World!\n"); | stampa la stringa sullo standard output. \n è il carattere “a capo” |
; | chiude ogni istruzione |
Compilato con -Wextra, gcc avvisa che argc e argv non sono usati. Quando non servono si può scrivere l’intestazione senza parametri. return 0; dice al sistema operativo che il programma è terminato bene. Dal C99 arrivare alla } finale di main senza return equivale a return 0;, quindi il programma della slide è corretto; scriverlo esplicitamente resta buona pratica, ed è quello che fanno i programmi del prof nel deck 3.2:
#include <stdio.h>
int main(void)
{
printf("Hello World!\n");
return 0;
}
Esercizio dalle slide (slide 28): togli pezzi al programma, per esempio il ; o il \n nella riga di printf, e leggi i messaggi di errore o il cambiamento nell’output.
1.7Standard I/O e memoria
La macchina astratta C ha un’unità centrale che esegue il programma, una memoria centrale e due periferiche standard, tutte sul bus (slide 30-33).
bus di sistema
============================================================
| | | |
+---------+ +---------+ +----------+ +----------+
| unità | x ->| cella | | [][][][] | | [][][][] |
| centrale| a ->| cella | | standard | | standard |
+---------+ alfa->| cella | | input | | output |
| ... | | tastiera | | video |
+---------+ +----------+ +----------+
memoria centrale
Standard input e standard output. Il C astrae le periferiche. Ogni programma ha due periferiche standard:
- standard input (
stdin), di solito la tastiera; - standard output (
stdout), di solito lo schermo.
Si possono pensare come sequenze di celle, ognuna con un dato, da cui leggere (input) o in cui scrivere (output).
Memoria. La memoria della macchina astratta è divisa in celle elementari, le variabili. Ogni cella contiene un dato usato dal programma. Si guarda solo la memoria dati: dove sta il codice del programma per ora non interessa.
I dati possono essere:
- numeri;
- caratteri;
- stringhe, cioè successioni finite di caratteri in celle consecutive;
- composizioni arbitrarie delle precedenti.
Come viene gestita la memoria per ora non conta. Conta come ci si riferisce a queste celle: con gli identificatori.
1.8Lessico
Case sensitive. Il C distingue maiuscole e minuscole (slide 34-35): Var1, var1 e VAR1 sono tre nomi diversi.
Spazi. Spazio, tab e a capo (newline) vengono ignorati, tranne dentro una stringa. Servono solo a rendere il codice leggibile. Queste due righe sono lo stesso programma per il compilatore:
x=3;myVar=5;
x = 3;
myVar = 5;
Ma "ciao mondo" e "ciaomondo" sono stringhe diverse.
Tabella ASCII. I caratteri sono memorizzati come numeri secondo la codifica ASCII: ogni carattere ha un codice. Il primo carattere della tabella, codice 0, è NUL, un carattere speciale che non si stampa.
Commenti. Testo ignorato dal compilatore, per chi legge il codice.
/* ... */: commento a blocco, può occupare più righe;// ...: commento in linea, finisce a fine riga.
Identificatori (slide 37, slide 48). Sono i nomi che il programmatore dà a variabili, funzioni e altri oggetti. Regole:
- composti da lettere, cifre e underscore
_; - il primo carattere è una lettera o
_, mai una cifra; - diversi da tutte le parole chiave.
| Validi | Non validi |
|---|---|
a, x, alfa, a1, xy23 | 1a (inizia con una cifra) |
MyFriend, DopoDomani | a b (contiene uno spazio) |
velocita_massima, _velocita | int (parola chiave) |
dopo-domani (il - è un operatore) |
Parole chiave (keyword). Parole riservate del linguaggio, con un significato fissato a priori: non si possono usare come identificatori anche se lessicalmente andrebbero bene. L’ANSI C del 1989 ne ha 32 (slide 38):
auto break case char const continue default do
double else enum extern float for goto if
int long register return short signed sizeof static
struct switch typedef union unsigned void volatile while
Il numero 32 vale per il C89. Gli standard successivi ne hanno aggiunte: il C99 inline, restrict, _Bool, _Complex, _Imaginary; il C11 _Alignas, _Alignof, _Atomic, _Generic, _Noreturn, _Static_assert, _Thread_local; il C23 fra le altre bool, true, false, nullptr. Alcuni compilatori aggiungono estensioni proprie. Se usi una keyword come nome, l’editor o il compilatore segnalano errore.
1.9Struttura di un programma
(slide 40)
#include <stdio.h> direttive per il preprocessore
int main(int argc, char *argv[]) intestazione
{
istruzione; sequenza di istruzioni
istruzione; fra { e }, ognuna chiusa da ;
...
}
Un programma C è composto da:
- un’intestazione, con l’identificatore predefinito
mainseguito da(int argc, char *argv[]); - una sequenza di istruzioni racchiusa fra
{e}.
Le istruzioni sono le frasi del linguaggio, e ognuna termina con ;.
1.10Istruzioni di input/output
Senza input e output un programma sarebbe inutile per l’utente: non potrebbe ricevere dati né mostrare risultati (slide 41-42).
| Istruzione | Direzione | Forma nelle slide |
|---|---|---|
scanf | legge dallo standard input e mette il dato in una variabile | scanf(<variabile>) |
printf | scrive sullo standard output il valore di un’espressione | printf(<espressione>) |
Entrambe stanno nella libreria stdio.h, che va inclusa con #include <stdio.h>.
La forma delle slide (scanf(&x);, printf((a-z)/10);) è semplificata per mostrare l’idea. In C vero serve anche una stringa di formato che dice il tipo del dato: %d per un intero.
#include <stdio.h>
int main(void)
{
int a;
int z;
if (scanf("%d", &a) != 1 || scanf("%d", &z) != 1) {
printf("servono due numeri interi\n");
return 1;
}
printf("%d\n", (a - z) / 10);
return 0;
}
Con input 57 e 7 stampa 5: .
Il valore di ritorno di scanf. scanf restituisce quanti valori è riuscita a leggere e assegnare: 1 se ha letto il numero, 0 se l’input non è un numero (per esempio ciao), EOF se l’input è finito. Se non lo controlli e l’input è sbagliato, la variabile resta com’era, cioè senza valore, e il programma va avanti con quella. Con input ciao il programma sopra stampa il messaggio d’errore invece di un numero a caso. Il || valuta la seconda scanf solo se la prima è andata bene (Espressioni, operatori e costanti, lazy evaluation).
Il & davanti alla variabile in scanf vuol dire “l’indirizzo di”. scanf deve sapere dove scrivere il dato letto, non quanto vale la variabile adesso. È il concetto di l-value qui sotto. printf invece ha bisogno solo del valore, quindi niente &.
1.11Variabili
Variabile in C e in matematica (slide 43-46). In matematica una variabile è un simbolo per un valore, e x = x + 1 sarebbe una contraddizione. In un linguaggio di programmazione una variabile è associata a una cella di memoria: un contenitore il cui valore può cambiare durante l’esecuzione. x = x + 1 vuol dire “prendi quello che c’è in , aggiungi 1, rimettilo in ”.
Le variabili sono denotate da identificatori, che servono a distinguerle. Il nome individua l’indirizzo della cella. Per evitare ambiguità è vietato usare:
- lo stesso identificatore per variabili diverse (non sapremmo più quale si intende);
- identificatori diversi per la stessa variabile.
nome l-value r-value
id -> [ cella @1008 ] -> 128
I nomi vengono dal lato dell’assegnazione in cui si usano: a sinistra di = serve un posto dove scrivere (l-value), a destra serve un valore da leggere (r-value). In x = x + 1; la stessa variabile compare due volte con due ruoli: la a destra fornisce il suo valore, la a sinistra fornisce la sua cella.
1.12Dichiarazione
Prima di usare una variabile la si dichiara (slide 49-50). Quando il compilatore incontra la dichiarazione, predispone un’area di memoria grande abbastanza per il tipo scelto.
tipo identificatore;
tipo identificatore = espressione;
Nella notazione delle slide la seconda forma si scrive tipo identificatore [= espressione];: le parentesi quadre indicano una parte facoltativa, non vanno scritte nel codice.
int x;
int y = 3 * 2;
La prima crea una variabile intera senza darle un valore. Finché non le assegni qualcosa il suo valore è indeterminato, e leggerlo è comportamento indefinito: in pratica di solito trovi quello che era rimasto in memoria, ma lo standard non garantisce niente, nemmeno un numero “casuale” ma stabile. Questo vale per le variabili locali, dichiarate dentro main o dentro un blocco. Le variabili globali, dichiarate fuori da ogni funzione, partono invece da 0. La seconda riga crea la variabile già inizializzata a .
1.13Assegnazione
L’espressione a destra può contenere (slide 51-52):
- un valore costante:
10,3.14,'2'(un carattere fra apici singoli); - un identificatore di variabile:
altezza; - una combinazione di espressioni con operatori (
+,-,*,/,%) e parentesi.
#include <stdio.h>
int main(void)
{
int lunghezza;
int altezza;
int peso;
int x = 3 * 2;
char alt;
int a;
int b;
int c;
int d;
lunghezza = 10;
alt = '2';
altezza = lunghezza;
peso = 10 * altezza * (lunghezza + 1);
x = x + 1;
a = b = c = d = 5;
printf("peso = %d, x = %d, alt = %c\n", peso, x, alt);
printf("a = %d, b = %d, c = %d, d = %d\n", a, b, c, d);
return 0;
}
Output:
peso = 1100, x = 7, alt = 2
a = 5, b = 5, c = 5, d = 5
La slide dichiara int a, b, c, d; in una riga sola: è C valido, ma qui si tiene una dichiarazione per riga, che si legge meglio e non inganna con i puntatori (int* p, q; dichiara un puntatore e un intero).
altezza = lunghezza; copia il valore: se dopo cambi lunghezza, altezza resta . '2' è il carattere 2, non il numero 2 (in ASCII vale 50).
Esecuzione (slide 56). Due passi, sempre in quest’ordine:
- si valuta l’espressione a destra di =, ottenendo un r-value;
- si memorizza quel risultato nella cella (l-value) indicata a sinistra.
x = x + 1; con x che vale 6
passo 1: x + 1 -> leggo x (r-value 6), sommo 1 -> 7
passo 2: x = -> scrivo 7 nella cella di x (l-value)
Proprio perché la destra si valuta prima, x = x + 1 ha senso: quando si scrive, il vecchio valore è già stato letto.
Sintassi generale (slide 53-54 e slide 64). La forma “variabile = valore” non copre tutti i casi. La sintassi vera dell’operatore di assegnazione semplice è:
exp1 = exp2
exp1deve essere un’espressione dotata di l-value: deve indicare una cella.x = 5va bene,5 = xex + 1 = 5no, perché5ex + 1sono solo valori, non posti.exp1edexp2devono avere tipi compatibili.- L’assegnazione è essa stessa un’espressione, e il suo valore è quello di
exp2. Quindi si può usare dentro un’altra espressione. - L’operatore = associa a destra.
Per questo funziona l’assegnazione a catena:
a = b = c = d = 5;
equivale a
a = (b = (c = (d = 5)));
Si parte da destra: d = 5 scrive 5 in d e vale 5, quel 5 viene assegnato a c, e così via fino ad a.
Esercizio della slide 65 (slide 64-65, aggiunte nella versione del deck di fine settembre). La slide 64 riprende la catena con cinque variabili, e = d = c = b = a = 1;, che equivale a (e = (d = (c = (b = (a = 1)))));. La 65 la fa provare su onlinegdb: stampa le variabili prima (BEFORE) e dopo (AFTER) la catena. Nel programma della slide a, d ed e sono dichiarate senza valore e stampate nel BEFORE: è proprio il caso del valore indeterminato visto sopra, e gcc con -Wall avvisa ('a' is used uninitialized). Qui sono inizializzate a 0 e la stampa è su una riga:
#include <stdio.h>
int main(void)
{
int a = 0;
int b = 2;
int c = 3 * 2;
int d = 0;
int e = 0;
printf("BEFORE\n");
printf("a=%d b=%d c=%d d=%d e=%d\n", a, b, c, d, e);
e = d = c = b = a = 1;
printf("AFTER\n");
printf("a=%d b=%d c=%d d=%d e=%d\n", a, b, c, d, e);
return 0;
}
Output (verificato):
BEFORE
a=0 b=2 c=6 d=0 e=0
AFTER
a=1 b=1 c=1 d=1 e=1
La catena sovrascrive anche b e c, che avevano già un valore: dopo la riga valgono tutte 1.
2Metodo
Leggere un’assegnazione.
- Guarda a sinistra di =: deve essere una cosa con una cella (l-value). Se è un numero o un’operazione, è un errore.
- Calcola il valore dell’espressione a destra usando i valori attuali delle variabili.
- Scrivi il risultato nella cella a sinistra. Solo adesso la variabile cambia.
- Con più = in fila, parti da quello più a destra.
Tracciare un programma a mano. Fai una tabella con una colonna per variabile e una riga per istruzione, e aggiorna solo la colonna della variabile a sinistra di =. Le variabili dichiarate e non ancora assegnate valgono ”?“.
| istruzione | lunghezza | altezza | peso |
|---|---|---|---|
lunghezza = 10; | 10 | ? | ? |
altezza = lunghezza; | 10 | 10 | ? |
peso = 10 * altezza * (lunghezza + 1); | 10 | 10 | 1100 |
3Esercizi tipo esame
Esercizio 1. Quali di questi identificatori sono validi in C? Per quelli non validi, di’ perché.
_x1 2pi int Int somma totale somma_totale sizeof a-b MAX_VAL
Soluzione
Validi: _x1, Int (diverso da int, il C è case sensitive), somma_totale, MAX_VAL.
Non validi: 2pi (inizia con una cifra), int e sizeof (parole chiave), somma totale (contiene uno spazio: sono due identificatori), a-b (il - è un operatore: il compilatore legge a meno b).
Esercizio 2. Scrivi l’output esatto.
#include <stdio.h>
int main(void)
{
int a = 3;
int b = 4;
int c;
c = a;
a = b;
b = c;
printf("%d %d %d\n", a, b, c);
a = b = c = 2;
a = a + b * c;
printf("%d %d %d\n", a, b, c);
return 0;
}
Soluzione
| istruzione | a | b | c |
|---|---|---|---|
| iniziale | 3 | 4 | ? |
c = a; | 3 | 4 | 3 |
a = b; | 4 | 4 | 3 |
b = c; | 4 | 3 | 3 |
a = b = c = 2; | 2 | 2 | 2 |
a = a + b * c; | 6 | 2 | 2 |
Output: 4 3 3 e poi 6 2 2 (verificato). Le prime tre assegnazioni scambiano a e b usando c come appoggio: senza, a = b; b = a; perderebbe il valore di a.
Esercizio 3. Quali di queste istruzioni sono sbagliate, e che tipo di errore è (sintassi o semantica)?
1) x = 5
2) 5 = x;
3) x + 1 = y;
4) media = somma / 0;
5) Printf("ciao\n");
Soluzione
- Sintassi: manca il
;. - e 3. Il lato sinistro di = deve avere un l-value, cioè essere una cella.
5ex + 1sono solo valori: il compilatore rifiuta (lvalue required). - Sintatticamente corretta, semanticamente sbagliata: si compila (gcc avvisa della divisione per zero) e il problema esplode a run-time.
- Il C è case sensitive:
Printfnon èprintf. gcc segnala una funzione non dichiarata, e il linker non la trova.
Esercizio 4. Scrivi un programma che legge due interi e stampa la somma e la media, con la media decimale.
Soluzione
#include <stdio.h>
int main(void)
{
int x;
int y;
printf("Due interi: ");
if (scanf("%d %d", &x, &y) != 2) {
printf("input non valido\n");
return 1;
}
printf("somma = %d\n", x + y);
printf("media = %f\n", (x + y) / 2.0);
return 0;
}
Con 7 4 stampa somma = 11 e media = 5.500000; con ciao stampa input non valido (verificato). (x + y) / 2 darebbe 5: fra interi la divisione è intera, il 2.0 la rende decimale.
Esercizio 5. SI o NO?
- Il C è un linguaggio interpretato.
- Il linker produce il codice oggetto
.o. /* ... */può occupare più righe.- In
scanf("%d", &x)la&si può togliere. - Una variabile locale non inizializzata vale 0.
Soluzione
- NO, è compilato. 2. NO, il
.olo produce il compilatore; il linker unisce i.oe le librerie nell’eseguibile. 3. SI. 4. NO,scanfha bisogno dell’indirizzo della cella in cui scrivere. 5. NO, il valore è indeterminato (le globali invece partono da 0).
4Errori tipici
- Dimenticare il
;in fondo a un’istruzione: errore di sintassi, spesso segnalato sulla riga dopo. - Dimenticare la
&inscanf: compila (con un avviso) e il programma scrive in una posizione a caso della memoria. - Non controllare il valore di ritorno di
scanf. - Usare una variabile prima di averle dato un valore.
- Scrivere = credendo di confrontare: = assegna, il confronto è ==.
- Confondere
'2'(carattere, codice 50) con2(numero). - Usare una parola chiave come nome di variabile.
5Domande
-
Che differenza c’è fra sintassi e semantica di un linguaggio?
-
Porta un esempio di due istruzioni C sintatticamente diverse con la stessa semantica.
-
Che differenza c’è fra compilazione e interpretazione?
-
Quali sono le fasi dallo scrivere un programma C all’eseguirlo, e cosa fa ciascuna?
-
Cosa fa il linker?
-
Cosa sono standard input e standard output?
-
Quali sono le regole per costruire un identificatore valido in C?
-
Cosa significa che il C è case sensitive?
-
Da quali due parti è composto un programma C?
-
Quali sono le quattro caratteristiche di una variabile?
-
Cosa sono l-value e r-value?
-
In che ordine si esegue un’assegnazione?
-
Perché
a = b = c = 5;è valido e a cosa equivale? -
Perché in
scanf("%d", &x)serve la&davanti ax?