En C, ¿por qué sizeof(char) es 1, cuando ‘a’ es un int?

7 minutos de lectura

avatar de usuario
leyendas2k

Lo intenté

printf("%d, %d\n", sizeof(char), sizeof('c'));

y consiguió 1, 4 como salida. Si el tamaño de un carácter es uno, ¿por qué 'c' dame 4? Supongo que es porque es un número entero. Así que cuando lo haga char ch="c"; ¿Está ocurriendo una conversión implícita, bajo el capó, de ese valor de 4 bytes a un valor de 1 byte cuando se asigna a la variable char?

  • Creo que tiene que ver con la promoción automática de enteros, alguien con más hechos que creencias publicará una respuesta fáctica

    – Preocupado binario

    12 de febrero de 2010 a las 13:32

  • @Roger: Él está preguntando sobre la diferencia entre C y C++ sizeof(‘a’), mientras que yo pregunté si está ocurriendo una conversión. Ver el cuerpo de la pregunta. Ya deduje que ‘a’ es un número entero en C.

    – leyendas2k

    12 de febrero de 2010 a las 14:01


  • Tengo que agradecer a “David Rodríguez – dribeas” por señalar que el enlace en mi respuesta es incorrecto. Borro mi respuesta. legends2k, la respuesta correcta debería ser para Peter o Neil, en mi humilde opinión.

    – Preocupado binario

    12 de febrero de 2010 a las 15:30

  • Obtuviste tu respuesta, pero un comentario: no puedes imprimir size_t objetos con "%d". Ya que sizeof rendimientos size_t a size_t objeto, debe imprimirlo con "%zu" (C99) o lanzarlo a unsigned long e imprimir con "%lu" (C89).

    – Alok Singhal

    13 de febrero de 2010 a las 2:51

  • stackoverflow.com/questions/433895/…

    – Ciro Santilli Путлер Капут 六四事

    27 de junio de 2015 a las 21:13

avatar de usuario
ricardo pennington

En C ‘a’ es una constante entera (!?!), por lo que 4 es correcto para su arquitectura. Se convierte implícitamente en char para la asignación. sizeof(char) siempre es 1 por definición. El estándar no dice qué unidades son 1, pero a menudo son bytes.

  • + 1 para “pero a menudo son bytes”, todavía me estoy riendo 🙂

    – Preocupado binario

    12 de febrero de 2010 a las 13:33

  • La norma define la sizeof operador como devolver el tamaño en bytesentonces no es con frecuencia, sino siempre. En el segundo párrafo de ‘El operador sizeof’: ‘El operador sizeof produce el tamaño (en bytes) de su operando.’

    – David Rodríguez – dribeas

    12 de febrero de 2010 a las 14:28


  • Siempre me estremezco cuando leo “emitir implícitamente” en publicaciones de SO. No hay conversión implícita: una conversión es siempre una conversión explícita. El Estándar C dice en 6.3: “Varios operadores convierten valores de operandos de un tipo a otro automáticamente. Esta subcláusula especifica el resultado requerido de tal conversión implícitaasí como los que resultan de una operación de yeso (una conversión explícita).”. Quiere decir “implícitamente convertido”.

    – Johannes Schaub – litb

    12 de febrero de 2010 a las 15:49

  • sizeof() mide en (entero, creo) múltiplos de CHAR_BITS. Ni mas ni menos. sizeof(char) == 1, por definición. El número de bits en otro tipo se puede encontrar multiplicando sizeof(type) con CHAR_BITS. Por supuesto, la mayoría (si no todas) las plataformas tendrán CHAR_BITS siendo 8.

    – Vatina

    12 de febrero de 2010 a las 16:17

  • Siempre son bytes. Puede que no sean octetos.

    – Carreras de ligereza en órbita

    17 de julio de 2015 a las 13:29

El estándar de C dice que un carácter literal como ‘a’ es de tipo int, no de tipo char. Por lo tanto, tiene (en su plataforma) sizeof == 4. Consulte esta pregunta para obtener una discusión más completa.

  • Pregunté sobre la promoción/el casting que ocurre entre los dos tipos de datos, mientras que la discusión/respuesta no responde esto.

    – leyendas2k

    12 de febrero de 2010 a las 13:46

  • @legends2K Preguntaste “Si el tamaño de un personaje es uno, ¿por qué ‘c’ me da 4?” Como esta respuesta y la pregunta que vinculé explican que ‘a’ tiene un tamaño de == 4, obviamente no hay casting ni promoción.

    luego

    12 de febrero de 2010 a las 13:49


  • Bien. hay una forma detallada de la pregunta, debajo de ella, que dice “¿hay un encasillamiento implícito, bajo el capó, de ese valor de 4 bytes a un valor de 1 byte cuando se asigna a la variable char”. Esto también es parte de eso, creo.

    – leyendas2k

    12 de febrero de 2010 a las 13:53


  • No hay promoción. En C, ‘a’ tiene tipo int. En la mayoría de las implementaciones de C, ‘a’ es exactamente igual que 97. En C++, ‘a’ tiene el tipo char.

    – gnasher729

    11 de abril de 2014 a las 14:02

Es el comportamiento normal del sizeof operador (Ver Wikipedia):

  • Para un tipo de datos, sizeof devuelve el tamaño del tipo de datos. Para charobtienes 1.
  • Para una expresión, sizeof devuelve el tamaño del tipo de la variable o expresión. Como un carácter literal se escribe como intobtienes 4.

Esto está cubierto en ISO C11 6.4.4.4 Character constants aunque no ha cambiado en gran medida con respecto a los estándares anteriores. Que establece, en el párrafo /10:

Una constante de carácter entero tiene tipo int. El valor de una constante de carácter entero 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 carácter asignado interpretado como un número entero.

avatar de usuario
t0mm13b

Según las normas ANSI C, un char es ascendido a un int en el contexto donde se usan números enteros, usó un especificador de formato de número entero en el printf de ahí los diferentes valores. Un carácter suele ser de 1 byte, pero esa implementación se define en función del tiempo de ejecución y el compilador.

  • El formato entero se refería a sizeof(‘a’) no a ‘a’, así que no veo cómo se sostiene este argumento.

    – SmacL

    12 de febrero de 2010 a las 13:33

  • El estándar C dice que un char literal es de tipo int: tiene un tamaño de int y no está involucrada ninguna promoción.

    luego

    12 de febrero de 2010 a las 13:35

  • Su respuesta parece sugerir que el compilador de C inspecciona una cadena de formato utilizada por una función de biblioteca al compilar un programa, ¿está seguro de que ese es el caso?

    – heijp06

    12 de febrero de 2010 a las 13:36

  • ¿Qué pasaría si fuera scanf(“%s\n”,format) ; printf (formato, tamaño de (char), tamaño de (‘a’)); y escribiría “%d, %d\n” cuando se le solicite? En este caso, el compilador no tiene forma de conocer los tipos de variables a priori y tiene que usar el operador de puntos suspensivos a ciegas como debe ser.

    – SF.

    12 de febrero de 2010 a las 13:36

  • @Peter van der Heijden: tiene razón, una cadena de formato y sus especificadores no tienen nada que ver con los tipos de variables que se pasan después de ellos. gcc, emitirá advertencias si no se alinean, pero compila bien con tipos que no coinciden, suponiendo que sepa más que el compilador. Dicho esto, la ‘a’ tiene un tamaño de y no está en un “contexto entero”. El tamaño de las llamadas está devolviendo size_t, que creo que generalmente se define como un número entero sin signo.

    –Michael Speer

    12 de febrero de 2010 a las 14:02

  • El formato entero se refería a sizeof(‘a’) no a ‘a’, así que no veo cómo se sostiene este argumento.

    – SmacL

    12 de febrero de 2010 a las 13:33

  • El estándar C dice que un char literal es de tipo int: tiene un tamaño de int y no está involucrada ninguna promoción.

    luego

    12 de febrero de 2010 a las 13:35

  • Su respuesta parece sugerir que el compilador de C inspecciona una cadena de formato utilizada por una función de biblioteca al compilar un programa, ¿está seguro de que ese es el caso?

    – heijp06

    12 de febrero de 2010 a las 13:36

  • ¿Qué pasaría si fuera scanf(“%s\n”,format) ; printf (formato, tamaño de (char), tamaño de (‘a’)); y escribiría “%d, %d\n” cuando se le solicite? En este caso, el compilador no tiene forma de conocer los tipos de variables a priori y tiene que usar el operador de puntos suspensivos a ciegas como debe ser.

    – SF.

    12 de febrero de 2010 a las 13:36

  • @Peter van der Heijden: tiene razón, una cadena de formato y sus especificadores no tienen nada que ver con los tipos de variables que se pasan después de ellos. gcc, emitirá advertencias si no se alinean, pero compila bien con tipos que no coinciden, suponiendo que sepa más que el compilador. Dicho esto, la ‘a’ tiene un tamaño de y no está en un “contexto entero”. El tamaño de las llamadas está devolviendo size_t, que creo que generalmente se define como un número entero sin signo.

    –Michael Speer

    12 de febrero de 2010 a las 14:02

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad