You need to specify all the dimensions except the highest. The reason is that the compiler is going to allocate one big block of memory, as opposed to one array of pointers pointing to their own little arrays. In other words,

int array[][3][4] = ...;

will allocate one contiguous region of memory of size 3*4*(however many 3x4 arrays you declare here). Thus when later on in your code, you write

array[1][2][3] = 69;

in order to find where in memory to write 69, it starts at address (array), then jumps forward 12*sizeof(int) to get to array[1], plus 2*4*sizeof(int) to get to array[1][2], plus 3*sizeof(int) to finally get to the start of array[1][2][3]. Compare this to writing, for example,

(sorry if my syntax isn't exact...been awhile since I've had to code something like this in C). In this example, array points to a block of code n*sizeof(int**) bytes long. Each element of this array points to another array of size 3*sizeof(int*) bytes long. Each element of these arrays points to another array of size 4*sizeof(int) bytes long. In this case, instead of calculating that array[1][2][3] is at address (array + something), it would need to follow a few different pointers in memory before finding where to write 69.