2012-08-02 12 views
12

En C, puede inicializar parcialmente una estructura o matriz, con el resultado de que los miembros/elementos que no se mencionan en el inicializador se inicializan en cero. (C99 sección 6.7.8.19). Por ejemplo: -¿Una cadena literal cuenta como inicializador parcial e inicialización cero?

int a[4] = {1, 2}; 
// a[0] == 1 
// a[1] == 2 
// a[2] == 0 
// a[3] == 0 

También puede inicializar "un array de tipo carácter" con una cadena literal (C99 sección 6.7.8.14), y "caracteres sucesivos ... inicializar los elementos de la matriz". Por ejemplo: -

char b[4] = "abc"; 
// b[0] == 'a' 
// b[1] == 'b' 
// b[2] == 'c' 
// b[3] == '\0' 

Todo bastante sencillo. Pero, ¿qué sucede si le das explícitamente la longitud de la matriz, pero usas un literal que es demasiado corto para llenar la matriz? ¿Los caracteres restantes tienen cero inicialización o tienen valores indefinidos?

char c[4] = "a"; 
// c[0] == 'a' 
// c[1] == '\0' 
// c[2] == ? 
// c[3] == ? 

tratándolo como un inicializador parcial tendría sentido, sería char c[4] = "a" se comportan exactamente igual que char c[4] = {'a'}, y tendría el útil efecto secundario de lo que le permite cero inicializar una matriz de caracteres toda forma concisa con char d[N] = "", pero no está del todo claro para mí que eso es lo que requiere la especificación.

+2

Woot. Encontré una pregunta sobre SO que tiene sentido. Dan, hiciste mi día. –

Respuesta

11
char c[4] = "a"; 

Todos los elementos restantes de la matriz se establecerán en 0. Es decir, no solo c[1] sino también c[2] y c[3].

Tenga en cuenta que esto no depende de la duración de almacenamiento de c, i. e., incluso si c tiene una duración de almacenamiento automática, los elementos restantes se establecerán en 0.

Desde el Estándar C (el énfasis es mío):

(C99, 6.7.8p21) "Si hay menos inicializadores en una lista corsé-cerrado que elementos o miembros de un agregado, o un menor número de caracteres de una cadena literal utilizado para inicializar una matriz de tamaño conocido que hay elementos de la matriz, el resto del agregado se inicializan implícitamente el mismo que los objetos que tienen una duración de almacenamiento estático. "

+0

Aha, allí. Esa es la aclaración que me faltaba. –

5

Desde el estándar C99 (como ya se dijo por ouah):

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

y:

Si un objeto que tiene una duración de almacenamiento automático no se inicia de forma explícita, su valor es indeterminado.Si un objeto que tiene una duración de almacenamiento estático es no inicializado de forma explícita, a continuación:

  • si tiene un tipo de puntero, se inicializa a un puntero nulo;
  • si tiene tipo aritmético, se inicializa a cero (positivo o sin signo);
  • si es un agregado, cada miembro se inicializa (recursivamente) de acuerdo con estas reglas;
  • si es una unión, el primer miembro nombrado se inicializa (recursivamente) según estas reglas .

Y char es un tipo aritmético, por lo que los elementos restantes de la matriz se inicializan a cero.

3

Absolutamente en todas partes en el lenguaje C, sigue el enfoque all-or-nothing para la inicialización. Si inicializa un agregado solo parcialmente, el resto de ese agregado se inicializa en cero.

Se puede decir que esto es excesivo y no es óptimo con las cadenas, pero así es como funciona en C.

Cuestiones relacionadas