I think your professor wants C, even though the pedanticly correct answer is E. The data referred to by argv
is an array, but the variable itself is a pointer. I think it's worth exploring why, because it has nothing to do with the type of array or main
.
Consider an array of integers,
int a[] = { 1, 2, 3 };
This allocates 3 adjacent integers. The size of the array is sizeof(int) * 3
.
Now let's write a function to double the values of each member,
void F( int m[], size_t n ) {
for( int i=0; i < n; i++ ) {
m[i] *= 2;
}
int main( int argc, char *argv[] ) {
F(a, sizeof(a)/sizeof(a[0]));
return EXIT_SUCCESS;
}
What is m
? It's declared to be an array, but it's really a pointer: sizeof(m) == sizeof(int*)
. That's because C doesn't pass arrays as function arguments. The term of art in C is that an array argument decays to a pointer.
It sorta kinda doesn't matter, because C syntax hides a host of sins, er, differences. You can use the subscript notation with both arrays and pointers. For that reason, our function F
can treat m
almost like an array, except that it requires the length, because it can't derive the length from the size, because the size is the size of the pointer.
Let me say that a different way. When F
is called, the "arguments on the stack" are not the values of a
, namely 1
, 2
, and 3
. There is just one such argument, a pointer to the first element of a
(often thought of as the address of the first element). You can use that pointer as an array partly because the name of an array also refers to the address of the first element.
Now let's back up to your friend argv
. Array, or pointer? Let's say your program foo is invoked on the command line:
$ foo sam I am
What does the operating system do? Somehow, it has to pass those 4 strings (character arrays) to your program. Somewhere, it has to allocate contiguous space for them. Conceptually, the shell might do something like:
char **args = calloc(5, sizeof(char*));
args[0] = "foo";
args[1] = "sam";
args[2] = "I";
args[3] = "am";
or,
char args[5] = { "foo", "sam", "I", "am" };
Either way, it could pass args
to execv(3), invoking your main
, and passing you a ... pointer. After all, it can't pass you an array, right?
Please note args
must be an array. If it weren't argv[1]
would be meaningless.
(Why 5 elements, you ask, when there are only 4 arguments? There's a rule -- C or Posix, i don't remember -- that the last element in the array (!) must be a NULL pointer.)
Array or pointer? Wave or particle? Where you stand depends on where you sit. argv
is pointer a to char*
, certainly. By definition, though, it's a pointer to the start of an array of char*
.