int (*arr4[8])
Here everything except the datatype name is enclosed with parentheses. How is it different from the firts three options?
The only times parentheses matter is when they change the default precedence of operators. Postfix []
and ()
have higher precedence than unary *
in both declarators and expressions, so *arr4[8]
is parsed as *(arr4[8])
. (*arr4[8])
doesn't affect the precedence of either *
or []
, so it's identical to writing *(arr4[8])
and *arr4[8]
. However, with (*arr3)[8]
, they do change that precedence, explicitly grouping the *
operator with arr
.
I tried to enclose it like (int *arr4[8])
as well, but seems like this is not valid in C.
It is not - the syntax doesn't allow it.
int (*arr5[8])[8]
Not sure, but I presume this is something like an array of pointers to an array of integers.
Precisely speaking, arr5
is an 8-element array of pointers to 8-element arrays of int
. Graphically, it would look something like this:
+---+ +---+---+---+---+---+---+---+---+
arr5: | | arr5[0] ----------> | | | | | | | | |
+---+ +---+---+---+---+---+---+---+---+
| | arr5[1] --------+
+---+ | +---+---+---+---+---+---+---+---+
| | arr5[2] ------+ +-> | | | | | | | | |
+---+ | +---+---+---+---+---+---+---+---+
... |
| +---+---+---+---+---+---+---+---+
+---> | | | | | | | | |
+---+---+---+---+---+---+---+---+
You would index each element as (*arr5[i])[j]
- you don't want to index into each arr5[i]
, you want to index into what each arr5[i]
points to. The declarator tells you this up front - you don't have to puzzle it out on your own. The structure of the declarator mirrors the structure of the expression.
Note that this declaration doesn't create the 8-element arrays of int
- it only creates an 8-element array of pointers. You would either need to dynamically allocate the memory for each arr5[i]
to point to, like:
for ( size_t i = 0; i < 8; i++ )
arr5[i] = malloc( sizeof *arr5[i] ); // sizeof *arr5[i] == sizeof (int [8])
or have a bunch of arrays already declared:
int foo[8];
int bar[8];
int bletch[8];
...
int (*arr5[8])[8] = { &foo, &bar, &bletch, ... };