Well it expects an array of pointers, what more is there to understand?

They're not the same thing.
Code:
An array of arrays
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|H|E|L|L|O| |W|O|R|L|D| | | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|T|H|I|S| |W|O|R|K|S| | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|W|O|O|!| | | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

An array of pointers
+----+    +-+-+-+-+-+-+-+-+-+-+-+-+
|    |--->|H|E|L|L|O| |W|O|R|L|D| |
+----+    +-+-+-+-+-+-+-+-+-+-+-+-+
|    |--->|T|H|I|S| |W|O|R|K|S| |
+----+    +-+-+-+-+-+-+-+-+-+-+-+
|    |--->|W|O|O|!| |
+----+    +-+-+-+-+-+
If you pass an array of arrays to something expecting an array of pointers, it's just going to take the first 4 characters of your string (say), and try and use that as a pointer to some other string. Then you immediately get something like unable to reference memory "0x41424344" where all the bytes of the "address" look remarkably like printable characters (in this case, ABCD).

Just because you can do
printf("%s", a[i] );
does NOT make them the same thing, because the compiler will generate slightly different code depending on how you declared the array to begin with.