简体   繁体   中英

The parameter argv in the function main(int argc, char *argv[])

Sorry if this seems like a basic question. I've been studying for a midterm I have coming up and I can't seem to wrap my head around this. I understand that argv can be used in the command line when you need to send it arguments, but none of the answers my professor gave us seems to make sense.

The parameter argv in the function main(int argc, char *argv[]) is:
A. An array of characters
B. A string
C. An array of pointers to character
D. A character pointer
E. None of the above

I feel like it is none of the above, but it could be because I don't fully understand the concept of argv . Any help would be appreciated!

The correct answer is E, none of the above. Although the parameter declaration looks like an array of pointer to char , the rules of C adjust it to pointer to pointer to char , and so do the rules of C++.

Either your instructor mistakenly intended choice C or your instructor designed a question inappropriately tricky for an introductory class, unless it is extra credit.

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* .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM