Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 45 di 47
  • livello principiante
Indice lezioni

Errori comuni e regole di stile in C

Come evitare gli errori e come scrivere un buon codice in linguaggio C
Come evitare gli errori e come scrivere un buon codice in linguaggio C
Link copiato negli appunti

Ecco alcuni degli errori in cui si incappa più frequentemente quando si programma in C. È utile elencare queste cose perché tipicamente sono quelle che fanno scervellare i programmatori per ore perché sono imperfezioni del codice a volte insidiose e mimetiche.

  • Assegnazione (=) al posto del confronto (==) - Bisogna porre attenzione, quando, utilizzando una struttura condizionale come IF-ELSE, scriviamo l'operazione di confronto (==), poiché essa può, per un errore di battitura, diventare un assegnamento (=); se ciò dovesse accadere, ad esempio, cercando di confrontare se due numeri sono uguali, potremmo trovarci nella spiacevole situazione in cui, invece di controllare se a == b, che restituisce true (in C un numero diverso da 0) solamente quando le due variabili hanno lo stesso valore, poniamo a = b, che è true praticamente sempre a meno che non si assegni a b uno 0, il che diventa mimetico al massimo.
  • Mancanza di parentesi ( ) per una funzione - Il programmatore inesperto tende a credere che una funzione alla quale non si passano parametri non debba avere le parentesi tonde; ciò è errato, le parentesi tonde, anche senza parametri, devono essere sempre messe.
  • Indici di Array - Quando si inizializzano o si usano gli array, bisogna porre attenzione agli indici utilizzati (e quindi alla quantità di elementi) poiché se si inizializza un array con N elementi, il suo indice deve avere un intervallo tra 0 (che è il primo elemento) ed N-1 (che è l'n-mo elemento).
  • Il C è Case Sensitive - Il linguaggio C (come C++ e Java) fa distinzione tra lettere maiuscole e minuscole, interpretandole come due caratteri diversi; bisogna quindi stare attenti, soprattutto quando si utilizzano le variabili.
  • Il ";" chiude ogni istruzione - È un errore tanto comune che non può non essere citato, ogni istruzione deve essere chiusa con un punto e virgola; questa facile dimenticanza (Nda: che colpisce anche i più esperti :) ), segnalata dal compilatore, può far perdere del tempo prezioso ed appesantisce inutilmente il lavoro del programmatore.
  • I nomi delle variabili, strutture, costanti e funzioni devono essere significativi - poiché le parole chiave del linguaggio sono in inglese, si consiglia di utilizzare nomi, per le variabili e le funzioni, in lingua italiana, in modo da poter capire, dal nome stesso, se quello che stiamo usando è effettivamente una parola chiave del linguaggio o un costrutto creato all'interno del nostro programma. Inoltre sarebbe buona norma, se il nome è composto da più parole, evidenziare con iniziali maiuscole le parole seguenti la prima; questa regola non vale, invece, per le costanti, che devono essere scritte tutte in maiuscolo e separate, se formate da più di una parola, dal carattere underscore "_".
  • Uso, funzione e posizione dei commenti - I commenti devono accompagnare quasi tutte le istruzioni, per spiegare il significato di ciò che stiamo facendo, inoltre devono essere sintetici e devono essere aggiornati appena modifichiamo un'istruzione. I commenti devono essere più estesi, invece, se devono spiegare un determinato algoritmo o se accompagnano una funzione.
  • Espressione ternaria - L'espressione ternaria <cond> ? <val> : <val> è, generalmente, sostitutiva di un costrutto if-else e restituisce il primo valore se l'espressione è vera (true) o il secondo se, invece, è falsa (false). L'espressione ternaria va messa, se possibile, sulla solita riga e, per evitare problemi, è consigliabile racchiudere tra parentesi tonde sia l'espressione sia i valori.
  • Ogni sorgente dovrebbe contenere, nell'ordine:
    1. Commento iniziale (con nome del file, nome dell'autore, data, testo del problema ed eventuali algoritmi usati);
    2. Istruzioni #include per tutti i file da includere (bisogna includere solo i file necessari);
    3. Dichiarazioni di constanti, strutture e tipi enumerativi;
    4. Definizione di variabili;
    5. Prototipi delle funzioni;
    6. Definizione delle funzioni (con la funzione main messa come prima funzione).
  • Uso delle parentesi graffe { } - Nelle dichiarazioni di tipi (StrUCT, UNION, ENUM) o nelle inizializzazioni di variabili all'interno delle definizioni la { che apre il blocco va posta di seguito al nome del tipo, vicino all'uguale dell'inizializzazione, sulla stessa riga; la graffa di chiusura andrà allineata con l'inizio della dichiarazione, su di una riga a sé stante.
    Nelle funzioni o nei costrutti IF/ELSE, FOR, WHILE, SWITCH la { di apertura del blocco va allineata sotto la prima lettera del costrutto, mentre nel costrutto do-while la { va sulla medesima riga del DO. La } di chiusura del blocco va allineata esattamente sotto la { di apertura, tranne nel do dove la } di chiusura va allineata sotto la D di do, seguita dal while.
    Tutte le istruzioni contenute in un blocco vanno indentate rispetto all'allineamento del blocco stesso (che sia la { di apertura o il do), tranne per le dichiarazione di variabili locali che vanno allineate sotto la { (o il do). Per evitare di avere sorgenti che eccedano la larghezza dello schermo è preferibile indentare di un paio di spazi, invece che di un tab.
  • Uso e commento delle funzioni - Una funzione deve eseguire un compito e non è semanticamente corretto scrivere funzioni che contengano il codice per fare molte cose assieme. È, piuttosto, conveniente scrivere le funzioni per i singoli compiti ed una ulteriore funzione che svolga il compito complesso, richiamando le funzioni precedenti.
    Prima di ogni funzione, eccetto che per il main, è necessario fare un commento che contenga:

    • Scopo della funzione;
    • Significato e valori leciti per ognuno dei parametri;
    • Valori di ritorno nei vari casi;
    • Eventuali parametri passati per riferimento modificati all'interno della funzione;
    • Eventuali effetti collaterali sulle variabili globali.

Esempio Pratico

(Visualizza il sorgente completo)

Prendendo spunto dai contenuti di questa lezione, si può notare che il codice di esempio contiene moltissimi commenti, sia per descrivere le azioni od il ruolo di un determinato oggeto (cosa rappresenta una variabile o cosa fa una funzione), sia per segnare l'inizio o la fine di alcune parti di codice (delimitazioni di apertura e chiusura delle funzioni, degli IF e dei cicli FOR).

[Intestazione Iniziale che descrive il programma]
0   /*
1    * Nome del file: rubrica.c
2    * Autore - Fabrizio Ciacchi
3    * Dicembre 2003
4    * Rubrica dimostrativa per Html.it
5    * Il programma genere un file rubrica.txt in formato CSV, Comma
6    * Separated Value, e quindi permette ad Outlook o Mozilla di
7    * importare i contatti.
8    */

[...]
[Spiegazione e commento di apertura di una funzione]

213  /*
214   * Aggiungo un nuovo contatto
215   */
216  struct elemento *aggiungiContatto(struct elemento *p)
217  { // aggiungiContatto() - OPEN

[...]
[Commento di apertura e chiusura di un IF]

441  if(subscelta == 1)
442  { // IF - OPEN
[...]
446  } // IF - CLOSE

Ti consigliamo anche