7
votes

ANSI C: Pourquoi les fonctions de caractère acceptent-elles l'argument globale au lieu de l'argument de caractère?

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 :


3
votes

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 à une fonction - il a été toujours promu int premier.


0 commentaires

10
votes

Les caractères et les entiers sont plutôt tricotés dans c.

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 le symbole de fin de fichier.

Cela signifie qu'un type char ne sera pas assez gros pour qu'ils utilisent un type plus large.

Le document de Justification C99 indique:

É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.

La norme elle-même a cela à dire:

L'en-tête déclare plusieurs fonctions utiles pour la classification et la cartographie personnages. Dans tous les cas, l'argument est un int, la valeur qui doit être représentables comme un caractère non signé ou doit être égal à la valeur de la macro eof. Si la L'argument a une autre valeur, le comportement est indéfini.


6 commentaires

"Le prochain type" le plus grand type "serait effectivement court . Mais, quand celles-ci ont été inventées, un court serait favorisé à int juste comme un char .


@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 était la même taille que char dans de nombreux endroits. Bien que la norme n'exige pas explicitement, int est plus grand que char à 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 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 du tout, mais aucun qui n'avait de même taille que Char .


@Jerry: Désolé, j'ai été confus. Pour une raison quelconque, je pensais que court é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 moi-même.



4
votes

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) et bar et boz était de type int , le compilateur serait Appuyez deux valeurs int sur la pile, appelez foo et espérons qu'il vous attendait à obtenir deux valeurs int . Étant donné que les types entiers inférieurs à int sont favorisés à int lors de l'évaluation des expressions, des fonctions C écrites avant l'invention des prototypes ne pouvaient pas passer de type entier plus petit.


0 commentaires

0
votes

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.


0 commentaires