Diferencia entre el uso de punteros de caracteres y matrices de caracteres

Pregunta básica

char new_str[]=""; char * newstr; 

Si tengo que concatenar algunos datos en él o usar funciones de cadena como strcat / substr / strcpy, ¿cuál es la diferencia entre los dos?

Entiendo que tengo que asignar memoria al enfoque char * (Línea # 2). No estoy muy seguro de cómo.

¿Y const char * y los literales son los mismos?

Necesito saber más sobre esto. ¿Alguien puede señalar algún buen contenido / material exhaustivo?

Por favor revisa este artículo a continuación:

También vea en caso de una matriz de caracteres como en su caso, char new_str [], entonces new_str siempre apuntará a la base de la matriz. El puntero en sí mismo no puede ser incrementado. Sí, puede usar subíndices para acceder al siguiente carácter en matriz, por ejemplo: new_str[3] ;

Pero en el caso de puntero a char, el puntero se puede incrementar new_str++ para buscar el siguiente caracter en la matriz.

También sugeriría este artículo para mayor claridad.

La excelente fuente para aclarar la confusión es Peter Van der Linden, Expert C Programming, Deep C secrets: las matrices y los punteros no son lo mismo es cómo se tratan en la memoria.

Con una matriz,

  char new_str []; 

el comstackdor le ha dado a new_str una dirección de memoria que se conoce tanto en comstackción como en tiempo de ejecución, por ejemplo, 0x1234, por lo que la indexación de new_str es simple al usar [] . Por ejemplo, new_str[4] , en tiempo de ejecución, el código elige la dirección de donde reside new_str , por ejemplo, 0x1234 (es decir, la dirección en la memoria física). agregando el especificador de índice [4] , 0x1234 + 0x4, el valor puede recuperarse.

Mientras que, con un puntero, el comstackdor da el símbolo

  char * newstr 

una dirección, por ejemplo, 0x9876, pero en el tiempo de ejecución, esa dirección utilizada, es un esquema de direccionamiento indirecto. Suponiendo que newstr estaba malloc

  newstr = malloc (10); 

, lo que está sucediendo es que, cada vez que se hace una referencia en el código para usar newstr, ya que la dirección de newstr es conocida por el comstackdor, es decir, 0x9876, pero lo que está señalando newstr es variable. En tiempo de ejecución, el código obtiene datos de la memoria física 0x9876 (es decir, newstr), pero en esa dirección hay otra dirección de memoria (ya que la hemos malloclado), por ejemplo, 0x8765 está aquí, el código recupera los datos de esa dirección de memoria que malloc asignado a newstr, es decir, 0x8765.

Los caracteres char new_str[] y char *newstr se usan indistintamente, ya que un índice de elemento zeroth de la matriz decae en un puntero y eso explica por qué podría newstr[5] o *(newstr + 5) Observe cómo se usa la expresión de puntero incluso aunque hemos declarado char *newstr , por lo tanto

  *(new_str + 1) = * newstr; 

O

  *(new_str + 1) = newstr [1]; 

En resumen, la diferencia real entre los dos es cómo se accede a ellos en la memoria.

Coge el libro, léelo, vívelo y respíralo. Es un libro shiny! 🙂

Esta es una matriz de caracteres:

 char buf [1000]; 

Entonces, por ejemplo, esto no tiene sentido:

 buf = &some_other_buf; 

Esto se debe a que buf , aunque tiene características de tipo puntero, ya apunta al único lugar que tiene sentido para él.

 char *ptr; 

Por otro lado, ptr es solo un puntero y puede apuntar a alguna parte. Muy a menudo, es algo como esto:

 ptr = buf; // #1: point to the beginning of buf, same as &buf[0] 

o tal vez esto:

 ptr = malloc (1000); // #2: allocate heap and point to it 

o:

 ptr = "abcdefghijklmn"; // #3: string constant 

Para todos estos, se puede escribir * ptr, excepto en el tercer caso donde algún entorno de comstackción define las constantes de cadena como no escribibles.

 *ptr++ = 'h'; // writes into #1: buf[0], #2: first byte of heap, or // #3 overwrites "a" strcpy (ptr, "ello"); // finishes writing hello and adds a NUL 

La diferencia es que uno es un puntero, el otro es una matriz. Puede, por ejemplo, sizeof () array. Usted puede estar interesado en leer aquí

Si usa C ++ como lo indican sus tags, realmente debería usar las cadenas de C ++, no las de C char .

El tipo de string hace que manipular cadenas sea mucho más fácil.

Si por alguna razón estás atrapado en matrices de caracteres, la línea:

 char new_str[] = ""; 

asigna 1 byte de espacio y le pone un carácter terminador nulo. Es sutilmente diferente de:

 char *new_str = ""; 

ya que eso puede darle una referencia a la memoria no grabable. La statement:

 char *new_str; 

por sí solo te da un puntero, pero nada de lo que apunta. También puede tener un valor aleatorio si es local para una función.

Lo que las personas tienden a hacer (en C en lugar de C ++) es hacer algo como:

 char *new_str = malloc (100); // (remember that this has to be freed) or char new_str[100]; 

para obtener suficiente espacio

Si usa las funciones str... , básicamente es responsable de asegurarse de tener suficiente espacio en la matriz de caracteres, para que no tenga todo tipo de prácticas raras y maravillosas en el código de depuración. Si usa cadenas reales de C ++, se hace mucho del trabajo pesado para usted.

El tipo del primero es char [1], el segundo es char *. Diferentes tipos.

Asigne memoria para este último con malloc en C o new en C ++.

 char foo[] = "Bar"; // Allocates 4 bytes and fills them with // 'B', 'a', 'r', '\0'. 

El tamaño aquí está implícito desde la cadena de inicializador.

Los contenidos de foo son mutables. Puede cambiar foo[i] por ejemplo donde i = 0..3.

OTOH si lo haces:

 char *foo = "Bar"; 

El comstackdor ahora asigna una cadena estática “Barra” en la memoria de solo lectura y no se puede modificar.

 foo[i] = 'X'; // is now undefined. 
 char new_str[]="abcd"; 

Esto especifica una matriz de caracteres (una cadena) de 5 bytes de tamaño (un byte para cada carácter más uno para el terminador nulo). Entonces almacena la cadena ‘abcd’ en la memoria y podemos acceder a esta cadena usando la variable new_str.

 char *new_str="abcd"; 

Esto especifica que una cadena ‘abcd’ está almacenada en algún lugar de la memoria y el puntero new_str apunta al primer carácter de esa cadena.

Para diferenciarlos en el lado de la asignación de memoria:

 // With char array, "hello" is allocated on stack char s[] = "hello"; // With char pointer, "hello" is stored in the read-only data segment in C++'s memory layout. char *s = "hello"; // To allocate a string on heap, malloc 6 bytes, due to a NUL byte in the end char *s = malloc(6); s = "hello"; 

Si estás en C ++, ¿por qué no usar std :: string para todas tus necesidades de cadenas? Especialmente todo lo relacionado con la concatenación. Esto te salvará de muchos problemas.