char ** a[12][12][12]
;
Array 'a' is a 3-Dimensional array, where every element is a pointer to a char pointer(pointing to char). Type of 'a' is char ** (*)[12][12], whereas the type of every element of 'a', is char **. Array 'a' will be pointing to the first(among the 12) two-dimensional array.
What is the valid initialization of p?
If p is also pointing to the same as 'a'. Means p is also pointing to the first two-dimensional array of a. Then
char ** (*p)[12][12] = a;
Type of p will be char ** (*)[12][12].
Note: p is a pointer to a two-dimensional array.
If p is pointing to array 'a'. Means p is a pointer to a three-dimensional array.
char ** (*p)[12][12][12] = &a;
Type of p is char ** (*p)[12][12][12] as it is pointing to three-dimensional array 'a'.
If p is pointing to an element of array 'a'. The type of every element of array 'a' is char **. And we need a pointer to this. Therefore,
char ***p = (char ***)a;
Here we do type casting because the type of 'a' is char ** (*)[12][12]. By this action, p will point to the first element of array 'a'.
Here is the code.
#include<stdio.h>
int main() {
int a1[2] = {1, 2}; // Type of a1 is int *
//becuase a is pointing to first element whose type is int.
int *p1; // Type of p1 is int *.
p1 = a1; // As both type is int *. This conversion is compactible.
printf("%d\n", *p1); // This will print the first element of a.
int a2[2][3] = {{1, 2, 3}, {4, 5, 6}}; // Type of a2 is int (*)[3];
// a2 is pointing to one dimensional array consisting of 3 elements.
int (*p2)[3]; // p2 is a pointer to one dimenstional array consisting 3 elements.
// Type of p2 is int (*)[3].
p2 = a2; // As both type is int (*)[3]. This conversion is compactible.
//Printing the second element of array 2.
printf("%d\n", a2[0][1]);
printf("%d\n", (*(*p2) + 1));
// When we should use the run of * * * * to initialize p.
int a3 = 5;
int *p3 = &a3;
int **pp3 = &p3;
int ***ppp4 = &pp3;
printf("%d\n", a3);
printf("%d\n", *p3);
printf("%d\n", **pp3);
printf("%d\n", ***ppp4);
printf("===================\n");
/* ============ */
int ** array[12][12][12];
// Every element of array is pointer to int pointer(pointer pointing to an int).
// Type of array is int ** (*)[12][12]. It is three dimensional array.
array[0][0][0] = pp3;
// pp3 has type int ** and every element of array has also the same type int **.
printf("%d\n", **array[0][0][0]); // This will output 5.
//Now if we want a pointer to array named array.
int ** (*pointer)[12][12] = array;
printf("%d\n", **(*(*(*pointer)))); // This will also output 5.
//If you want a pointer to the element of array named array.
int ***parray = (int ***)array;
// Here we are doing the type casting because type of array is int ** (*)[12][12].
// We want a pointer to the first element of array.
// Type of every element of array is int **.
// And we want to pointer to that element That's why type of parray is int ***.
printf("%d", ***parray);
}