In said:
Is this a style thing?
int main(int argc, char *argv[] ) or int main(int argc, char **argv )
Yes.
i.e. *argv[] or **argv
Why choose the latter?
1. Because it's the *actual* type of argv, *argv[] is merely syntactic
sugar.
2. Because it saves one keystroke.
To the newbie, *argv[] is more intuitive, because it actually reflects
the common usage of argv. That's why most C books use this notation.
Once the programmer realises that *argv[] is nothing more than syntactic
sugar for **argv (which is far from obvious to the newbie), the easier
to type form may become more attractive.
Note that this discussion is valid only for argv when used as function
parameter. In any other context, the two forms have different meanings:
char **foo; /* a pointer to a pointer to char */
char *bar[]; /* an array of pointers to char, of unspecified size */
foo has a complete type, i.e. its size is known by the compiler, and
therefore sizeof foo is OK anywhere after the declaration of foo.
bar has an incomplete type, its size is not known until another
declaration will specify the actual number of array elements:
fangorn:~/tmp 144> cat test.c
char *bar[];
int invalid(void) { return sizeof bar; }
char *bar[3];
int main(void) { return sizeof bar; }
fangorn:~/tmp 145> gcc test.c
test.c: In function `invalid':
test.c:3: sizeof applied to an incomplete type
While this is a contrived example, it is not uncommon to have declarations
of external arrays of unknown size:
extern *bar[];
bar is actually defined in another module and there is no way to tell its
number of elements at compile time. At run time, either the module
defining it will export its size to the rest of the program or a sentinel
value will be used to mark the end of the array (or both, for partially
initialised arrays).
Dan