Q: pointers to 4 dimensional array 
    int **z[DIM0] = {yr,ys};  

____210________218_______226________234________242________  
|         |         |          |          |           |  
|  218    | 226     |          |          |           |  
|_________|_________|__________|__________|___________|_____  
     yr       *yr      xa[0]      xa[1]        xa[2]  ........  
                       ** yr

Hello,
        I am trying to figure out logic of why type pointer to pointer int were used for array z  elements type?
What happens when yr is assigned a type pointer to pointer int when array z is initialized. yr is and array of pointers to int. yr decays to pointer of int.
before array z is initialized.
But after z initializes yr is a pointer to pointer. Its no longer a pointer of type int due to decay? yr has and address what would address be after its converted to pointer to pointer of int as array z element. Could someone show memory diagram for yr, *yr, **yr?   
after array z  initialization                                                                                    after yr declaration

____200______208_____216_______________256________________
|         |       |         |         |               |
|         |   256 |         |         |      yr[0]    |
|_________|_______|_________|_________|_______________|________
|    yr      *yr     **yr                                                                       
confused I understand when you assign a type pointer to pointer to a pointer value. I understand
how memory is mapped.  Confused because yr has and address before initialization.
How is **yr created?
The following I follow.
int x = 5;
int *p = &x;
int **q = &p


___________240__________248________256_______
|                    |            |          |
|       248          |       256  |    5     |
|___________________ |___________ |__________|
         q                p             x

const int DIM = 2, DIM1 = 3, DIM2 = 4;
int xa[DIM2], xb[DIM2], xc[DIM2], xd[DIM2], xe[DIM2], xf[DIM2];
int *yr[DIM1] = {xa, xb, xc}, *ys[DIM1] = {xd, xe, xf};
**z[DIMO] = {yr, ys};


A: If all the data were allocated as one giant block like this:
int z[DIM1][DIM2][DIM3];

It would allocate a single contiguous array and you could
reference into it directly:
val= z[1][2][3];

This is what your diagrams describe. This only works iff z[][][]
was allocated in one fell swoop.
But it wasn't, and your diagram does not reflect the code.
It was allocated as many smaller subsets (xa,xb,xc,xd,xe,xf) which are
scattered around in memory.  That is why yr[] and ys[] need to be
pointers to the beginning of each set.  yr[0] points to xa[0],
yr[1] points to xb[0].  yr[0] points to an int, so it is
declared as int *yr[].
And now yr and ys are also allocated independently. So z[] needs to
point to each of the sets of pointers to sets of integers. z[0]
points to yr[0] which points to xa[0] which is an int, so z is
declared as int **z[].
Your diagram would be correct if it had 24 boxes scattered around
on the page with lots of arrows.

A: First of all, TeasingDart has a good point: None of these examples constitute a 4-dimensional array. It's not a 3-dimensional array, either, despite having three levels of indirection. An array is a single allocation.
There's one obvious reason that might explain why z wasn't declared as int ***, similarly to your q, p and x examples: int ***z = {yr,ys}; produces an error, and the person who wrote this code knew no better than you. This would lead on to my main point here: Why would you choose to learn from such a resource?
If you want to declare a three-dimensional array for use in a particular function or block of code, declare it inside the function or block of code as TeasingDart did:
int z[DIM1][DIM2][DIM3];

Alternatively, if you expect to be returning the array and you want to use malloc, you could use something like the following in C:
typedef int_column[DIM2][DIM3];
int_column *foo = malloc(DIM1 * sizeof *foo);

... or of course std::vector in C++, which brings me to another point: It's probably not a good idea to tag C and C++, most of the time, when your question is really just a C question.
Notice how this is still only one allocation? That's an important aspect of arrays.
