Taille du caractère ('a') en C / C ++

299

Quelle est la taille des caractères en C et C ++? Autant que je sache, la taille de char est de 1 octet en C et C ++.

En C:

#include <stdio.h>
int main()
{
    printf("Size of char : %d\n", sizeof(char));
    return 0;
}

En C ++:

#include <iostream>
int main()
{
    std::cout << "Size of char : " << sizeof(char) << "\n";
    return 0;
}

Pas de surprise, les deux donnent la sortie: Size of char : 1

Maintenant , nous savons que les personnages sont représentés comme 'a', 'b', 'c', '|', ... Je viens donc modifié les codes ci - dessus pour ceux - ci:

En C:

#include <stdio.h>
int main()
{
    char a = 'a';
    printf("Size of char : %d\n", sizeof(a));
    printf("Size of char : %d\n", sizeof('a'));
    return 0;
}

Production:

Size of char : 1
Size of char : 4

En C ++:

#include <iostream>
int main()
{
    char a = 'a';
    std::cout << "Size of char : " << sizeof(a) << "\n";
    std::cout << "Size of char : " << sizeof('a') << "\n";
    return 0;
}

Production:

Size of char : 1
Size of char : 1

Pourquoi le sizeof('a')renvoie des valeurs différentes en C et C ++?

whacko__Cracko
la source
8
Le "%|"format nécessite un intargument (ou quelque chose qui promeut int). sizeofdonne un résultat de type size_t. Soit convertir en intutilisant un cast ou, si votre implémentation le prend en charge, utilisez "%zu".
Keith Thompson

Réponses:

349

En C, le type d'une constante de caractère comme 'a'est en fait un int, avec une taille de 4 (ou une autre valeur dépendante de l'implémentation). En C ++, le type est char, avec une taille de 1. C'est l'une des nombreuses petites différences entre les deux langages.

Eric Postpischil
la source
12
Dans la norme C ++, c'est la section 2.13.2 / 1, en C 6.4.4.4, au moins dans la documentation que j'ai.
14
+1 (Sauf que, bien que la "taille de 4" s'applique évidemment à la plate-forme de nthrgeek, elle ne s'applique pas nécessairement à toutes les plates-formes.)
sbi
28
@nthrgeek: Je suis trop paresseux pour citer les deux normes, mais la norme C ++ a une annexe dédiée aux incompatibilités avec C. Sous l'annexe C.1.1, elle mentionne que "le type de caractère littéral est changé de intà char, ce qui explique le comportement. :)
2010
3
@nthrgeek: §6.4.4.4, paragraphe 10: "Une constante de caractère entier a le type int. La valeur d'une constante de caractère entier contenant un seul caractère mappé à un caractère d'exécution à un octet est la valeur numérique de la représentation du mappé caractère interprété comme un entier. "
Stephen Canon
7
@nthrgeek: Vous ne devriez pas demander une référence standard sauf si vous avez un argument sur un point spécifique et que vous voulez comprendre pourquoi l'autre personne a une opinion différente. Si tout le monde est d'accord, acceptez-le. Vous (en tant que développeur) devez être assez intelligent pour trouver rapidement par vous-même une réponse commune comme celle-ci.
Martin York
26

Comme Paul l'a dit, c'est parce que 'a'c'est un inten C mais unchar en C ++.

Je couvre cette différence spécifique entre C et C ++ dans quelque chose que j'ai écrit il y a quelques années, à: http://david.tribble.com/text/cdiffs.htm

David R Tribble
la source
4
Juste curieux, mais travaillez-vous à mettre à jour ce document (très détaillé) pour inclure les nouvelles modifications dans C ++ 11 et C11?
Adam Rosenfield
Pas pour le moment. Mon intérêt pour le C et le C ++ a beaucoup diminué au cours des cinq dernières années.
David R Tribble
3
Euh, j'ai utilisé votre travail pour écrire ceci et vous êtes donc sur SO. Un si petit monde!
17

En C, les types de littéraux de caractères sont int et char en C ++. C'est en C ++ nécessaire pour prendre en charge la surcharge de fonctions . Voir cet exemple:

void foo(char c)
{
    puts("char");
}
void foo(int i)
{
    puts("int");
}
int main()
{
    foo('i');
    return 0;
}

Production:

char
Forgeron
la source
5

En langage C , le littéral de caractère n'est pas un chartype. C considère le caractère littéral comme un entier. Il n'y a donc pas de différence entre sizeof('a')et sizeof(1).

Ainsi, le littéral sizeof est égal à sizeof entier en C.

En langage C ++ , le littéral de caractère est le type de char. La cppreference dit:

1) littéral de caractère étroit ou littéral de caractère ordinaire, par exemple 'a'ou '\n'ou '\13'. Un tel littéral a un typechar et une valeur égaux à la représentation de c-char dans le jeu de caractères d'exécution. Si c-char n'est pas représentable comme un seul octet dans le jeu de caractères d'exécution, le littéral a le type int et la valeur définie par l'implémentation.

Ainsi, en C ++, le littéral de caractères est un type de char. ainsi, la taille du littéral de caractère en C ++ est d'un octet.

Alos, dans vos programmes, vous avez utilisé un spécificateur de format incorrect pour l' sizeofopérateur.

C11 §7.21.6.1 (P9):

Si une spécification de conversion n'est pas valide, le comportement n'est pas défini.275) Si un argument n'est pas du type correct pour la spécification de conversion correspondante, le comportement n'est pas défini.

Donc, vous devez utiliser un %zuspécificateur de format au lieu de%d , sinon c'est un comportement non défini en C.

msc
la source
%zun'est pas pris en charge sur de nombreuses plates-formes, mais une meilleure portabilité, utilisation (int)sizeof(char)et format%d
chqrlie
La valeur des littéraux de caractères n'est pas nécessairement le code ASCII correspondant. Cela dépend des jeux de caractères source et d'exécution et si le chartype est signé ou non par défaut.
chqrlie