¿Cuál es la ventaja de usar uint8_tmás unsigned charen C?
Sé que en casi todos los sistemas uint8_tes solo una definición de tipo unsigned char, entonces, ¿por qué usarlo?
Documenta su intención: almacenará números pequeños, en lugar de un personaje.
También se ve mejor si está usando otros typedefs como uint16_to int32_t.
unsigned charosigned chardocumenta la intención también, ya que sin adornoschares lo que muestra que estás trabajando con personajes.unsignederaunsigned intpor definición?charparece implicar un carácter, mientras que en el contexto de una cadena UTF8, puede ser solo un byte de un carácter multibyte. El uso de uint8_t podría dejar en claro que no se debe esperar un carácter en cada posición; en otras palabras, cada elemento de la cadena / matriz es un entero arbitrario sobre el que no se deben hacer suposiciones semánticas. Por supuesto, todos los programadores de C lo saben, pero puede empujar a los principiantes a hacer las preguntas correctas.Solo para ser pedante, algunos sistemas pueden no tener un tipo de 8 bits. De acuerdo con Wikipedia :
Por
uint8_tlo tanto, no se garantiza que exista, aunque lo hará para todas las plataformas donde 8 bits = 1 byte. Algunas plataformas integradas pueden ser diferentes, pero eso se está volviendo muy raro. Algunos sistemas pueden definirchartipos de 16 bits, en cuyo caso probablemente no habrá ningún tipo de 8 bits.Aparte de ese problema (menor), la respuesta de @Mark Ransom es la mejor en mi opinión. Utilice el que muestre más claramente para qué está utilizando los datos.
Además, supongo que usted quiso decir
uint8_t(el tipo de definición estándar de C99 proporcionado en elstdint.hencabezado) en lugar deuint_8(no forma parte de ningún estándar).fuente
uint8_t(o escribirlo para eso). Esto se debe a que el tipo de 8 bits tendría bits no utilizados en la representación de almacenamiento, queuint8_tno debe tener.typedef unsigned integer type uint8_t; // optionalEntonces, en esencia, no se necesita una biblioteca conforme estándar C ++ para definir uint8_t (ver el comentario // opcional )El punto es escribir código independiente de la implementación.
unsigned charno se garantiza que sea un tipo de 8 bits.uint8_tes (si está disponible).fuente
sizeof(unsigned char)regresará1por 1 byte. pero si un sistema char e int son del mismo tamaño, por ejemplo, de 16 bitssizeof(int), también volverá1Como dijiste, " casi todos los sistemas".
chares probablemente uno de los menos propensos a cambiar, pero una vez que comience a usaruint16_ty amigos, usar lasuint8_tmezclas mejor, e incluso puede ser parte de un estándar de codificación.fuente
En mi experiencia, hay dos lugares donde queremos usar uint8_t para significar 8 bits (y uint16_t, etc.) y donde podemos tener campos de menos de 8 bits. Ambos lugares son donde el espacio es importante y, a menudo, necesitamos mirar un volcado sin procesar de los datos al depurar y debemos poder determinar rápidamente qué representa.
El primero está en los protocolos de RF, especialmente en los sistemas de banda estrecha. En este entorno, es posible que necesitemos empaquetar tanta información como podamos en un solo mensaje. El segundo es en el almacenamiento flash, donde podemos tener un espacio muy limitado (como en los sistemas integrados). En ambos casos, podemos usar una estructura de datos empaquetados en la que el compilador se encargará del empaque y desempaquetado por nosotros:
El método que use depende de su compilador. Es posible que también deba admitir varios compiladores diferentes con los mismos archivos de encabezado. Esto sucede en sistemas integrados donde los dispositivos y servidores pueden ser completamente diferentes, por ejemplo, puede tener un dispositivo ARM que se comunica con un servidor Linux x86.
Hay algunas advertencias sobre el uso de estructuras empaquetadas. El mayor problema es que debe evitar desreferenciar la dirección de un miembro. En sistemas con palabras mutibyte alineadas, esto puede resultar en una excepción desalineada, y un coredump.
Algunas personas también se preocuparán por el rendimiento y argumentarán que el uso de estas estructuras empaquetadas ralentizará su sistema. Es cierto que, detrás de escena, el compilador agrega código para acceder a los miembros de datos no alineados. Puede ver eso mirando el código de ensamblaje en su IDE.
Pero dado que las estructuras empaquetadas son más útiles para la comunicación y el almacenamiento de datos, los datos se pueden extraer en una representación no empaquetada cuando se trabaja con ellos en la memoria. Normalmente no necesitamos trabajar con todo el paquete de datos en la memoria de todos modos.
Aquí hay una discusión relevante:
pragma pack (1) ni __attribute__ ((alineado (1))) funciona
¿El __attribute __ ((empaquetado)) / #pragma pack de gcc no es seguro?
http://solidsmoke.blogspot.ca/2010/07/woes-of-structure-packing-pragma-pack.html
fuente
Hay poco. Desde el punto de vista de la portabilidad,
charno puede ser menor que 8 bits, y nada puede ser menor quechar, por lo que si una implementación C dada tiene un tipo entero de 8 bits sin signo, seráchar. Alternativamente, es posible que no tenga ninguno, en cuyo punto cualquiertypedeftruco es discutible.Podría usarse para documentar mejor su código en el sentido de que está claro que necesita bytes de 8 bits y nada más. Pero en la práctica, es una expectativa razonable prácticamente en cualquier lugar (hay plataformas DSP en las que no es cierto, pero las posibilidades de que su código se ejecute allí son escasas, y también podría equivocarse usando una afirmación estática en la parte superior de su programa en tal plataforma).
fuente
unsigned charpoder mantener valores entre 0 y 255. Si puedes hacerlo en 4 bits, no tengo ganas.uint8_ta la implementación. Me pregunto, ¿los compiladores para DSP con caracteres de 16 bits suelen implementarseuint8_to no?#include <stdint.h>, y usaruint8_t. Si la plataforma lo tiene, se lo dará. Si la plataforma no lo tiene, su programa no se compilará, y la razón será clara y directa.Eso es realmente importante, por ejemplo, cuando está escribiendo un analizador de red. los encabezados de paquetes se definen por la especificación del protocolo, no por la forma en que funciona el compilador C de una plataforma en particular.
fuente
En casi todos los sistemas he conocido uint8_t == unsigned char, pero esto no está garantizado por el estándar C. Si está intentando escribir código portátil y importa exactamente el tamaño de la memoria, use uint8_t. De lo contrario, use char sin firmar.
fuente
uint8_tsiempre coincide con el rango y el tamañounsigned chary el relleno (ninguno) cuandounsigned chares de 8 bits. Cuandounsigned charno es de 8 bits,uint8_tno existe.unsigned charestá 8 bits, seuint8_tgarantiza que sea unatypedefde la misma y no unatypedefde un tipo entero sin signo extendido ?unsigned char/signed char/charel tipo más pequeño, no más pequeño que 8 bits.unsigned charNo tiene relleno. Parauint8_tser, debe ser de 8 bits, sin relleno, debido a un tipo entero proporcionado por la implementación: que coincida con los requisitos mínimos deunsigned char. En cuanto a "... garantizado para ser un typedef ..." parece una buena pregunta para publicar.