2011-11-23 29 views
10

si escribo:Inicialización matriz de caracteres con la cadena más pequeña literal

char arr[8] = "abc"; 

¿Hay alguna especificación más de lo que podría ser arr[4]? Hice algunas pruebas con Clang y parece que los caracteres restantes en la matriz se establecen en nulo. Además, char arr[8] = ""; pone a cero cada byte. No estoy seguro si esto es un compilador conveniencia, comportamiento estándar, pura coincidencia o me equivoqué.


void a() 
{ 
    char arr[8] = "abc"; /* breakpoint here, line 3 */ 
    strcpy(arr, "1234567"); 
} 
int main() 
{ 
    a(); 
    a(); 
    return 0; 
} 

depurador transcripción:

 
Breakpoint 1, a() at str.c:3 
3   char arr[8] = "abc"; 
(gdb) s 
Current language: auto; currently minimal 
4   strcpy(arr, "1234567"); 
(gdb) p arr 
$1 = "abc\000\000\000\000" 
(gdb) c  
Continuing. 

Breakpoint 1, a() at str.c:3 
3   char arr[8] = "abc"; 
(gdb) p arr 
$2 = "1234567" 
(gdb) s 
4   strcpy(arr, "1234567"); 
(gdb) p arr 
$3 = "abc\000\000\000\000" 
+0

@Lundin - en realidad, arr [3] se establece en NULL de terminación, por lo que tiene razón para preguntar acerca de matriz [4] –

+0

@JamesCaccese parece ser un error tipográfico ... de todos modos, todo se explica en la respuesta que publiqué. – Lundin

+0

@Lundin - ¿Quién es Typo, Your's o @ sidyll's? Su comentario anterior que arr [4] se establece en terminación nula debido a que "" es falso. arr [3] se establece en terminación nula debido a "", arr [4] se pone a cero porque no se inicializó explícitamente. Su respuesta a continuación es correcta, pero su comentario está desactivado y confunde el problema. Como no puede editar comentarios, probablemente debería eliminarlos. –

Respuesta

16

Es un comportamiento estándar.

arr[3] se inicializa en 0 porque la terminación 0 es parte de la cadena literal.

Todos los elementos restantes se inicializan a 0 también - ISO/IEC 9899:1999, 6.7.8, 21:

Si hay menos inicializadores en una lista corsé-cerrado que elementos o miembros de un agregado, o menos caracteres en un literal de cadena usado para inicializar una matriz de tamaño conocido que hay elementos en la matriz, el resto del agregado debe ser inicializado implícitamente lo mismo que los objetos que tienen una duración de almacenamiento estática.

Y char objetos con almacenamiento estático se inicializan a 0.

+0

Gracias por la referencia estándar. – sidyll

+0

... pero eso solo se define para una lista incluida en corchetes, que no es lo que usa el código en cuestión, ¿no? – kusma

+1

No, "... o menos caracteres en una cadena literal ...". –

3

Este es el comportamiento estándar. Cada elemento de una matriz que no se inicializa explícitamente se inicializa a un valor predeterminado ('\0' para char), si cualquier prefijo de la matriz se inicializa en la declaración. También funciona para otros tipos:

int a[10] = {1}; 

ceros fuera a[1] través a[9].

0

Según la norma, todos los índices más allá de lo que se especifica será puesto a cero/null. Más información en this SO post

7
char arr[8] = "abc"; 

es completamente equivalente a

char arr[8] = {'a', 'b', 'c', '\0'}; 

ISO C 6.7.8 § 21 estados que

Si hay menos inicializadores en un corsé-cerrado list than there son elementos o miembros de un agregado, o menos caracteres en un literal de cadena usado para inicializar una matriz de tamaño conocido que allí son elementos en la matriz, el resto del agregado debe ser inicializado implícitamente lo mismo que los objetos que tienen almacenamiento estático duración.

En la llanura Inglés, esto significa que todos los valores al final de la matriz se ponen a 0. Así que las garantías estándar que su código es equivalente a:

char arr[8] = {'a', 'b', 'c', '\0', 0, 0, 0, 0}; 

Ahora, por supuesto, '\ 0 'pasa a ser el valor cero también.

Esta regla es universal para todas las matrices y no solo para las cadenas. Además, lo mismo se aplica al inicializar una estructura, pero solo establece explícitamente algunos de sus miembros (6.7.8 §18).


Esto es por lo que puede escribir código como

char arr[8] = ""; 

En este ejemplo, el primer elemento de la matriz se inicializa explícitamente a '\ 0', y el resto de los elementos de forma implícita a cero . El compilador traduce esto a

char arr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 
+0

¿Qué significa 'objetos que tienen una duración de almacenamiento estático'? No puedo entender esa parte de la especificación. ¿Puedes por favor explicarlo? –

Cuestiones relacionadas