109 votes

Pourquoi les C caractère littéraux entiers (ints) au lieu de caractères ?

En C++, . Cela est logique intuitive, puisque est un caractère littéral, et `` telle que définie par la norme.

C cependant, `` . Autrement dit, il semble que C caractère littéraux sont en fait des entiers. Est-ce que quelqu'un sait pourquoi ? Je peux trouver beaucoup de mentions de cette bizarrerie C mais aucune explication de pourquoi elle existe.

39voto

Malx Points 656

discussion sur le même sujet

« Plus précisément, les promotions intégrante. K & R C, c’était pratiquement ( ?) Impossible d’utiliser une valeur de caractère sans lui être promu en int, ce qui rendra le caractère constant int éliminé en premier lieu de cette étape. Ont été et est encore multi constantes de caractères tels que « abcd » ou cependant beaucoup seront adaptera dans un int. »

22voto

Je ne connais pas les raisons spécifiques pour lesquelles un littéral de caractère en C est de type int. Mais en C++, il y a une bonne raison de ne pas faire de cette façon. Réfléchissez à ceci:

void print(int);
void print(char);

print('a');

Vous attendez que l'appel à imprimer sélectionne la deuxième version de prendre un char. Ayant un caractère littéral étant un int rendrait impossible. Notez qu'en C++, les littéraux d'avoir plus d'un caractère toujours être de type int, bien que leur valeur est définie par l'implémentation. Donc, 'ab' type int, tandis que l' 'a' type char.

19voto

dmckee Points 50318

utilisez gcc sur mon MacBook, j’ai essayer :

qui, une fois exécuté donne :

ce qui suggère qu’un personnage est de 8 bits, comme vous pensez, mais un littéral de caractère est un int.

8voto

Tony D Points 43962

En arrière quand C était écrit, le PDP-11 de la MACRO-11 de l'assemblée de la langue a:

MOV #'A, R0      // 8-bit character encoding for 'A' into 16 bit register

Ce genre de chose est assez commun dans le langage d'assemblage - le faible taux de 8 bits tiendra le code de caractère, les autres bits égaux à 0. PDP-11 avait même:

MOV #"AB, R0     // 16-bit character encoding for 'A' (low byte) and 'B'

Cela a fourni un moyen pratique pour charger des deux personnages dans la basse et haute octets de la 16 bits de registre. Vous pouvez ensuite écrire ailleurs, la mise à jour des données textuelles ou de l'écran de la mémoire.

Ainsi, l'idée de caractères d'être promu au registre de la taille est tout à fait normal et souhaitable. Mais, disons que vous avez besoin pour obtenir 'A' dans un registre pas dans le cadre de la codées en dur opcode, mais à partir de quelque part dans la mémoire principale contenant:

address: value
20: 'X'
21: 'A'
22: 'A'
23: 'X'
24: 0
25: 'A'
26: 'A'
27: 0
28: 'A'

Si vous voulez lire juste un 'A' à partir de ce mémoire principale dans un registre, qui aimeriez-vous lire?

  • Certains Processeurs ne peuvent directement prendre en charge la lecture d'une valeur 16 bits en 16 bits registre, ce qui signifierait une lecture à 20 ou 22 exigerait alors les bits de 'X' être nettoyé, et selon le boutisme de la CPU l'un ou l'autre aurait besoin de déplacement dans l'octet de poids faible.

  • Certains Processeurs peuvent exiger une mémoire aligné à lire, ce qui signifie que l'adresse la plus basse concernés doit être un multiple de la taille des données: vous pourriez être en mesure de lire les adresses, les 24 et 25, mais pas 27 et 28.

Donc, un compilateur de générer du code pour obtenir Un " a " dans le registre peut préférer à perdre un peu plus de mémoire et d'encoder la valeur 0 'A' ou 'A' 0 - en fonction de l'endianness, et aussi de s'assurer qu'il est correctement aligné (à savoir pas d'un drôle d'adresse de mémoire).

Ma conjecture est que C est tout simplement porté ce niveau de CPU centrée sur le comportement, la pensée de constantes de caractère occupant registre des tailles de mémoire, portant la commune d'évaluation de C comme un "assembleur de haut niveau".

(Voir 6.3.3 sur la page 6-25 de http://www.dmv.net/dec/pdf/macro.pdf)

5voto

Kyle Cronin Points 35834

Je me souviens de la lecture de K&R et de voir un extrait de code qui permettrait de lire un caractère à la fois jusqu'à ce qu'il a frappé des expressions du FOLKLORE. Depuis, tous les caractères sont des caractères valides dans un fichier/flux d'entrée, cela signifie que les expressions du FOLKLORE ne peut pas être n'importe quelle valeur char. Ce que le code a été de mettre à la lecture de caractères en un entier (int), puis de tester pour les expressions du FOLKLORE, puis convertir un char si il n'était pas.

Je me rends compte ce n'est pas exactement la réponse à votre question, mais il serait un certain sens, pour le reste des chaînes de caractères pour être sizeof(int) si les expressions du FOLKLORE littérale était.

int r;
char buffer[1024], *p; // don't use in production - buffer overflow likely
p = buffer;

while ((r = getc(file)) != EOF)
{
  *(p++) = (char) r;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X