Tipo Booleano in Linguaggio C

Il linguaggio C considera qualunque valore diverso da zero come vero. Tuttavia, per anni, non è esistito un tipo di dato propriamente booleano. In questo articolo vedremo come rappresentare valori booleani in C89 e in C99.

Valori Booleani in C89

Per anni, nel linguaggio C mancava un tipo propriamente booleano, ossia un tipo di dato in grado di memorizzare un valore vero o falso.

Abbiamo visto che il C considera come vero tutto ciò che è diverso da zero, per cui una soluzione a questo problema è stata quella di adoperare variabili di tipo int per memorizzare 0, quindi falso, oppure 1, quindi vero.

Quindi, ad esempio, una variabile booleana, in gergo tecnico flag, poteva essere rappresentata in C in questo modo:

int flag;

flag = 0; /* falso */

/* ... */

flag = 1; /* vero */

Sebbene questa tecnica funzioni, non è la soluzione più leggibile. Anche perché non è immediatamente chiaro che alla variabile flag possiamo assegnare solo i valori 0 e 1 e che tali valori rappresentino rispettivamente falso e vero.

Spesso, quindi, nei programmi scritti per i compilatori C89, i programmatori tendevano a definire delle macro semplici con i nomi TRUE e FALSE:

#define TRUE 1
#define FALSE 0

Per cui l'assegnamento di variabili booleani assumeva un aspetto molto più leggibile:

int flag;

flag = FALSE; /* falso */

/* ... */

flag = TRUE; /* vero */

Fatto questo, possiamo testare la variabile flag in un'istruzione if:

if (flag == TRUE) {
    printf("La variabile flag è vera\n");
} else {
    printf("La variabile flag è falsa\n");
}

Oppure, in modo più compatto, possiamo scrivere:

if (flag) {
    printf("La variabile flag è vera\n");
} else {
    printf("La variabile flag è falsa\n");
}

Quest'ultima forma, in particolare, è quella forse più corretta dal momento che, come abbiamo visto, in C qualsiasi valore diverso da zero è considerato vero. Di conseguenza, se per errore alla variabile flag assegniamo un valore diverso da 0 o 1, l'istruzione if funzionerà comunque correttamente.

Analogamente, per testare la falsità di una variabile booleana, possiamo scrivere:

if (!flag) {
    printf("La variabile flag è falsa\n");
} else {
    printf("La variabile flag è vera\n");
}

In questo caso, l'operatore ! (not) inverte il valore della variabile flag, quindi se flag è 0, !flag sarà 1, e viceversa.

Quest'idea di utilizzare int per rappresentare valori booleani è stata, spesso, portata fino ad un grado successivo in cui si definiscono delle macro per rappresentare il tipo booleano in questo modo:

#define BOOL int

#define TRUE 1
#define FALSE 0

BOOL flag;

flag = FALSE; /* falso */

/* ... */

flag = TRUE; /* vero */

In questo modo si rendeva ancora più esplicito il fatto che la variabile flag fosse di tipo booleano, anche se in realtà era di tipo int.

Vedremo nelle prossime lezioni delle tecniche più raffinate per definire un tipo booleano in C, come le enumerazioni e le definizioni di tipi personalizzati.

Valori Booleani in C99 e oltre

La mancanza di un tipo booleano in C è stata definitivamente risolta nello standard C99, che ha introdotto un nuovo tipo di dato chiamato _Bool.

Nello standard C99, possiamo dichiarare, quindi, una variabile booleana in questo modo:

_Bool flag;

Internamente, una variabile di tipo _Bool non è altro che un intero, precisamente un unsigned int. Tuttavia, a differenza di una normale variabile intera, essa può assumere solo i valori 0 e 1. In generale, se proviamo ad assegnare ad una variabile _Bool un valore diverso da 0, il compilatore provvede in automatico ad assegnare il valore 1.

Ad esempio, possiamo scrivere:

_Bool flag;

flag = 8; /* flag assume il valore 1 */

Essendo, nella pratica, degli interi, è possibile effettuare delle operazioni matematiche su variabili di tipo _Bool. Tuttavia, è buona norma evitare di farlo, ed usare tali variabili solo per valutare condizioni.

Inoltre, è possibile stampare tali variabili utilizzando il formato %d:

printf("Il valore di flag è %d\n", flag);

In questo caso il valore di flag verrà stampato come 1.

Definizione

Tipo di dati _Bool

Il tipo di dati _Bool è un tipo di dato introdotto nello standard C99 per rappresentare valori booleani. Il tipo _Bool può assumere solo due valori: 0 e 1, che rappresentano rispettivamente i valori falso e vero.

Il nome dato al tipo di dato _Bool può sembrare a prima vista strano. Perché, infatti, non usare un nome più semplice come bool? La risposta è che, quando fu definito lo standard C99, bisognava mantenere la retrocompatibilità con i vecchi programmi scritti per lo standard precedente. Motivo per cui, dato che nei vecchi programmi venivano definiti, con macro, tipi come bool e true, si è scelto di utilizzare un nome che non entrasse in conflitto con essi.

Inoltre, lo standard C89 detta che qualunque nome che inizia con un underscore seguito da una lettera maiuscola o da un altro underscore è riservato al compilatore. Per cui, il nome _Bool è un nome riservato.

Lo standard C99 ha introdotto anche una nuova libreria, <stdbool.h>, che facilita il lavoro con valori booleani.

In particolare, in essa sono definite tre macro:

  • bool, che è un alias per _Bool; anche se, a partire dallo standard C23 non è più un alias ma un tipo a tutti gli effetti;
  • true, che è un alias per 1;
  • false, che è un alias per 0.

Quindi, possiamo scrivere:

#include <stdbool.h>

bool flag;

flag = true; /* vero */

/* ... */

flag = false; /* falso */

In questo modo, il codice risulta più leggibile e più vicino al linguaggio naturale.

Definizione

Header <stdbool.h>

L'header <stdbool.h> è un header introdotto nello standard C99 che definisce tre macro per facilitare il lavoro con valori booleani:

  • bool, che è un alias per _Bool;
  • true, che è un alias per 1;
  • false, che è un alias per 0.

In Sintesi

  • In C89 non esiste un tipo di dato booleano, per cui si utilizzano variabili di tipo int per rappresentare valori booleani;
  • Per rendere il codice più leggibile, si possono definire delle macro TRUE e FALSE per rappresentare rispettivamente i valori 1 e 0;
  • Nello standard C99 è stato introdotto il tipo _Bool per rappresentare valori booleani;
  • Nello standard C99 è stata introdotta la libreria <stdbool.h> che definisce tre macro per facilitare il lavoro con valori booleani: bool, true e false.