what will be the dimension of integer array arr if declared like this :
int arr[][2]={1,2,3};
what is the use of not declaring the highest dimension ?
what will be the dimension of integer array arr if declared like this :
int arr[][2]={1,2,3};
what is the use of not declaring the highest dimension ?
Somewhat to my surprise, your declaration:
int arr[][2]={1,2,3};
appears to be legal. You can legally omit inner braces in initializers. For example, if you wanted to define the bounds of arr
explicitly and initialize all its elements, you could write either:
int arr[2][2] = { { 1, 2}, { 3, 4 } };
or, equivalently:
int arr[2][2] = { 1, 2, 3, 4 };
You can also omit trailing elements, and they'll be implicitly set to zero. For a one-dimensional array, this is straightforward; this:
int arr[4] = { 1, 2, 3 };
is equivalent to:
int arr[4] = { 1, 2, 3, 0 };
And if you omit a dimension, it can be inferred from the initializer:
int arr[] = { 1, 2, 3, 4 }; // 4 elements
Since you're defining arr
as an array of 2-element arrays of int
, this:
int arr[][2]={1,2,3};
is equivalent to this:
int arr[][2] = { { 1, 2 }, { 3 } };
You have two elements in the initializer (each of which initializes a 2-element array), so that's equivalent to:
int arr[2][2] = { { 1, 2 }, { 3 } };
Finally, you've omitted the last initializer sub-element, so it's implicitly zero:
int arr[2][2] = { { 1, 2 }, { 3, 0 } };
In general, omitting dimensions and trailing initializers is useful because it lets the compiler figure out certain things. If I write:
char message[] = "hello, world";
I don't have to count the characters in the string (and add 1 for the terminating '\0'
). Computers are really good at counting things; making a human do that job would be silly.
Similarly, omitting some initializers lets you provide only the information you need. With C99's addition of designated initializers, you can even initialize a specified member of a structure and let the compiler take care of everything else:
struct foo obj = { .something = 42 };
As for flattening initializers by omitting inner curly braces, I personally don't see much use for that except for the special case of using a { 0 }
initializer to initialize and entire array or structure to zero. In particular, for multidimensional arrays I find it much clearer to show the entire structure of the array.
Per the minimal bracketing rule (6.7.9p20 in C11),
enough initializers from the list are taken to account for the elements or members of the subaggregate or the first member of the contained union; any remaining initializers are left to initialize the next element or member of the aggregate of which the current subaggregate or contained union is a part.
So the following declarations are equivalent:
int arr[][2]={1,2,3};
int arr[][2]={{1,2},{3}};
int arr[2][2]={{1,2},{3}};
As to why this is useful: when initializing a large multi-dimensional array, it may well be obvious to the reader how many items there are per subaggregate; in which case, there is no need to supply the brackets between subaggregates.