The C standard (citing the latest C11 draft N1570 here) explains this quite well.
§6.7.9 Initialization, p21:
If there are fewer initializers in a brace-enclosed list than there are elements or members
of an aggregate, or fewer characters in a string literal used to initialize an array of known
size than there are elements in the array, the remainder of the aggregate shall be
initialized implicitly the same as objects that have static storage duration.
(emphasis mine)
so, every element except a[0]
in your code is initialized implicitly. Now let's look what that means:
§6.7.9 Initialization, p10:
If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate. If an object that has static or thread storage duration is not initialized
explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules,
and any padding is initialized to zero bits;
— if it is a union, the first named member is initialized (recursively) according to these
rules, and any padding is initialized to zero bits;
(again, emphasis mine)
so, a[1]
to a[4]
are initialized to 0
-- type int
is an arithmetic type.