Check the types!!
Given the definition as int a[4][4];
- ais of type- int [4][4]- array of an array of 4 integers. It's not the same as- int **.
- a[n]is of type- int [4]- array of 4 integers. It's not the same as- int *
- a[n][m]is of type- int. - integer.
Now, given the fact, that the address of the array is also the address of the first element in the array, the values are same, but they differ in types.
To check it visually
int a[4][4]
      +-------+--------+-------+-----------+
      |       |        |       |           |
      |a[0][0]| a[0][1]| a[0][2]   a[0][3] |
      |       |        |       |           |
      +------------------------------------+
      |       |        |       |           |
      |a[1][0]|        |       |           |
      |       |        |       |           |
      +------------------------------------+
      |       |        |       |           |
      |a[2][0]|        |       |           |
      |       |        |       |           |
      +------------------------------------+
      |       |        |       |           |
      |       |        |       |           |
      |       |        |       |           |
      |       |        |       |           |
      +-------+--------+-------+-----------+
Then, quoting the C11, §6.3.2.1
Except when it is the operand of the sizeof operator, the _Alignof operator, or the
  unary & operator, or is a string literal used to initialize an array, an expression that has
  type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points
  to the initial element of the array object and is not an lvalue. [...]
So, while passing an argument of type array as a function argument, it decays to the pointer to the first element of the array.
So, let's have a look.
- a, decays to- &(a[0])- the address of the first element of type- int (*)[4].
- *a, which is the same as- a[0], decays to an- int *, pointer to the first element.
- **awhich is same as- *(*a)==- *(a[0])==- a[0][0]- that's the- intvalue at that index.
Now once again look carefully at the image above - do you see that the first element of int [0] and int [0][0] are basically residing at the same address? In other words, the starting address are the same.
That's the reason behind the output you see.