An array is an object in memory.  It has an address and a size.  It's also true that in certain contexts, an array decays into a pointer to its first element.  So numerically, if both a and &a are compared as pointer values, they compare as equal, since they both point to the same address in memory.  But they have different data types: a has type int[4] ("array 4 of int"), or int* ("pointer to int") in  certain contexts, whereas &a always has type int (*)[4] ("pointer to array 4 of int").
 &a points here
 |
 V
+------+------+------+------+
| a[0] | a[1] | a[2] | a[3] |  sizeof(a) == 16
+------+------+------+------+
 ^
 |
 &a[0] also points here
 In certain contexts, 'a' means &a[0]
Hence, (void *)a == (void *)&a.
Also note that because a and &a point to different data types (and in particular, the pointed-to types have different sizes), doing pointer arithmetic will yield different results.  a+1 will point to &a[1] (advances by one int value), whereas &a+1 will point to just past the end of the array at &a[4], since it advances by one "array 4 of int" unit:
                       &a+1 points here
                             |
                             V
+------+------+------+------+
| a[0] | a[1] | a[2] | a[3] |
+------+------+------+------+
        ^
        |
  a+1 points here