What is the type of command-line argument `argv` in C?

前端 未结 6 977
广开言路
广开言路 2020-12-28 17:45

I\'m reading a section from C Primer Plus about command-line argument argv and I\'m having difficulty understanding this sentence.

It says that,

相关标签:
6条回答
  • 2020-12-28 17:56

    Yes, exactly.

    argv is a char** or char*[], or simply an array of char* pointers.

    So argv[0] is a char* (a string) and argv[0][0] is a char.

    0 讨论(0)
  • 2020-12-28 17:57

    argv is of type char **. It is not an array. It is a pointer to pointer to char. Command line arguments are stored in the memory and the address of each of the memory location is stored in an array. This array is an array of pointers to char. argv points to first element of this array.

                      Some
                      array
    
                     +-------+        +------+------+-------------+------+
    argv ----------> |       |        |      |      |             |      |
                     | 0x100 +------> |      |      | . . . . . . |      |  Program Name1
             0x900   |       |        |      |      |             |      |
                     |       |        +------+------+-------------+------+
                     +-------+         0x100  0x101
                     |       |        +------+------+-------------+------+
                     | 0x205 |        |      |      |             |      |
             0x904   |       +------> |      |      | . . . . . . |      |  Arg1
                     |       |  .     |      |      |             |      |
                     +-------+        +------+------+-------------+------+
                     |  .    |  .      0x205  0x206
                     |  .    |
                     |  .    |  .
                     |  .    |
                     +-------+  .     +------+------+-------------+------+
                     |       |        |      |      |             |      |
                     | 0x501 +------> |      |      | . . . . . . |      |  Argargc-1
                     |       |        |      |      |             |      |
                     +-------+        +------+------+-------------+------+
                     |       |         0x501  0x502
                     | NULL  |
                     |       |
                     +-------+
    
    
    0xXXX Represents memory address
    
    

    1. In most of the cases argv[0] represents the program name but if program name is not available from the host environment then argv[0][0] represents null character.

    0 讨论(0)
  • 2020-12-28 17:59

    argv is an array of pointers to characters.

    The following code displays the value of argv, the contents of argv and performs a memory dump on the memory pointed at by the contents of argv. Hopefully this illuminates the meaning of the indirection.

    #include <stdio.h>
    #include <stdarg.h>
    
    print_memory(char * print_me)
    {
        char * p;
        for (p = print_me; *p != '\0'; ++p)
        {
            printf ("%p: %c\n", p, *p);
        }
    
        // Print the '\0' for good measure
        printf ("%p: %c\n", p, *p);
    
    }
    
    int main (int argc, char ** argv) {
        int i;
    
        // Print argv
        printf ("argv: %p\n", argv);
        printf ("\n");
    
        // Print the values of argv
        for (i = 0; i < argc; ++i)
        {
            printf ("argv[%d]: %p\n", i, argv[i]);
        }
        // Print the NULL for good measure
        printf ("argv[%d]: %p\n", i, argv[i]);
        printf ("\n");
    
        // Print the values of the memory pointed at by argv
        for (i = 0; i < argc; ++i)
        {
            print_memory(argv[i]);
        }
    
        return 0;
    }
    

    Sample Run:

    $ ./a.out Hello World!
    argv: ffbfefd4
    
    argv[0]: ffbff12c
    argv[1]: ffbff134
    argv[2]: ffbff13a
    argv[3]: 0
    
    ffbff12c: .
    ffbff12d: /
    ffbff12e: a
    ffbff12f: .
    ffbff130: o
    ffbff131: u
    ffbff132: t
    ffbff133:
    ffbff134: H
    ffbff135: e
    ffbff136: l
    ffbff137: l
    ffbff138: o
    ffbff139:
    ffbff13a: W
    ffbff13b: o
    ffbff13c: r
    ffbff13d: l
    ffbff13e: d
    ffbff13f: !
    ffbff140:
    
    $
    

    You have this big contiguous array ranging from ffbff12c to ffbff140 which contains the command line arguments (this is not guaranteed to be a contiguous by the standard, but is how it's generally done). argv just contains pointers into that array so you know where to look for the words.

    argv is a pointer... to pointers... to characters

    0 讨论(0)
  • 2020-12-28 17:59

    Yes.

    The type of argv is char**, i.e. a pointer to pointer to char. Basically, if you consider a char* to be a string, then argv is a pointer to an array of strings.

    0 讨论(0)
  • 2020-12-28 18:01

    This thread is such a train wreck. Here is the situation:

    • There is an array with argc+1 elements of type char *.
    • argv points to the first element of that array.
    • There are argc other arrays of type char and various lengths, containing null terminated strings representing the commandline arguments.
    • The elements of the array of pointers each point to the first character of one of the arrays of char; except for the last element of the array of pointers, which is a null pointer.

    Sometimes people write "pointer to array of X" to mean "pointer to the first element of an array of X". You have to use the contexts and types to work out whether or not they actually did mean that.

    0 讨论(0)
  • 2020-12-28 18:08

    Directly quoting from C11, chapter §5.1.2.2.1/p2, program startup, (emphasis mine)

    int main(int argc, char *argv[]) { /* ... */ }

    [...] If the value of argc is greater than zero, the array members argv[0] through argv[argc-1] inclusive shall contain pointers to strings, [...]

    and

    [...] and the strings pointed to by the argv array [...]

    So, basically, argv is a pointer to the first element of an array of strings note. This can be made clearer from the alternative form,

    int main(int argc, char **argv) { /* ... */ }

    You can rephrase that as pointer to the first element of an array of pointers to the first element of null-terminated char arrays, but I'd prefer to stick to strings .


    NOTE:

    To clarify the usage of "pointer to the first element of an array" in above answer, following §6.3.2.1/p3

    Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. [...]

    0 讨论(0)
提交回复
热议问题