Pourquoi les fonctions de caractères acceptent l'argument int plutôt que l'argument de caractère?
<ctype.h> int isalnum(int c); int isalpha(int c); int iscntrl(int c); int isdigit(int c); int isgraph(int c); int islower(int c); int isprint(int c); int ispunct(int c); int isspace(int c); int isupper(int c); int isxdigit(int c); int tolower(int c); int toupper(int c);
4 Réponses :
Ils doivent accepter EOF en plus des valeurs de caractère normales. Ils prédemblent également l'invention des prototypes de fonction. A cette époque, il n'y avait aucun moyen de passer un char code> à une fonction - il a été toujours promu
int code> premier. P>
Les caractères et les entiers sont plutôt tricotés dans c. p>
Lorsque vous recevez un caractère à partir d'un flux d'entrée, il doit être en mesure de représenter chaque caractère plus em> le symbole de fin de fichier. p>
Cela signifie qu'un type Le document de Justification C99 indique: P>
Étant donné que ces fonctions sont souvent utilisées principalement comme des macros, leur domaine est limité aux petits entiers positifs représentables dans un caractère non signé, ainsi que la valeur de l'EOF. EOF est traditionnellement -1, mais peut être un entier négatif, et donc distinguable de tout code de caractère valide. Ces macros peuvent ainsi être implémentées efficacement en utilisant l'argument comme un index dans une petite gamme d'attributs. P>
blockQuote>
La norme elle-même a cela à dire: p>
L'en-tête char code> ne sera pas assez gros pour qu'ils utilisent un type plus large. P>
"Le prochain type" le plus grand type "serait effectivement court code>. Mais, quand celles-ci ont été inventées, un
court code> serait favorisé à
int code> juste comme un
char code>.
@JerryCoffin Que voulez-vous dire? Tous les shorts sont toujours favorisés à l'INT, chaque fois qu'ils sont utilisés dans une expression.
@Amirsaniyan: tandis que ((mychar = tolower (getchar (getchar (getchar (getchar (getchar ())! = EOF) {/ * Faire des choses * /} Techniquement, les valeurs non ascii renvoient des valeurs indéfinies, mais quand "ce comportement est indéfini" n'a jamais arrêté quiconque de compter dessus?
@Jerry: Plus important encore, lorsque celles-ci ont été inventées courte code> était la même taille que
char code> dans de nombreux endroits. Bien que la norme n'exige pas explicitement,
int code> est plus grand que
char code> à peu près partout. S'ils avaient la même taille, la mise en œuvre aurait besoin d'une valeur négative "réservée" spéciale, qui n'est pas un point de code dans l'ensemble de caractères d'exécution et ne peut jamais être lu à partir d'une entrée d'entrée (y compris par exemple un flux de fichiers binaires), et utiliser cela comme eof. Je ne suis pas sûr que ce soit légal, car cela signifierait qu'il y a une valeur de
char code> qui ne peut pas être écrit dans un fichier et lire en arrière.
@Stevejessop: Quel compilateur avait charpuré et court la même taille? Je suis sûr qu'aucun des compilateurs AT & T, ni des Blancsmiths. Je me souviens d'un bon nombre de compilateurs vraiment anticipés (par exemple, BDS C) qui n'avaient pas court code> du tout, mais aucun qui n'avait de même taille que
Char code>.
@Jerry: Désolé, j'ai été confus. Pour une raison quelconque, je pensais que court code> était souvent 8 bits sur des systèmes de 8 bits et 16 bits, mais bien sûr que cela ne serait pas conforme. En y pensant, je ne suis pas sûr que j'ai jamais utilisé
court code> moi-même.
Quand C a été inventé pour la première fois, il n'y avait pas de vérification du temps de compilation des arguments de la fonction. Si on a appelé foo (bar, boz) code> et
bar code> et
boz code> était de type
int code>, le compilateur serait Appuyez deux valeurs
int code> sur la pile, appelez
foo code> et espérons qu'il vous attendait à obtenir deux valeurs
int code>. Étant donné que les types entiers inférieurs à
int code> sont favorisés à
int code> lors de l'évaluation des expressions, des fonctions C écrites avant l'invention des prototypes ne pouvaient pas passer de type entier plus petit. P >
Oui, il pourrait être de s'adapter à l'EOF qui est toujours une valeur non-caractère, bien que la valeur exacte de l'EOF puisse varier avec différents systèmes, mais cela ne sera jamais identique à un code de caractère. p>
Je soupçonne que la réponse est similaire à celle donnée ici A >. Dans C, les littéraux de caractères sont de type
int code>.
@Cody: Les deux décisions peuvent être liées, en ce que le type de données correct pour faire "calculs" sur des caractères de C est
int code>. Mais les littéraux ayant le même type que ces paramètres de fonctionnement ne sont pas aussi simples que cela semble. Vous pouvez écrire
isalnum ('a') code>, mais vous n'êtes pas garanti de pouvoir écrire
isalnum (char_min) code> ou quel que soit le caractère littéral correspondant à
char_min < / Code> Dans votre implémentation, car cela pourrait être négatif. Pour correspondre correctement avec ces fonctions, les littéraux de caractères auraient vraiment besoin de type
non signé code>, mais ensuite les casser sur
char code> serait potentiellement mauvais.