lenguaje - funciones de cadenas de caracteres en c++
¿Por qué las cadenas en C necesitan ser anuladas? (9)
Me pregunto por qué este es el caso. Estoy ansioso por saber más acerca de los idiomas de bajo nivel, y solo estoy en los conceptos básicos de C y esto ya me está confundiendo.
¿Los lenguajes como PHP anulan automáticamente las cadenas a medida que se interpretan y / o analizan?
C no tiene noción de cuerdas por sí misma. Las cadenas son simplemente matrices de caracteres (o wchars para Unicode y similares).
Debido a esos hechos, C no tiene forma de verificar, es decir, la longitud de la cadena, ya que no hay "mystring-> length", no hay un valor de longitud establecido en alguna parte. La única forma de encontrar el final de la cadena es iterar sobre ella y verificar el / 0.
Hay bibliotecas de cadenas para C que usan estructuras como
struct string {
int length;
char *data;
};
para eliminar la necesidad de la terminación / 0, pero esto no es el estándar C.
Los lenguajes como C ++, PHP, Perl, etc. tienen sus propias bibliotecas de cadenas internas que a menudo tienen un campo de longitud independiente que acelera algunas funciones de cadena y elimina la necesidad de / 0.
Algunos otros lenguajes (como Pascal) usan un tipo de cadena que se llama (de manera sorprendente) Cadena Pascal, almacena la longitud en el primer byte de la cadena, por lo que esas cadenas están limitadas a una longitud de 255 caracteres.
Deben estar terminados en nulo para que sepas cuánto tiempo tienen. Y sí, son simplemente matrices de char.
Los lenguajes de nivel superior como PHP pueden optar por ocultar la terminación nula de usted o no usarla en absoluto; pueden mantener una longitud, por ejemplo. C no lo hace así debido a la sobrecarga involucrada. Es posible que los lenguajes de alto nivel no implementen cadenas como una matriz de caracteres; podrían (y algunos lo hacen) implementarlas como listas de matrices de caracteres, por ejemplo.
Del excelente artículo de Joel sobre el tema:
Recuerde cómo funcionan las cadenas en C: consisten en un conjunto de bytes seguidos de un carácter nulo, que tiene el valor 0. Esto tiene dos implicaciones obvias:
No hay forma de saber dónde termina la cadena (es decir, la longitud de la cadena) sin moverse a través de ella, buscando el carácter nulo al final. Tu cadena no puede tener ceros en ella. Por lo tanto, no puede almacenar un blob binario arbitrario como una imagen JPEG en una cadena C. ¿Por qué las cadenas en C funcionan de esta manera? Es porque el microprocesador PDP-7, en el que se inventaron UNIX y el lenguaje de programación C, tenía un tipo de cadena ASCIZ. ASCIZ significa "ASCII con una Z (cero) al final".
¿Es esta la única manera de almacenar cadenas? No, de hecho, es una de las peores formas de almacenar cadenas. Para programas no triviales, API, sistemas operativos, bibliotecas de clases, debe evitar cadenas ASCIZ como la plaga.
En C, las cadenas están representadas por una matriz de caracteres asignados en un bloque de memoria contiguo y, por lo tanto, debe haber un indicador que indique el final del bloque (es decir, el carácter nulo), o una forma de almacenar la longitud (como las cadenas de Pascal que están prefijados por una longitud).
En lenguajes como PHP, Perl, C #, etc., las cadenas pueden o no tener estructuras de datos complejas, por lo que no puede asumir que tienen un carácter nulo. Como ejemplo artificial, podría tener un lenguaje que represente una cadena como esta:
class string
{
int length;
char[] data;
}
pero solo lo ve como una cadena regular sin campo de longitud, ya que esto puede ser calculado por el entorno de ejecución del idioma y solo se usa internamente para asignar y acceder a la memoria correctamente.
Es una convención: se podría haber implementado con otro algoritmo (por ejemplo, la longitud al comienzo del búfer).
En un lenguaje de "bajo nivel" como ensamblador, es fácil probar "NULL" de manera eficiente: eso podría facilitar la decisión de usar cadenas terminadas en NULL en lugar de mantener un registro de un contador de longitud.
Están terminados en cero porque muchas funciones de la biblioteca estándar esperan que lo sean.
Las cadenas C son matrices de caracteres, y una matriz C es solo un puntero a una ubicación de memoria, que es la ubicación de inicio de la matriz. Pero también la longitud (o final) de la matriz debe expresarse de alguna manera; En el caso de cadenas, se utiliza una terminación nula. Otra alternativa sería llevar de algún modo la longitud de la cadena junto con el puntero de la memoria, o colocar la longitud en la primera ubicación de la matriz, o lo que sea. Es sólo una cuestión de convención.
Los lenguajes de nivel superior como Java o PHP almacenan la información de tamaño con la matriz de forma automática y transparente, por lo que el usuario no tiene que preocuparse por ellos.
Piense acerca de qué es la memoria: un bloque contiguo de unidades de tamaño byte que se puede rellenar con cualquier patrón de bits.
2a c6 90 f6
Un personaje es simplemente uno de esos patrones de bits. Su significado como una cuerda está determinado por la forma en que lo tratas. Si miras la misma parte de la memoria, pero al usar una vista entera (o algún otro tipo), obtendrás un valor diferente.
Si tiene una variable que es un puntero al comienzo de un grupo de caracteres en la memoria, debe saber cuándo termina esa cadena y comienza la siguiente pieza de datos (o basura).
Ejemplo
Veamos esta cadena en la memoria ...
H e l l o , w o r l d ! /0
^
|
+------ Pointer to string
... podemos ver que la cadena termina lógicamente después de !
personaje. Si no hubiera /0
(o cualquier otro método para determinar su fin), ¿cómo sabríamos al buscar a través de la memoria que habíamos terminado con esa cadena? Otros idiomas llevan la longitud de la cadena con el tipo de cadena para resolver esto.
Hice esta pregunta cuando mi conocimiento subyacente de las computadoras era limitado, y esta es la respuesta que habría ayudado hace muchos años. Espero que ayude a alguien más también. :)
Porque en C, las cadenas son solo una secuencia de caracteres a los que se accede desde un puntero al primer carácter.
No hay espacio en un puntero para almacenar la longitud, por lo que necesita alguna indicación de dónde está el final de la cadena.
En C se decidió que esto sería indicado por un carácter nulo.
En pascal, por ejemplo, la longitud de una cadena se registra en el byte inmediatamente anterior al puntero, por lo que las cadenas pascal tienen una longitud máxima de 255 caracteres.