Tipo a usar para representar un byte en ANSI (C89/90) C?

7 minutos de lectura

avatar de usuario
Sidio

¿Existe un método de queja de estándares para representar un byte en ANSI (C89/90) C? Sé que, en la mayoría de los casos, un carácter resulta ser un byte, pero entiendo que no se garantiza que sea así. Además, hay stdint.h en el estándar C99, pero ¿qué se usaba antes de C99?

Tengo curiosidad acerca de los 8 bits específicamente y un “byte” (tamaño de (x) == 1).

  • Asegúrese de distinguir byte de octeto. sizeof(char) = 1 siempre, lo que significa que un char es siempre un byte. Sin embargo, un byte no siempre es un octeto (los bytes DEC Alpha eran de 10 bits, IIRC… los octetos se definen como 8 bits).

    – Tomás

    13 de enero de 2009 a las 4:47

avatar de usuario
alex b

char es siempre un byte pero no siempre es un octeto. Un byte es la unidad de memoria direccionable más pequeña (en la mayoría de las definiciones), un octeto es una unidad de memoria de 8 bits.

Es decir, sizeof(char) es siempre 1 para todas las implementaciones, pero CHAR_BIT macro en limits.h define el tamaño de un byte para una plataforma y no siempre es de 8 bits. Hay plataformas con bytes de 16 y 32 bits, por lo tanto char ocupará más bits, pero sigue siendo un byte. Dado que el rango requerido para char es al menos -127 a 127 (o 0 a 255), será por lo menos 8 bits en todas las plataformas.

ISO/CEI 9899:TC3

6.5.3.4 El tamaño del operador

  1. El operador sizeof produce el tamaño (en bytes) de su operando, que puede ser una expresión o el nombre entre paréntesis de un tipo. […]
  2. Cuando se aplica a un operando que tiene tipo char, unsigned charo signed char(o una versión calificada de la misma) el resultado es 1. […]

Énfasis mío.

  • El rango requerido para char es en realidad de -127 a 127 (no olvide que algunas arquitecturas solían usar una magnitud con signo o representaciones enteras del complemento de uno) o de 0 a 255, dependiendo de si char tiene signo o no. El complemento a dos de 8 bits admite -128 a 127, no -127 a 128.

    – bk1e

    14 de enero de 2009 a las 7:48

  • @Chris: byte = unidad de memoria direccionable más pequeña. No estoy seguro de lo que quiere decir con su pregunta. un byte de menos de 8 bits significa que una plataforma no puede ser compatible con C.

    – Alex B.

    14 de enero de 2009 a las 8:37

  • No me di cuenta de que C requería > = bytes de 8 bits (de hecho, el estándar dice que un byte debe contener un carácter y un carácter debe tener 8 bits). Hemos llegado a la frontera de la portabilidad de C…

    – Chris Conway

    14 de enero de 2009 a las 16:36

  • @theduke, principalmente DSP, por ejemplo: leo.sprossenwanne.at/dsp/Entwicklungsprogramme/Entpack/CC56/DSP/…

    – Alex B.

    2 de octubre de 2011 a las 3:10

  • Un byte de hardware físico de menos de 8 bits no es un problema con respecto a la conformidad C siempre que el byte lógico presentado por la implementación de C es de al menos 8 bits. Esto significa que una máquina con bytes de hardware de 7 bits podría proporcionar un byte lógico de 14 bits para char y ser conforme, pero entonces todos los tipos más grandes tendrían que ocupar un número entero (y alineado) de dichos bytes lógicos (es decir, no podría tener un número entero de 21 bits compuesto por 3 bytes de hardware a menos que incluyera 7 bits adicionales de relleno (el resto del segundo char) junto con eso.

    – R.. GitHub DEJA DE AYUDAR A ICE

    21 de octubre de 2011 a las 4:54

Siempre puede representar un byte (si se refiere a 8 bits) en un carácter sin firmar. Siempre tiene un tamaño de al menos 8 bits, todos los bits constituyen el valor, por lo que siempre cabe un valor de 8 bits.

Si desea exactamente 8 bits, también creo que tendrá que usar formas dependientes de la plataforma. Los sistemas POSIX parecen ser requerido para admitir int8_t. Eso significa que en los sistemas POSIX, char (y por lo tanto un byte) siempre tiene 8 bits.

  • Compatibilidad con POSIX para stdint.h posteriores a C99.

    – Chris Conway

    13 de enero de 2009 a las 0:47

  • Ah sí. parece de 2001. pero creo que incluso si no tiene un compilador c99 que lo envíe, si está en una máquina posix, puede aprovechar sus requisitos de stdint.h. si está en ms windows, todas mis apuestas están canceladas 🙂 ¿quizás pueda sacar cosas de cstdint.hpp de boost y c’ify?

    – Johannes Schaub – litb

    13 de enero de 2009 a las 0:55

  • Me refiero a un byte, no necesariamente 8 bits, pero gracias. Aparte, ¿dice la especificación que debe ser de al menos 8 bits, o simplemente es así?

    – Sidio

    13 de enero de 2009 a las 2:30

  • sí, los límites de documentación estándar c.h requieren que UCHAR_MAX sea al menos 255, no tenga bits de relleno y use un sistema binario puro. char debe tener el mismo rango y representación que un char sin firmar o un char firmado, pero debe ser un tipo distinto.

    – Johannes Schaub – litb

    13 de enero de 2009 a las 12:15

En ANSI C89/ISO C90 sizeof(char) == 1. Sin embargo, no siempre se da el caso de que 1 byte tenga 8 bits. Si desea contar la cantidad de bits en 1 byte (y no tiene acceso aLIMITES.h), le sugiero lo siguiente:

unsigned int bitnum(void) {
    unsigned char c = ~0u; /* Thank you Jonathan. */
    unsigned int v;

    for(v = 0u; c; ++v)
        c &= c - 1u;
    return(v);
}

Aquí usamos el método de Kernighan para contar el número de bits establecidos en C. Para comprender mejor el código anterior (o ver otros similares), lo remito a “Trucos para jugar con bits“.

  • Es mejor usar ~0 que -1; en una máquina de complemento a uno o de magnitud de signo, es posible que -1 no esté configurado en todos los bits. Se garantiza que ~0 tiene todos los bits establecidos.

    –Jonathan Leffler

    13 de enero de 2009 a las 4:31

  • @Jonathan: Eso tiene sentido. Gracias por la sugerencia. Ahora edito la publicación. (¡Lamento haber editado este comentario tantas veces!)

    luego

    13 de enero de 2009 a las 4:52

  • se define matemáticamente: -N es (2^CHAR_BIT – (N mod (2^CHAR_BIT))), lo que significa que -1 es siempre el carácter sin signo más alto, con todos los bits 1. La diferencia en la representación del signo es que si tiene complemento a dos, la conversión es conceptual allí: el patrón de bits no cambiará:

    – Johannes Schaub – litb

    13 de enero de 2009 a las 12:21

  • @R: ¿Cómo puede ser esto? El complemento a uno significa que, para enteros de 16 bits, -1 es %11111111-11111110 porque para hacer un número negativo, los bits simplemente se invierten (mira aquí). Solo para el complemento de Dos, -1 sería %11111111-11111111, es decir, 0x7FFFF + 1 (que es cuando muchas CPU configuran amablemente el indicador de desbordamiento).

    – Andreas Spindler

    23/10/2012 a las 21:23


  • @AndreasSpindler: vea el comentario de JohannesSchaub-litb: una conversión de firmado a sin firmar no es solo una reinterpretación del patrón de bits, conceptualmente, agrega Uxxx_MAX hasta que esté dentro del rango.

    – ninjalj

    23 de febrero de 2015 a las 18:47

¿Antes de C99? Código dependiente de la plataforma.

Pero ¿por qué te importa? Simplemente use stdint.h.

En todas las implementaciones de CI que se han utilizado (desde UNIX antiguo hasta compiladores integrados escritos por ingenieros de hardware y compiladores de grandes proveedores) char siempre ha sido de 8 bits.

Puede encontrar macros y typedefs bastante confiables en boost.

  • Bueno, puedes simplemente copiar/pegar lo que necesites desde allí. No hay nada especial si solo necesita un tipo confiable de enteros de cierta longitud.

    – Polipensador

    13 de enero de 2009 a las 1:04

avatar de usuario
ty5

Noté que algunas respuestas han redefinido la palabra byte para que signifique algo más que 8 bits. Un byte tiene 8 bits; sin embargo, en algunas implementaciones de c, char tiene 16 bits (2 bytes) u 8 bits (1 byte). Las personas que llaman a un byte ‘la unidad de memoria direccionable más pequeña’ o alguna basura similar han perdido la comprensión del significado de byte (8 bits). La razón por la que algunas implementaciones de C tienen caracteres de 16 bits (2 bytes) y algunas tienen caracteres de 8 bits (1 byte), y no hay un tipo estándar llamado ‘byte’, se debe a la pereza.

Entonces, deberíamos usar int_8

  • Bueno, puedes simplemente copiar/pegar lo que necesites desde allí. No hay nada especial si solo necesita un tipo confiable de enteros de cierta longitud.

    – Polipensador

    13 de enero de 2009 a las 1:04

¿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