2010-10-29 22 views
9

¿Estas dos líneas de código logran el mismo resultado? Si tuviera estas líneas en una función, ¿la cadena está almacenada en la pila en ambos casos? ¿Hay alguna razón fuerte por la que debería usar una sobre la otra, además de no tener que declarar el terminador nulo en la primera línea de código?En C, ¿puedo inicializar una cadena en una declaración de puntero de la misma manera que puedo inicializar una cadena en una declaración de matriz char?

char s[] = "string"; 
char* s = "string\0"; 
+7

Solo para obtener información, no necesita el \ 0 en el segundo ejemplo. Cuando se utilizan comillas dobles, \ 0 siempre se inserta en la matriz. – RMAAlmeida

+0

Y solo por el vocabulario, de lo que estás hablando no son asignaciones, sino declaraciones con inicializadores. Ellos obedecen diferentes reglas. MI.Si su primera declaración no está permitida como una asignación, no puede asignar matrices. –

+0

posible duplicado de [C: diferencias entre el puntero y la matriz] (http://stackoverflow.com/questions/1335786/c-differences-between-pointer-and-array) –

Respuesta

23

No, esas dos líneas no logran el mismo resultado.

char s[] = "string" da como resultado una matriz modificable de 7 bytes, que inicialmente se rellena con el contenido 's' 't' 'r' 'i' 'n' 'g' '\0' (todo copiado en tiempo de ejecución desde el literal de cadena).

char *s = "string" da como resultado un puntero a memoria de solo lectura que contiene la cadena literal "cadena".

Si desea modificar el contenido de su cadena, la primera es la única manera de hacerlo. Si solo necesita acceso de solo lectura a una cadena, la segunda será un poco más rápida porque la cadena no tiene que ser copiada.


En ambos casos, no hay necesidad de especificar un terminador nulo en el literal de cadena. El compilador se encargará de que, para que cuando se encuentra con el cierre"

+5

Además, el segundo solo está permitido por un legado horrible razones. Debería usar 'const char * s =" cadena ";' –

+0

@Steve: para C++ estaría completamente de acuerdo con usted. Para C, tiendo a dar un margen de maniobra un poco más, porque en la práctica hay demasiadas formas en que el 'const' se interpone en tu camino. (Eso también se conoce como envenenamiento por const) –

+2

Si estoy utilizando bibliotecas dudosas, estoy de acuerdo contigo (a veces). Si el código está bajo mi control, lo arreglo para que 'const' no se interponga en mi camino. La alternativa es tomar copias de cadenas que deben pasarse como parámetros no const a API dudosas. A veces es factible, por ejemplo, si la cadena que se pasa es un literal definido cerca de la llamada, o como global, entonces simplemente use la primera de las dos opciones anteriores. Otras veces es un PITA, en cuyo caso puedes tomar el golpe de strdup o descartar 'const' (que es" inseguro ", pero ya estás usando una API" insegura "). –

2

La diferencia entre estos dos:.

char a[] = "string"; 
char* b = "string"; 

es que a es en realidad una matriz estática en la pila, mientras que B es un puntero a una constante. puede modificar el contenido de una, pero no b.

1

Además de las otras respuestas voy a intentar explicar por qué no se puede modificar la variable *s más adelante en el flujo del programa.

conceptualmente, cuando una el programa se carga en memoria que tiene 3 zonas (segmentos):

  • segmento de código: el texto de su programa se almacena aquí (que es un área de sólo lectura)
  • segmento de datos: contiene las variables globales o estáticas que tienen una valor predefinido y se puede modificar
  • segmento de pila: aquí se cargan las funciones tal como se llaman. El conjunto de valores (un marco de pila) se inserta en la pila para cada llamada de función que contiene la dirección de retorno de la función y las variables locales.

En su caso la variable s[] es una variable local (array), en la función de main(), que se inicializa con el valor "string". Por lo tanto, se almacena en la pila y se puede modificar.

La variable *s es un puntero que apunta a la dirección de "string\0", una constante ubicada en el segmento de código. Al ser un área de solo lectura, no puede modificar sus contenidos.

Cuestiones relacionadas