resueltos - ¿Por qué las transmisiones en C++ usan char en lugar de char sin signo?
programas en c++ ejemplos avanzados (4)
Siempre me he preguntado por qué la biblioteca estándar de C ++ ha creado una instancia de la secuencia básica_ [io] y todas sus variantes utilizando el tipo de caracteres en lugar del tipo de caracteres unsigned char
. char
significa (dependiendo de si está firmado o no) puede tener desbordamiento y subdesbordamiento para operaciones como get (), lo que conducirá a un valor definido por la implementación de las variables involucradas. Otro ejemplo es cuando desea enviar un byte, sin formatear, a un ostream usando su función put
.
¿Algunas ideas?
Nota : todavía no estoy muy convencido. Entonces, si conoce la respuesta definitiva, puede publicarla de hecho.
Posiblemente he entendido mal la pregunta, pero la conversión de char sin signo a char no está sin especificar, depende de la implementación (4.7-3 en el estándar de C ++).
El tipo de un carácter de 1 byte en C ++ es "char", no "char sin signo". Esto da a las implementaciones un poco más de libertad para hacer lo mejor en la plataforma (por ejemplo, el cuerpo de estándares puede haber creído que existen CPUs donde la aritmética de byte con signo es más rápida que la aritmética de bytes sin signo, aunque eso es especulación por mi parte). También por compatibilidad con C. El resultado de eliminar este tipo de incertidumbre existencial de C ++ es C # ;-)
Dado que el tipo "char" existe, creo que tiene sentido que las secuencias habituales lo usen aunque su firma no esté definida. Entonces, tal vez su pregunta se responda con la respuesta a "¿por qué C ++ no acaba de definir el carácter que no va a firmar?"
char es para caracteres, char sin signo para bytes de datos sin procesar y caracteres con signo para, bueno, datos firmados.
Standard no especifica si se usará char firmado o no firmado para la implementación de char: es específico del compilador. Solo especifica que el "carácter" será "suficiente" para contener los caracteres en su sistema, tal como estaban los caracteres en ese momento, es decir, no UNICODE.
Usar "char" para los personajes es la forma estándar de hacerlo. Usar char sin signo es un truco, aunque coincidirá con la implementación del compilador de char en la mayoría de las plataformas.
Siempre lo he entendido de esta manera: el objetivo de la clase iostream
es leer y / o escribir una secuencia de caracteres, que, si lo piensas, son entidades abstractas que solo están representadas por la computadora que utiliza una codificación de caracteres. El estándar C ++ hace grandes esfuerzos para evitar fijar la codificación de caracteres, diciendo solo que "Los objetos declarados como caracteres ( char
) deben ser lo suficientemente grandes como para almacenar cualquier miembro del conjunto de caracteres básicos de la implementación", porque no es necesario forzar el "conjunto de caracteres básicos de implementación" para definir el lenguaje C ++; el estándar puede dejar la decisión de qué codificación de caracteres se usa para la implementación (compilador junto con una implementación de STL), y simplemente tenga en cuenta que los objetos char
representan caracteres únicos en algunas codificaciones.
Un escritor de implementación podría elegir una codificación de un solo octeto, como ISO-8859-1 o incluso una codificación de doble octeto, como UCS-2 . No importa. Siempre que un objeto char
sea "lo suficientemente grande como para almacenar cualquier miembro del conjunto de caracteres básicos de la implementación" (tenga en cuenta que esto prohíbe explícitamente las codificaciones de longitud variable ), la implementación incluso puede elegir una codificación que represente el latín básico de una manera incompatible con cualquier codificación común!
Es confuso que los tipos de caracteres char
, signed char
y unsigned char
comparten "char" en sus nombres, pero es importante tener en cuenta que char
no pertenece a la misma familia de tipos fundamentales como signed char
y unsigned char
. signed char
está en la familia de tipos enteros con signo:
Hay cuatro tipos de entero con signo : "char firmado", "short int", "int" y "long int".
y unsigned char
está en la familia de tipos enteros sin signo:
Para cada uno de los tipos de entero con signo, existe un tipo entero sin signo correspondiente (pero diferente): "unsigned char", "unsigned short int", "unsigned int" y "unsigned long int", ...
La única similitud entre los tipos de caracteres char
, signed char
y unsigned char
es que "[ellos] ocupan la misma cantidad de almacenamiento y tienen los mismos requisitos de alineación". Por lo tanto, puede reinterpret_cast
desde char *
a unsigned char *
para determinar el valor numérico de un carácter en el conjunto de caracteres de ejecución.
Para responder a su pregunta, la razón por la cual el STL usa char
como el tipo predeterminado es porque las transmisiones estándar están diseñadas para leer y / o escribir secuencias de caracteres, representadas por objetos char
, no enteros ( signed char
y unsigned char
). El uso de char
frente al valor numérico es una forma de separar las preocupaciones.
Creo que este comentario lo explica bien. Citar:
signed char y unsigned char son aritméticos, tipos integrales como int y unsigned int. Por otro lado, char está expresamente destinado a ser del tipo "E / S" que representa una unidad de datos fundamental opaca y específica del sistema en su plataforma. Yo los usaría en este espíritu.