HOWTO · C

Inicializar un array a 0 en C

Este tutorial presenta diferentes formas de inicializar un array a 0 en C

En esta página

Para inicializar a cero todos los elementos de un array de int al declararlo, usa int values[5] = {0};. C inicializa el primer elemento con 0 y también inicializa a cero todos los demás elementos del agregado. Si el array ya existe, asigna cada elemento dentro de un bucle. memset puede llenar de ceros los bytes de un array, pero llenar bytes no sustituye en general a la inicialización de valores tipados.

Inicializar un array a cero al declararlo

Usa un inicializador cuando conozcas el tamaño del array al declararlo. El siguiente ejemplo completo imprime los cinco valores inicializados.

#include <stdio.h>

int main(void) {
    int values[5] = {0};
    for (size_t i = 0; i < sizeof values / sizeof values[0]; ++i) {
        printf("%d%s", values[i], i == 4 ? "\n" : " ");
    }
    return 0;
}
0 0 0 0 0

El inicializador {0} asigna explícitamente cero al primer elemento; la inicialización del agregado asigna cero a los elementos omitidos. También puedes omitir el inicializador de un objeto con duración de almacenamiento estática o de hilo: C lo inicializa automáticamente a cero. Un array local ordinario sin inicializar tiene duración de almacenamiento automática, por lo que sus elementos no se establecen automáticamente en cero. Añade un inicializador o asigna los elementos antes de leerlos.

Inicializar un array a cero con un bucle

Un bucle resulta útil cuando el array ya está declarado o cuando los valores se eligen durante la ejecución. Este ejemplo completo usa la cantidad de elementos del array como límite del bucle e imprime el resultado.

#include <stdio.h>

int main(void) {
    int values[5];
    size_t count = sizeof values / sizeof values[0];

    for (size_t i = 0; i < count; ++i) {
        values[i] = 0;
    }
    for (size_t i = 0; i < count; ++i) {
        printf("%d%s", values[i], i + 1 == count ? "\n" : " ");
    }
    return 0;
}
0 0 0 0 0

La expresión sizeof funciona aquí porque values es un array dentro del mismo ámbito, no un parámetro de tipo puntero. Si pasas un array a una función, pasa también su longitud; dentro de esa función, el parámetro se ajusta a un puntero y sizeof devuelve el tamaño del puntero.

Usar memset() con cuidado

La función de la biblioteca estándar memset escribe el mismo valor de byte en una región de memoria. Incluye <string.h> y usa sizeof values para abarcar todo el array dentro del ámbito, como en este ejemplo completo.

#include <stdio.h>
#include <string.h>

int main(void) {
    int values[5];
    memset(values, 0, sizeof values);

    for (size_t i = 0; i < sizeof values / sizeof values[0]; ++i) {
        printf("%d%s", values[i], i == 4 ? "\n" : " ");
    }
    return 0;
}
0 0 0 0 0

El tercer argumento es una cantidad de bytes, así que sizeof values es correcto para este array. memset no asigna un valor tipado a cada elemento; escribe una representación con todos los bits en cero. Úsala solo cuando esa representación sea adecuada para el tipo de elemento y la plataforma. Para inicializar de forma portable un array semánticamente a cero al declararlo, prefiere {0}. No des por sentado que los bytes en cero representan un puntero nulo o un cero de punto flotante en todas las implementaciones de C.

Inicializar un array con valores distintos de cero

Incluye los valores que quieras en el inicializador, por ejemplo, int values[] = {2, 4, 6};. C deduce la dimensión externa a partir de la cantidad de inicializadores. En un array multidimensional, con esta forma solo se puede omitir la dimensión externa: int grid[][3] = {{1, 2, 3}, {4, 5, 6}};; hay que especificar la dimensión interna.

Los designadores de rango de GNU, como int values[5] = {[0 ... 4] = 7};, son una extensión de GCC y no forman parte de la sintaxis estándar portable de C. Si necesitas portabilidad entre compiladores de C, usa una lista de inicializadores ordinaria o un bucle. Un literal compuesto como (int[]){1, 2, 3} crea un array sin nombre con duración de bloque en este contexto de función; no es una asignación dinámica y no sustituye a una declaración de array con nombre para la inicialización general.