Tamaño del carácter ('a') en C / C ++

298

¿Cuál es el tamaño de los caracteres en C y C ++? Hasta donde sé, el tamaño de char es de 1 byte en C y C ++.

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;
}

Sin sorpresas, ambos dan la salida: Size of char : 1

Ahora sabemos que los personajes son representados como 'a', 'b', 'c', '|', ... Así que acaba de modificar los códigos anteriores a éstos:

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;
}

Salida:

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;
}

Salida:

Size of char : 1
Size of char : 1

¿Por qué sizeof('a')devuelve diferentes valores en C y C ++?

whacko__Cracko
fuente
8
El "%|"formato requiere un intargumento (o algo que promueva int). sizeofproduce un resultado de tipo size_t. Conviértase a intusar un reparto o, si su implementación lo admite, use "%zu".
Keith Thompson, el

Respuestas:

348

En C, el tipo de una constante de carácter como 'a'es en realidad un int, con un tamaño de 4 (o algún otro valor dependiente de la implementación). En C ++, el tipo es char, con un tamaño de 1. Esta es una de las muchas pequeñas diferencias entre los dos lenguajes.

Eric Postpischil
fuente
12
En el estándar C ++ es la sección 2.13.2 / 1, en C 6.4.4.4, al menos en el documento que tengo.
14
+1 (Excepto que, aunque el "tamaño de 4" obviamente se aplica a la plataforma de nthrgeek, no necesariamente se aplica a todas las plataformas.)
sbi
28
@nthrgeek: Soy demasiado vago para citar ambos estándares, pero el estándar C ++ tiene un apéndice dedicado a las incompatibilidades con C. En el Apéndice C.1.1, menciona que "Tipo de carácter literal se cambia de inta char, lo que explica el comportamiento. :)
jalf
3
@nthrgeek: §6.4.4.4, párrafo 10: "Una constante de caracteres enteros tiene el tipo int. El valor de una constante de caracteres enteros que contiene un solo carácter que se asigna a un carácter de ejecución de un solo byte es el valor numérico de la representación del mapeado personaje interpretado como un entero ".
Stephen Canon
77
@nthrgeek: No debe pedir una referencia estándar a menos que tenga una discusión sobre un punto específico y quiera entender por qué la otra persona tiene una opinión diferente. Si todos están de acuerdo, simplemente acéptenlo. Usted (como desarrollador) debe ser lo suficientemente inteligente como para encontrar rápidamente una respuesta común como esta solo.
Martin York
26

Como dijo Paul, es porque 'a'es un inten C pero un charen C ++.

Cubro esa diferencia específica entre C y C ++ en algo que escribí hace unos años, en: http://david.tribble.com/text/cdiffs.htm

David R Tribble
fuente
44
Es curioso, pero ¿está trabajando en actualizar ese documento (muy detallado) para incluir los nuevos cambios en C ++ 11 y C11?
Adam Rosenfield
No en este momento. Mi interés en C y C ++ ha disminuido mucho en los últimos cinco años más o menos.
David R Tribble
3
Usé tu trabajo para escribir esto y aquí estás en SO. ¡Un mundo tan pequeño!
17

En C, el tipo de literales de caracteres son int y char en C ++. Esto se requiere en C ++ para soportar la sobrecarga de funciones . Ver este ejemplo:

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

Salida:

char
Herrero
fuente
5

En lenguaje C , el carácter literal no es un chartipo. C considera el carácter literal como entero. Entonces, no hay diferencia entre sizeof('a')y sizeof(1).

Entonces, el literal sizeof de caracteres es igual a sizeof entero en C.

En lenguaje C ++ , el carácter literal es tipo de char. La cppreference dice:

1) carácter estrecho literal o carácter ordinario literal, por ejemplo, 'a'or '\n'o '\13'. Tal literal tiene el tipochar y el valor igual a la representación de c-char en el juego de caracteres de ejecución. Si c-char no es representable como un solo byte en el juego de caracteres de ejecución, el literal tiene el tipo int y el valor definido por la implementación.

Entonces, en C ++ el literal de caracteres es un tipo de char. entonces, el tamaño del carácter literal en C ++ es un byte.

Alos, en sus programas, ha utilizado un especificador de formato incorrecto para el sizeofoperador.

C11 §7.21.6.1 (P9):

Si una especificación de conversión no es válida, el comportamiento no está definido.275) Si algún argumento no es el tipo correcto para la especificación de conversión correspondiente, el comportamiento no está definido.

Por lo tanto, debe usar el %zuespecificador de formato en lugar de %d, de lo contrario, es un comportamiento indefinido en C.

msc
fuente
%zuno es compatible con muchas plataformas, pero mejor portabilidad, uso (int)sizeof(char)y formato%d
chqrlie
El valor de los literales de caracteres no es necesariamente el código ASCII correspondiente. Depende de los juegos de caracteres de origen y ejecución y de si el chartipo está firmado o no de forma predeterminada.
chqrlie