1) Arrays are really pointers, so the index tells you the offset. The first element is located at the base-address itself, and thus has an offset of 0 (zero) -- which in array-notation is adress[0]. The name of an array (without the index) is the *address* of -- i.e. the *pointer* to -- the first element (array[0]). So arrays and pointers are interchangable.
array = &(array[0])
array[0] = *(array) = *(array+0) Offset of zero
array[1] = *(array+1) Offset of 1
array[2] = *(array+2) Offset of 2
array[3] = *(array+3) Offset of 3
2) I think you got that wrong... It's "char *argv[]" , or if you like (as arrays and pointers are the same thing) "char **argv"... not "char *argv".
Strings in C and C++ are really NULL-terminated char-arrays, so "char *" (char-pointer) tells you that this is an array of chars... and as it's used NULL-terminated, it is a string. (Again pointers and arrays are the same).
The reason for the array -- the "[]" at the end or the extra "*" -- is that you have an array of strings... in other words, an array of NULL-terminated char-arrays.
You have an array containing pointers... these pointers, each points to a string -- a NULL-terminated char-array/char-pointer. That means the whole thing will be a "table of char-pointers", "a table of char tables" or "a pointer to char-pointers".
Each of the pointers point to a string containing one argumet -- with the first element (argv[0]) pointing to the program-name itself. argv[1] points to a string with the 1st argument, argv[2] points to a string with the 2nd argument.
As your after particular arguments, it's better to do it this way, than having one big string containing the whole command-line.
3) No idea, sorry...