Utilisation de int pour les types de caractères lors de la comparaison avec EOF

Citant Kernighan et Ritchie dans «Le langage de programmation C» Page 16 –

#include main() { int c; c = getchar(); while(c!=EOF) { putchar(c); c = getchar(); } getchar(); return 0; } 

“Le caractère de type est spécifiquement conçu pour stocker de telles données de caractère, mais tout type entier peut être utilisé. Nous avons utilisé int pour une raison subtile mais importante. Le problème consiste à distinguer la fin de l’entrée des données valides. La solution est que getchar renvoie une valeur distinctive lorsqu’il n’y a plus d’entrées, une valeur qui ne peut pas être confondue avec un caractère réel. Cette valeur est appelée EOF , pour “fin de fichier”. Nous devons déclarer que c est un type suffisamment grand pour contenir toute valeur qui getchar Nous ne pouvons pas utiliser char car c doit être suffisamment grand pour contenir EOF en plus des char possibles. Par conséquent, nous utilisons int . “.

J’ai regardé stdio.h, il est écrit #define EOF (-1)

Le livre indique de manière concluante que caractère ne peut pas être utilisé alors que ce programme “fonctionne très bien” (voir EDIT) avec le type de données c comme caractère également. Que se passe-t-il? Quelqu’un peut-il expliquer en termes de bits et de valeurs signées?

MODIFIER:
Comme Oli l’a mentionné dans la réponse, le programme ne peut pas distinguer entre EOF et 255 . Donc, cela ne fonctionnera pas bien. Je veux savoir ce qui se passe – Etes-vous en train de dire que lorsque nous comparons c! = EOF, la valeur EOF est convertie en une valeur char = 255 (11111111 en binary; c’est-à-dire que les bits 0 à 7 de EOF sont écrits en complément à 2 notation)?

Votre programme ne fonctionne pas bien; il ne sera pas en mesure de distinguer entre EOF et 255 .

Cela semble fonctionner correctement parce que char est probablement signed sur votre plate-forme, il est donc toujours capable de représenter -1 .

getchar result est le caractère d’entrée converti en caractère unsigned char , puis en int ou EOF c.-à-d. qu’il se situe dans la plage -1 – 255, soit 257 valeurs différentes. Vous ne pouvez pas le définir dans un caractère 8 bits sans en fusionner deux. Pratiquement, soit vous confondrez EOF avec un caractère valide (cela se produira si le caractère n’est pas signé), soit vous confondez un autre caractère avec EOF (cela se produira si le caractère est signé).

Remarque: je suppose un type de caractère 8 bits, je sais que cette hypothèse n’est pas étayée par la norme, c’est de loin le choix d’implémentation le plus courant.