So, if you do:
int i; double arr[4][3][3] = {{1,1,1,1,1,1,1,1,1},{2,2,2,2,2,2,2,2,2}, {3,3,3,3,3,3,3,3,3},{4,4,4,4,4,4,4,4,4}}; double (*pp3)[3][3]; pp3 = arr; for (i = 0; i <= 3; i++) { printf("pp3 + %d is %f \n", i, ***(pp3 + i)); }
Then you will get the desired behavior. The problem with your code is that, as the compiler tells you, you are trying to assign a pointer to an array of 9 double ( double (*pp1)[sizeof(arr[0] / sizeof(arr[0][0][0])] evaluates to double (*pp1)[9] ), but you need a pointer to an array of 3 from array 3, which was declared using double arr[4][3][3] . From my tests, gcc will accept double (*pp1)[9] with a warning to the compiler, which I tried to get in my comment below. I hope this clears up.
If you want to keep this general, then you really need double (*pp3)[sizeof(arr[0]) / sizeof(arr[0][0])][sizeof(arr[0][0]) / sizeof(arr[0][0][0])] , which is a bloody nightmare.
EDIT: Forgot to dereference ... Had to copy / paste haha. An explanation of the behavior of the question code has also been added. Corrected in accordance with the comments.