2012-08-31 13 views
9

Estoy confundido acerca de la siguiente línea de código:matriz de punteros a char arrays

char* words[] = { "aaa", "bbbb", "ccccc", "dddddd" }; 

mi modo de entender, cada palabra se almacena primero y luego cada posición de la matriz words apuntará a continuación a la primera carácter de cada palabra. ¿Cómo se almacenan estas cadenas? ¿Hay una asignación dinámica aquí o estas palabras están almacenadas en la pila?

Si se almacenan en la pila, ¿de qué manera se almacenan? Por ejemplo, si puedo imprimir algunos de los contenidos de words de la siguiente manera:

#include <stdio.h> 
int main() { 
    char* words[] = { "aaa", "bbbb", "ccccc", "dddddd" }; 
    printf("\n\n(*words)[0] = %s", words[0]); 
    printf("\n\n(*words)[0]+1 = %s", words[0]+1); 
    return 0; 
} 

en lugar de imprimir aaa y bbbb, lo que consigo es aaa y aa. Realmente no entiendo cuál es el motivo de esto ya que, de la forma en que lo veo, words[0]+1 debe apuntar a la cadena bbbb y no al segundo carácter de aaa. ¿Que esta pasando aqui?

+0

¿Estás confusas palabras '[0] + 1',' (palabras + 1) [0] 'y' palabras [1] '? –

+0

Pruebe '& words [0] + 1' – oldrinb

Respuesta

2

la forma en que lo veo, palabras [0] 1 deben apuntar a la bbbb cadena y no al segundo carácter de aaa

words[0] sí es un puntero char - que está perfectamente bien que obtienes el segundo personaje de "aaa" al agregarle uno. Lo que quiere es words + 1 o &words[0] + 1 que será correctamente "bbbb".

Además, las cadenas en sí se asignan al iniciar el ejecutable y es probable que sean colocadas en la sección de datos o bss del binario por el vinculador. Además, cuando declare e inicialice words, se asignará en la pila como cualquier otra matriz automática y sus elementos se asignarán a punteros al principio de cada constante de cadena.

+0

Veo. De hecho, traté de hacer cosas como 'words [1] [1] = 'u'' para cambiar' bbbb' en 'bubb', pero' bbbb' permanece igual después de que lo cambio (!). ¿Esto se debe a que las cadenas son de solo lectura (estoy asumiendo que son, ya que son valores)? –

+0

@curvature sí lo son. Alégrate de que no se bloquee: la modificación de constantes de cadena es UB. –

3

palabras [0] apunta a la primera 'a' en "aaa".

palabras [0] +1 mueve ese puntero a lo largo de un carácter, por lo que llega a apuntar a la segunda 'a'.

palabras [1] puntos en "BBBB"

palabras [1] +1 puntos "bbb", por ejemplo, la segunda 'b' en "bbbb".

0

palabras [0] devuelve la dirección de aaa. Agregar 1 a eso incrementa la dirección para apuntar al segundo a.

¿Quiere decir palabras [0 + 1]?

Eso debería darle lo que está esperando.

0
char* words[] = { "aaa", "bbbb", "ccccc", "dddddd" }; 

Todas las 4 cadenas tienen una duración de almacenamiento estática y se asignan antes del inicio del programa.

En el inicializador, las matrices se convierten en punteros a char y la matriz words se inicializa con los valores del puntero.

1

Las cadenas literales se almacenan en la memoria estática. Su ubicación real depende de la implementación, pero las cadenas literales se almacenan en algún lugar, normalmente en la parte de datos del ejecutable; esto no es una asignación dinámica ni de pila. Su matriz contiene punteros a estas ubicaciones.

palabras [0] +1 debe apuntar a la cadena bbbb y no al segundo carácter de aaa.

Esto simplemente no es cómo funciona la indexación de matriz. Indexa la matriz de cadenas con words[0], ahora tiene una cadena y todas las operaciones se aplican a esa cadena. No se puede hacer aritmética con índices de matriz fuera del subíndice. Para llegar a la cadena "bbbb", debe usar words[1].

6

La diferencia es porque words[0]+1 no es lo mismo que words[0+1].

El primero apunta al segundo caracter en words[0], mientras que el segundo apunta a la segunda palabra.

1

Tanto el espacio de pila como el de almacenamiento dinámico se asignan dinámicamente, es decir, se asignan en tiempo de ejecución. ¿Su código compilado se asigna dinámicamente, en el montón o la pila? Obviamente ninguno. El almacenamiento para las constantes es similar al almacenamiento del código ... se almacenan en el ejecutable en el disco y se cargan en la memoria de solo lectura. (Nota para los pedantes: así es como se hacen las cosas en una implementación típica, no es obligatorio según el estándar de lenguaje.)

words[0] es la dirección de la primera 'a' de "aaaa". Agregar 1 a esa dirección seguramente debería dar la dirección de la segunda "a" de "aaaa". La dirección de "bbbb" está en words[1].

En el formato de su printf tiene "(* palabras) [0]", pero eso es diferente. *words es lo mismo que words[0]. (*words)[0] es lo mismo que **words, que es la primera 'a' (no su dirección) de "aaaa". Imprimirá (*words)[0] con %c, no %s.

15

esto es como ..

enter image description here

ya que las palabras una serie de caracteres de punteros por lo que cada índice de la matriz de las palabras llevará a cabo la dirección de de la cadena literal, es decir. dirección base de los literales de cadena si va a imprimir

printf("%s",words[0])// index 0 will print aaa. 
Cuestiones relacionadas