La différence est la taille en octets de la variable, et de là, les différentes valeurs que la variable peut contenir.
Un caractère doit accepter toutes les valeurs comprises entre 0 et 127 (inclus). Ainsi, dans les environnements courants, il occupe exactement un octet (8 bits). La norme ne précise pas s'il est signé (-128 - 127) ou non signé (0 - 255).
Un int doit être au moins un mot signé de 16 bits et accepter toutes les valeurs comprises entre -32767 et 32767. Cela signifie qu'un int peut accepter toutes les valeurs d'un char, que ce dernier soit signé ou non.
Si vous voulez stocker uniquement des caractères dans une variable, vous devez la déclarer comme suit char
. L'utilisation d'un int
ne ferait que gaspiller de la mémoire, et pourrait induire en erreur un futur lecteur. Une exception courante à cette règle est le cas où vous voulez traiter une valeur plus large pour des conditions spéciales. Par exemple, la fonction fgetc
de la bibliothèque standard est déclaré comme retournant int
:
int fgetc(FILE *fd);
car la valeur spéciale EOF
(pour End Of File) est défini comme l'adresse de l'utilisateur. int
valeur -1 (tous les bits à un dans un système à deux compléments) qui signifie plus que la taille d'un caractère. De cette façon, aucun caractère (seulement 8 bits dans un système commun) ne peut être égal à la constante EOF. Si la fonction était déclarée pour retourner un simple char
rien ne permet de distinguer la valeur EOF du caractère 0xFF (valide).
C'est la raison pour laquelle le code suivant est mauvais et ne devrait jamais être utilisé :
char c; // a terrible memory saving...
...
while ((c = fgetc(stdin)) != EOF) { // NEVER WRITE THAT!!!
...
}
À l'intérieur de la boucle, un char serait suffisant, mais pour que le test ne réussisse pas lors de la lecture du caractère 0xFF, la variable doit être un int.