2010-05-30 32 views

Respuesta

2

La primera declaración declara una matriz, mientras que la segunda es un puntero.

Si le interesa la diferencia en algún aspecto en particular, aclare su pregunta.

9

char a[]="string"; // a es una matriz de caracteres.

char *p="string"; // p es una cadena literal que tiene una asignación estática. Cualquier intento de modificar el contenido de p conduce a un comportamiento no definido ya que los literales de cadena se almacenan en la sección de solo lectura de la memoria.

2

Sin diferencia. A menos que quieras escribir en la matriz, en cuyo caso el mundo entero explotará si tratas de usar la segunda forma. Ver here.

27

El primero es una matriz y el otro es un puntero.

La declaración de matriz "char a[6];" pide que el espacio de seis caracteres ser puesta a un lado, al ser conocido por el nombre de "a." Es decir, no es un lugar llamado "a" en la que seis personajes pueden sentarse. La declaración del puntero "char *p;", por otro lado, solicita un lugar que contiene un puntero. El puntero debe ser conocido con el nombre "p," y puede señalar cualquier char (o conjunto contiguo de caracteres) en cualquier lugar.

Las declaraciones

char a[] = "hello"; 
char *p = "world"; 

darían lugar a estructuras de datos que podrían ser representados como esto:

+---+---+---+---+---+---+ 
a: | h | e | l | l | o |\0 | 
    +---+---+---+---+---+---+ 
    +-----+  +---+---+---+---+---+---+ 
p: | *======> | w | o | r | l | d |\0 | 
    +-----+  +---+---+---+---+---+---+ 

Es importante darse cuenta de que tal referencia x [3] genera un código diferente dependiendo de si x es una matriz o un puntero. Dadas las declaraciones anteriores, cuando el compilador ve la expresión a [3], emite código para comenzar en la ubicación "a", mueve tres hacia atrás y busca el carácter allí. Cuando ve la expresión p [3], emite código para comenzar en la ubicación "p", busca el valor del puntero allí, agrega tres al puntero y finalmente busca el carácter al que apunta. En el ejemplo anterior, tanto un [3] como un p [3] resultan ser el carácter 'l', pero el compilador llega allí de manera diferente.

Puede utilizar buscar hay toneladas de explicaciones sobre el tema en Internet.

+4

¿dónde se asigna la memoria en el primer caso y dónde en el segundo caso? ¿apilar? ¿montón? Cuando decides apuntar p a algo más, ¿significa eso que "wrold" será desasignado? – Laz

+6

+1 para ilustraciones ASCII. –

+3

@Ram Bhat: en el primer caso, depende de dónde se coloca esa definición; si está en una función, probablemente en la pila, si está en una estructura, depende del lugar donde se asigna la estructura completa; si está fuera de cualquier función, en el segmento global vars. Lo mismo vale para el puntero p; la cadena "mundial" a la que p señala, en cambio, * normalmente * está en una sección particular del ejecutable que se mapea en la memoria al cargar, que se utiliza como tabla de cadenas. –

1

Una diferencia es que sizeof (a) -1 se reemplazará con la longitud de la cadena en el momento de la compilación. Con p necesita usar strlen (p) para obtener la longitud en tiempo de ejecución. Además, a algunos compiladores no les gusta char * p = "cadena", quieren const char * p = "cadena", en cuyo caso la memoria para "cadena" es de solo lectura pero la memoria para a no lo es. Incluso si el compilador no requiere la declaración const, es una mala práctica modificar la cadena apuntada por p (es decir, * p = 'a'). El puntero p se puede cambiar para señalar a otra cosa. Con la matriz a, se debe copiar un nuevo valor en la matriz (si corresponde).