The existing answers, although correct, do not give an absolutely clear idea that there is a fundamental reason (other than language rules) why you cannot use char [10][10] for char ** . Even if you force the actors to say something like
char arr[2][2]; char ** ptr = (char **)arr;
he will not work.
The reason is that in C and C ++ a two-dimensional array is laid out in memory as an array of arrays. That is, in C a two-dimensional array is laid out in memory as one selection,
arr -> arr[0][0] arr[0][1] arr[1][0] arr[1][1]
You will notice that arr does not point to char * , but to arr[0][0] , which is char ; therefore, while arr can be added to char * , it cannot be attributed to char ** .
The correct forced tide will be
char arr[2][2]; char * ptr = (char *)arr;
If you do not want to force the cast (always a good idea, if possible!), You would say
char arr[2][2]; char * ptr = arr[0];
or, to make the result clearer,
char arr[2][2]; char * ptr = &arr[0][0];
And now you have (in fact) a pointer to an array of 4 characters. [Proviso: I cannot find anything in the C standard that prohibits implementations from adding an additive between two lines of an array, but I don’t think that a real-world implementation does this, and the usual coding practice depends on the assumption that there will not be such an addition. ]
If you really needed to convert arr to char ** , you would need to explicitly create an array of pointers:
char arr[2][2] char * arr_ptrs[2]; char ** ptr; arr_ptrs[0] = arr[0]; arr_ptrs[1] = arr[1]; ptr = arr_ptrs;
C could, in principle, do this automatically for you if you tried to apply a two-dimensional array to a pointer to a pointer, but this would violate the programmer’s expectation that the actor has no side effects, such as memory allocation.
In Java, by comparison, a two-dimensional array is always an array of pointers to arrays, so an array
char arr[][] = { {'a', 'b'}, {'c', 'd'} };
laid out in memory as three separate selections, in random order and not necessarily contiguous,
arr -> arr[0] arr[1] arr[0] -> arr[0][0] arr[0][1] arr[1] -> arr[1][0] arr[1][1]
You will immediately notice that this requires more memory than the equivalent C array, and it is slower to evaluate at runtime. On the other hand, this allows the rows of the array to have different lengths.