2009-11-27 14 views
17

Pregunta básica.Diferencia entre el uso de punteros de caracteres y matrices de caracteres

char new_str[]=""; 

char * newstr; 

Si tengo que concatenar algunos datos en él o utilizar 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 n. ° 2). No estoy muy seguro de cómo.

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

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

+1

Tome un vistazo a este increíble tutorial http://pw2.netcom.com/~tjensen/ptr/cpoint.htm – jyz

Respuesta

7

favor vaya a través this article a continuación:

Véase también en el caso de arreglo de char como en su caso, char new_str [] entonces el new_str se siempre punto 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 sugiero this article para mayor claridad.

2

La diferencia es que uno es un puntero, el otro es una matriz. Puede, por ejemplo, sizeof() array. Puede interesarle leer here

1

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

Asignar 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 en la cadena de inicialización.

El contenido de foo es mutable. Puede cambiar foo[i] por ejemplo donde i = 0..3.

otoh si lo hace:

char *foo = "Bar"; 

El compilador ahora asigna una cadena estática "bar" en la memoria de sólo lectura y no se puede modificar.

foo[i] = 'X'; // is now undefined. 
+0

Hmm. Nah. foo no es mutable No puedes cambiar a Foo. Puedes cambiar los elementos de foo, sí, pero no puedes cambiar foo a bar, si bar también es una matriz char, por ejemplo. –

+0

Bastante justo, Sr. Nitpicker. –

-2

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

1

Si usa C++ como lo indican sus etiquetas, realmente debería utilizar las cadenas de C++, no las matrices C char.

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

Si le pegan con char matrices, por alguna razón, la línea:

char new_str[] = ""; 

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

char *new_str = ""; 

ya que eso puede darle una referencia a la memoria no grabable. La declaración:

char *new_str; 

por sí solo le 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..., es básicamente responsable de asegurarse de tener suficiente espacio en la matriz char, 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.

5

Esta es una matriz de caracteres:

char buf [1000]; 

Así, por ejemplo, esto no tiene sentido:

buf = &some_other_buf; 

Esto es debido buf, aunque tiene características de tipo puntero, que ya es apuntando al único lugar que tiene sentido para eso.

char *ptr; 

Por otro lado, ptr sólo es un puntero, y puede señalar 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 ellos, * ptr se puede escribir, excepto la tercera caso donde algún entorno de compilación define las constantes de cadena para ser no escribible.

*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 
8

La fuente excelente para aclarar la confusión es Peter Van der Linden, Experto de programación C, C - secretos profundos que las matrices y los punteros no son lo mismo es la forma en que son tratados en la memoria.

Con una matriz,

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

Considerando que, con un puntero, el compilador le da al símbolo

char *newstr
una dirección, p. 0x9876, pero en el tiempo de ejecución, esa dirección utilizada, es un esquema de direccionamiento indirecto. Suponiendo que newstr estuviera malloc'd
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 compilador, 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.

El char new_str[] y char *newstr se utilizan indistintamente, ya que un índice de elementos cero de la matriz se desintegra en un puntero y que explica por qué usted podría newstr[5] o *(newstr + 5) Observe cómo se utiliza la expresión puntero a pesar de que 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.

Consigue el libro y léelo y vividlo y respíralo. Es un libro brillante! :)

+2

Como nota al margen: C tiene expresiones conmutativas, por ejemplo 4 + 3 es igual a 3 + 4. Esto también se aplica a los punteros, * (new_str + 1) es igual que * (1 + new_str) que incidentalmente es 1 [new_str]. Eso fue una broma y se hace referencia en otra parte de la red, probablemente para echar a alguien. ¡Rara vez se usa en producción, todavía no se ha visto en ningún lado! – t0mm13b

0
char new_str[]="abcd"; 

Esto especifica un conjunto de caracteres (una cadena) de tamaño 5 bytes (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 una cadena 'abcd' se almacena en algún lugar de la memoria y el puntero new_str puntos para el primer carácter de la cadena.

0

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"; 
Cuestiones relacionadas