Is it the same thing? Technically, not. An array is NOT a pointer. An array is implemented internally as a pointer, but an array is NOT equivalent to a pointer. (If you don't believe me take the sizeof an array and of a pointer to the same data type as that array.
With that being said, you do indeed have the correct idea.
char *ary[] as you put it, is indeed the way to declare an array of strings. The key difference here is that you will need to give this array a size at compile time. char** can be made to act as an array using dynamic memory allocation (malloc, calloc etc.) BUT it is also has another purpose. It is indeed a pointer to a pointer which means that if it appears in a function prototype it has a dual meaning. The function may accept a two-d ary, OR a pointer by reference. The same way you pass an integer by reference.
If you pass a char** into a function then if that char pointer points to a valid character pointer which then in turn points to a character than yes that is true, however, you will need to note the difference conceptually between a 2-D array and a table of values. You should think of a 2-D array as a serpate row of pointers to arrays
const char ary[10][10];
ary[0] = "Hello" assigns the entire string to this array
ary[0] --------> ary[][0] which is H. Note that this is not the correct syntax, but for idea's sake consider the first number the value of the first pointer I.E. to which array it points. Then after being dereferenced, you are working with a char* so you can think of it as an array of char at that point.
You final last question. Funtion prototypes do not distinugish between char* ar[] and char**. They can be treated differently by the programmer within the funcition, but as far is it is concerned it is receiving a pointer to a character pointer. How you increment, dereference it is up to you.