Pregunta

En C/C++, ¡qué unsigned char ¿se utiliza para?¿En qué se diferencia de un regular? char?

¿Fue útil?

Solución

En C++ hay tres distinto tipos de personajes:

  • char
  • signed char
  • unsigned char

Si está utilizando tipos de caracteres para texto, utilice el no calificado char:

  • es el tipo de caracteres literales como 'a' o '0'.
  • es el tipo que forma las cuerdas C como "abcde"

También funciona como un valor numérico, pero no se especifica si ese valor se trata como con o sin signo.Tenga cuidado con las comparaciones de caracteres mediante desigualdades, aunque si se limita a ASCII (0-127), estará prácticamente a salvo.

Si está utilizando tipos de caracteres como números, usar:

  • signed char, que te da al menos el rango de -127 a 127.(-128 a 127 es común)
  • unsigned char, que te da al menos el rango de 0 a 255.

"Al menos", porque el estándar C++ solo proporciona el rango mínimo de valores que cada tipo numérico debe cubrir. sizeof (char) se requiere que sea 1 (es decir,un byte), pero en teoría un byte podría ser, por ejemplo, 32 bits. sizeof todavía estaría informando su tamaño como 1 - lo que significa que tú podría tener sizeof (char) == sizeof (long) == 1.

Otros consejos

Esto depende de la implementación, ya que el estándar C NO define la firma de char.Dependiendo de la plataforma, el carbón puede ser signed o unsigned, por lo que debe solicitar explícitamente signed char o unsigned char si su implementación depende de ello.Solo usa char si pretende representar caracteres a partir de cadenas, ya que esto coincidirá con lo que su plataforma pone en la cadena.

La diferencia entre signed char y unsigned char es como era de esperar.En la mayoría de las plataformas, signed char será un número en complemento a dos de 8 bits que oscilará entre -128 a 127, y unsigned char será un entero sin signo de 8 bits (0 a 255).Tenga en cuenta que la norma NO requiere que char Los tipos tienen 8 bits, solo eso. sizeof(char) devolver 1.Puedes obtener el número de bits en un carácter con CHAR_BIT en limits.h.Hoy en día hay pocas plataformas, si es que hay alguna, en las que esto sea algo más que 8, aunque.

Hay un buen resumen de este tema. aquí.

Como otros han mencionado desde que publiqué esto, es mejor que uses int8_t y uint8_t si realmente quieres representar números enteros pequeños.

Como creo que es realmente necesario, solo quiero establecer algunas reglas de C y C++ (son iguales en este sentido).Primero, todos los bits de unsigned char participar en la determinación del valor de cualquier objeto char sin firmar.Segundo, unsigned char se indica explícitamente sin firmar.

Ahora, tuve una discusión con alguien sobre lo que sucede cuando conviertes el valor -1 de tipo int a unsigned char.Rechazó la idea de que el resultado unsigned char tiene todos sus bits establecidos en 1, porque estaba preocupado por la representación de signos.Pero no es necesario.De esta regla se desprende inmediatamente que la conversión hace lo que se pretende:

Si el nuevo tipo no está firmado, el valor se convierte sumando o restando repetidamente uno más que el valor máximo que se puede representar en el nuevo tipo hasta que el valor esté en el rango del nuevo tipo.(6.3.1.3p2 en un borrador C99)

Esa es una descripción matemática.C++ lo describe en términos de cálculo de módulo, que se ajusta a la misma regla.De todos modos, ¿qué es no garantizado es que todos los bits del número entero -1 son uno antes de la conversión.Entonces, ¿qué tenemos para poder afirmar que el resultado unsigned char tiene todos sus CHAR_BIT ¿Los bits se convirtieron en 1?

  1. Todos los bits participan en la determinación de su valor, es decir, no se producen bits de relleno en el objeto.
  2. Agregando solo una vez UCHAR_MAX+1 a -1 producirá un valor dentro del rango, es decir UCHAR_MAX

¡Eso es suficiente, en realidad!Así que siempre que quieras tener un unsigned char teniendo todos sus bits uno, lo haces

unsigned char c = (unsigned char)-1;

También se deduce que una conversión es no simplemente truncando bits de orden superior.El acontecimiento afortunado para complemento a dos es que allí es solo un truncamiento, pero lo mismo no es necesariamente cierto para otras representaciones de signos.

Como por ejemplo usos de carácter sin firmar:

carácter sin firmar se utiliza a menudo en gráficos por computadora, que muy a menudo (aunque no siempre) asigna un solo byte a cada componente de color.Es común ver un color RGB (o RGBA) representado como 24 (o 32) bits, cada uno de ellos carácter sin firmar.Desde carácter sin firmar Los valores caen en el rango [0,255], los valores normalmente se interpretan como:

  • 0 significa una falta total de un componente de color determinado.
  • 255 significa el 100% de un pigmento de color determinado.

Entonces terminarías con RGB rojo como (255,0,0) -> (100% rojo, 0% verde, 0% azul).

¿Por qué no utilizar un carácter firmado?La aritmética y el desplazamiento de bits se vuelven problemáticos.Como ya se explicó, un carácter firmadoEl rango de esencialmente se desplaza en -128.Un método muy simple e ingenuo (en su mayoría no utilizado) para convertir RGB a escala de grises es promediar los tres componentes de color, pero esto genera problemas cuando los valores de los componentes de color son negativos.El rojo (255, 0, 0) promedia a (85, 85, 85) cuando se usa carácter sin firmar aritmética.Sin embargo, si los valores fueran carácter firmados (127,-128,-128), terminaríamos con (-99, -99, -99), que sería (29, 29, 29) en nuestro carácter sin firmar espacio, lo cual es incorrecto.

Si desea utilizar un carácter como un número entero pequeño, la forma más segura de hacerlo es con el int8_ty uint8_t tipos.

signed char tiene un rango de -128 a 127; unsigned char tiene un rango de 0 a 255.

char será equivalente a char firmado o char sin firmar, dependiendo del compilador, pero es un tipo distinto.

Si estás usando cadenas de estilo C, solo usa char.Si necesita utilizar caracteres para aritmética (bastante raro), especifique explícitamente firmado o sin firmar para portabilidad.

char y unsigned char No se garantiza que sean tipos de 8 bits en todas las plataformas; se garantiza que serán de 8 bits o más.Algunas plataformas tienen Bytes de 9 bits, 32 bits o 64 bits.Sin embargo, las plataformas más comunes hoy en día (Windows, Mac, Linux x86, etc.) tienen bytes de 8 bits.

En términos de valores directos, se utiliza un carácter regular cuando se sabe que los valores están entre CHAR_MIN y CHAR_MAX mientras que un carácter sin firmar proporciona el doble de rango en el extremo positivo.Por ejemplo, si CHAR_BIT es 8, el rango de regular char solo se garantiza que sea [0, 127] (porque puede estar firmado o sin firmar) mientras unsigned char será [0, 255] y signed char será [-127, 127].

En términos de para qué se utiliza, los estándares permiten que los objetos de POD (datos antiguos simples) se conviertan directamente en una matriz de caracteres sin firmar.Esto le permite examinar la representación y los patrones de bits del objeto.No existe la misma garantía de juegos de palabras seguros para char o char firmado.

unsigned char solo toma valores positivos....como 0 a 255

mientras

signed char toma valores tanto positivos como negativos....como -128 a +127

Un carácter sin firmar es un valor de byte (sin firmar) (de 0 a 255).Quizás estés pensando en "char" en términos de ser un "carácter", pero en realidad es un valor numérico.El "char" normal está firmado, por lo que tiene 128 valores y estos valores se asignan a caracteres mediante codificación ASCII.Pero en cualquier caso, lo que estás almacenando en la memoria es un valor de byte.

Si le gusta usar varios tipos de longitud y firma específicos, probablemente sea mejor usar uint8_t, int8_t, uint16_t, etc. simplemente porque hacen exactamente lo que dicen.

Un carácter sin signo utiliza el bit reservado para el signo de un carácter normal como otro número.Esto cambia el rango a [0 - 255] en lugar de [-128 - 127].

Generalmente, los caracteres sin firmar se utilizan cuando no se desea un signo.Esto marcará la diferencia al hacer cosas como cambiar bits (shift extiende el signo) y otras cosas cuando se trata de un carácter como un byte en lugar de usarlo como un número.

El carácter sin firmar es el corazón de todos los trucos.En casi TODOS los compiladores para TODAS las plataformas, un carácter sin firmar es simplemente un BYTE.Un entero sin signo de (normalmente) 8 bits.que puede tratarse como un pequeño número entero o un paquete de bits.

Además, como alguien más ha dicho, el estándar no define el signo de un carácter.entonces tienes 3 tipos distintos de "char":char, char firmado, char sin firmar.

Algunas búsquedas en Google encontradas este, donde la gente tuvo una discusión sobre esto.

Un carácter sin firmar es básicamente un solo byte.Por lo tanto, usaría esto si necesita un byte de datos (por ejemplo, tal vez quiera usarlo para activar y desactivar indicadores que se pasarán a una función, como se hace a menudo en la API de Windows).

citado del libro "the c programming laugage":

El calificador signed o unsigned se puede aplicar a char o cualquier número entero.Los números sin firmar son siempre positivos o cero, y obedecen las leyes de la módulo aritmética 2^n, donde n es el número de bits en el tipo.Entonces, por ejemplo, si los caracteres son de 8 bits, las variables de char sin firmar tienen valores entre 0 y 255, mientras que los chars firmados tienen valores entre -128 y 127 (en una máquina de complemento de dos). Ya sea que los chars lisos estén firmados o no se sigan a la máquina. -Permates dependientes, pero imprimibles, siempre son positivos.

El carácter sin firmar solo toma valores positivos:0 a 255 Char firmado toma valores positivos y negativos:-128 a +127

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top