c++ que ¿Por qué las cadenas usan char*?




hombres con cadenas en el cuello (6)

Jim Balter nota en un comentario que

Las instrucciones en el PDP-11 que tratan con los bytes los trataron como cantidades firmadas, así es como los primeros compiladores de C los trataron, y sin firmar, ni siquiera existían.

Sospecho firmemente que esta es la respuesta a la razón por la cual no se requiere que el tipo de carácter predeterminado no esté firmado, pero uno necesita una cita de alguna cuenta histórica escrita para estar seguro.

En cuanto a por qué no se requiere que se firme (!), En una máquina complementaria que no sea de dos, como (la única que sé que posiblemente todavía esté en uso) un Clearpath Dorado, un personaje signed char no puede contener todos los valores de un unsigned char , ya que está desperdiciando un patrón de bits en un cero negativo, o lo que sea que se use para ese patrón de bits. Si se requiriera que se firmara char , esto sería un problema para reinterpretar los datos generales como una secuencia de valor char . En consecuencia, en una máquina de este tipo, el char debe estar sin firmar, o, de lo contrario, el software tendrá que participar en contorsiones extremas para enfrentarlo.

¿Por qué la mayoría de las funciones de cadena en los stdlibs C / C ++ toman los punteros char* ?

La firma de caracteres de char ni siquiera está especificada en el estándar, aunque la mayoría de los compiladores modernos (GCC, MSVC) tratan a los caracteres como firmados de forma predeterminada.

¿Cuándo tendría sentido tratar las cadenas como (posiblemente) bytes firmados? AFAIK no hay valores de caracteres significativos por debajo de cero en ningún conjunto de caracteres. Para ciertas operaciones de cadena, los valores deben convertirse a caracteres unsigned char todos modos.

Entonces, ¿por qué los stdlibs usan char* ? Incluso los métodos específicos de C++ , como string::string(const char *); ?


Answer #1

¿Por qué la mayoría de las funciones de cadena en los stdlibs C / C ++ toman los punteros char *?

En C ++ uno usa std :: string. En C, los patrones de uso ya estaban demasiado establecidos cuando se introdujeron los tipos sin firma y no excluiría un problema de eficiencia.

no hay valores de caracteres significativos por debajo de cero

Bueno, hay una restricción en algún lugar del estándar de C ++ de que los caracteres en el conjunto de caracteres básicos son positivos. Pero es ingenuo pensar que esa restricción es válida para todos los personajes.

Esa restricción obliga a las implementaciones que permiten que EBCDIC como sistema de codificación tenga sus caracteres sin firma.

La mayoría de los compiladores modernos (GCC, MSVC) tratan el carácter como firmado por defecto.

El comportamiento de gcc depende del destino y tiene opciones para cambiar el valor predeterminado del objetivo.


Answer #2

El estándar de C es agnóstico en cuanto a si el char simple está firmado o no, y trata de forma única al char distinto del signed char . Además, el conjunto de caracteres ASCII base, que incluye la mayoría de los caracteres principales de control e imprimibles en idioma inglés, consta de 128 caracteres y, por lo tanto, puede representarse adecuadamente mediante un char firmado (al menos en cualquier sistema que proporcione 8 bits por byte). Como señala Jim Balter (ver comentarios a continuación), ASCII no constituye el conjunto de caracteres base completo del lenguaje C, pero sospecho que sí incluyó a la mayoría de los personajes de uso común. También hay un corpus masivo de código C que se basa en las propiedades de (aunque no necesariamente exclusivo de) ASCII (p. Ej., El NUL especial NUL que tiene un valor de cero, los caracteres alfanuméricos se organizan de forma secuencial y en orden ascendente, etc.).


Answer #3

Como dijo Bjarne en The C ++ Programming Language , si un char se toma como firmado o sin firmar depende de la implementación, y el lenguaje C ++ proporciona dos tipos para cada implementación.


Answer #4
  1. Estoy bastante seguro de que la mayoría de las funciones de cadena son anteriores a la existencia de caracteres unsigned char .
  2. El char simple puede ser un tipo firmado o sin firmar. Los estándares C y C ++ permiten explícitamente cualquiera de los dos (siempre es un tipo separado de caracteres unsigned char o caracteres con signed char , pero tiene el mismo rango que uno u otro).
  3. Mientras que las funciones de la cadena C usan char * , std::string es lo que se usa en la mayoría de C ++.

Answer #5

Otros se adentraron en las razones históricas por las que fue así cuando C se diseñó por primera vez y (más tarde) se estandarizó, pero hay otra razón por la que esta aparente anomalía persiste hasta nuestros días.

Simplemente, cuando utiliza caracteres para caracteres, no necesita saber si está firmado o no. La biblioteca estándar proporciona funciones portátiles para operar con caracteres independientemente de su representación. Si ignora esas funciones e insiste en hacer comparaciones y aritmética en los caracteres, merece todos los errores que reciba.

Para tomar un ejemplo simple, es bastante común verificar si un carácter se puede imprimir con la expresión c >= ' ' o, de manera equivalente, con c >= 0x20 , pero en su lugar solo debe usar isprint(c) . De esa manera, no se está exponiendo a una confusión firmada / no firmada y posiblemente está introduciendo errores dependientes de la plataforma en su programa.

Una vez que adquiera el hábito de usar caracteres con unsigned char y caracteres unsigned char solo como números enteros pequeños (generalmente de 8 bits) para la aritmética, y solo use caracteres cuando esté operando con datos de caracteres, parecerá completamente natural que el char sea ​​un tipo separado con firmeza definida por la implementación, e incluso más natural que las funciones de procesamiento de cadenas siempre usan char y char * lugar de las variantes con o sin signo. La firmeza de char parece tan relevante como la firmeza de bool .





c