usar - ¿Diferencia entre char y char firmado en c++?
declarar string en c (3)
Considere el siguiente código:
#include <iostream>
#include <type_traits>
int main(int argc, char* argv[])
{
std::cout<<"std::is_same<int, int>::value = "<<std::is_same<int, int>::value<<std::endl;
std::cout<<"std::is_same<int, signed int>::value = "<<std::is_same<int, signed int>::value<<std::endl;
std::cout<<"std::is_same<int, unsigned int>::value = "<<std::is_same<int, unsigned int>::value<<std::endl;
std::cout<<"std::is_same<signed int, int>::value = "<<std::is_same<signed int, int>::value<<std::endl;
std::cout<<"std::is_same<signed int, signed int>::value = "<<std::is_same<signed int, signed int>::value<<std::endl;
std::cout<<"std::is_same<signed int, unsigned int>::value = "<<std::is_same<signed int, unsigned int>::value<<std::endl;
std::cout<<"std::is_same<unsigned int, int>::value = "<<std::is_same<unsigned int, int>::value<<std::endl;
std::cout<<"std::is_same<unsigned int, signed int>::value = "<<std::is_same<unsigned int, signed int>::value<<std::endl;
std::cout<<"std::is_same<unsigned int, unsigned int>::value = "<<std::is_same<unsigned int, unsigned int>::value<<std::endl;
std::cout<<"----"<<std::endl;
std::cout<<"std::is_same<char, char>::value = "<<std::is_same<char, char>::value<<std::endl;
std::cout<<"std::is_same<char, signed char>::value = "<<std::is_same<char, signed char>::value<<std::endl;
std::cout<<"std::is_same<char, unsigned char>::value = "<<std::is_same<char, unsigned char>::value<<std::endl;
std::cout<<"std::is_same<signed char, char>::value = "<<std::is_same<signed char, char>::value<<std::endl;
std::cout<<"std::is_same<signed char, signed char>::value = "<<std::is_same<signed char, signed char>::value<<std::endl;
std::cout<<"std::is_same<signed char, unsigned char>::value = "<<std::is_same<signed char, unsigned char>::value<<std::endl;
std::cout<<"std::is_same<unsigned char, char>::value = "<<std::is_same<unsigned char, char>::value<<std::endl;
std::cout<<"std::is_same<unsigned char, signed char>::value = "<<std::is_same<unsigned char, signed char>::value<<std::endl;
std::cout<<"std::is_same<unsigned char, unsigned char>::value = "<<std::is_same<unsigned char, unsigned char>::value<<std::endl;
return 0;
}
El resultado es :
std::is_same<int, int>::value = 1
std::is_same<int, signed int>::value = 1
std::is_same<int, unsigned int>::value = 0
std::is_same<signed int, int>::value = 1
std::is_same<signed int, signed int>::value = 1
std::is_same<signed int, unsigned int>::value = 0
std::is_same<unsigned int, int>::value = 0
std::is_same<unsigned int, signed int>::value = 0
std::is_same<unsigned int, unsigned int>::value = 1
----
std::is_same<char, char>::value = 1
std::is_same<char, signed char>::value = 0
std::is_same<char, unsigned char>::value = 0
std::is_same<signed char, char>::value = 0
std::is_same<signed char, signed char>::value = 1
std::is_same<signed char, unsigned char>::value = 0
std::is_same<unsigned char, char>::value = 0
std::is_same<unsigned char, signed char>::value = 0
std::is_same<unsigned char, unsigned char>::value = 1
Lo que significa que int
y signed int
se consideran del mismo tipo, pero no char
y signed char
. Porqué es eso ?
¿Y si puedo transformar un char
en char
signed char
usando make_signed
, cómo hacer lo contrario (transformar un signed char
en un char
)?
De hecho, el Estándar dice con precisión que char, char firmado y unsigned son 3 tipos diferentes. Un char suele ser de 8 bits, pero esto no está impuesto por la norma. Un número de 8 bits puede codificar 256 valores únicos; la diferencia es solo en cómo se interpretan esos 256 valores únicos. Si considera un valor de 8 bits como un valor binario firmado, puede representar valores enteros desde -128 (codificado 80H) hasta +127. Si considera que no está firmado, puede representar valores de 0 a 255. Por el estándar C ++, se garantiza que un personaje firmado puede mantener los valores de -127 a 127 (no -128!), Mientras que un personaje no firmado puede mantener valores 0 a 255.
Cuando se convierte un char en un int, el resultado es la implementación definida! el resultado puede ser, por ejemplo, -55 o 201 según la implementación de la máquina del carácter único ''É'' (ISO 8859-1). De hecho, una CPU que contiene el carácter en una palabra (16 bits) puede almacenar FFC9 o 00C9 o C900, o incluso C9FF (en representaciones endian grandes y pequeñas). El uso de caracteres firmados o no firmes garantiza el resultado de conversión char a int.
Es por diseño, el estándar de C ++ dice que char
, signed char
y unsigned char
son diferentes tipos. Creo que puedes usar el reparto estático para la transformación.
Hay tres tipos de caracteres básicos distintos : char, char firmado y unsigned char . Aunque hay tres tipos de caracteres, solo hay dos representaciones: firmada y sin firmar. El personaje (normal) usa una de estas representaciones. ¿Cuál de las otras dos representaciones de caracteres es equivalente a char depende del compilador ?
En un tipo sin signo, todos los bits representan el valor. Por ejemplo, un personaje sin signo de 8 bits puede contener los valores de 0 a 255 inclusive.
La norma no define cómo se representan los tipos con signo, pero sí especifica que el rango debe dividirse equitativamente entre valores positivos y negativos. Por lo tanto, se garantiza que un carácter de 8 bits firmado puede contener valores desde -127 hasta 127.
Entonces, ¿cómo decidir qué tipo usar?
Los cálculos que utilizan char son usualmente problemáticos. Por defecto, Char está firmado en algunas máquinas y no firmado en otras. Así que no deberíamos usar (simple) char en expresiones aritméticas. Úsalo solo para contener personajes. Si necesita un entero pequeño, especifique explícitamente entre caracteres con signo o sin signo .