Home > Blockchain >  Why is char** argv same as char* argv[]
Why is char** argv same as char* argv[]

Time:07-14

So I have read that behind the scenes when passing an array in a function the compiler turns

int myArray(int arr[])

into

int myArray(int *arr)

Also an array most of the times decays to a pointer, for example

arr[0]

is the same as

(arr    0)

(Correct me if I am wrong)

But when it comes to char *argv it gets confusing, char *argv[] translates to an array of strings.

For example:

argv[2] = "Hello"
argv[3] = "World"

But how is **argv the same as *argv[] since **argv is a pointer to a pointer, how can **argv contain 10 different values since it is a pointer to a pointer? I think I have misunderstood something.

CodePudding user response:

Also an array most of the times decays to a pointer for example arr[0] is the same as (arr 0)

arr[0] is evaluated like *( arr 0 ) that is the same as *arr.

Function parameters having array types are adjusted by the compiler to pointers to the array element types.

On the other hand, an array used as an argument expression is implicitly converted to pointer to its first element.

So for example these function declarations

void f( char * s[100] );
void f( char * s[10] );
void f( char * s[] );

are equivalent and declare the same one function as

void f( char **s );

To make it clear just introduce a typedef name. For example

typedef char *T;

then you have

void f( T s[] );

So the function parameter is adjusted by the compiler to

void f( T *s );

Now change the typedef alias to its original type and you will get

void f( char * *s );

Pay attention to that the pointer s knows nothing how many elements the array has used as a function argument.

Thus for example the function main is declared like

int main( int argc, char *argv[] );

That is it has one more parameter argc that allows to determine the number of elements in the array of strings passed to the function. Though if to tell about main then in general the parameter argc is redundant because the array of strings always contains the sentinel value NULL. That is argv[argc] is equal to NULL.

But in general you have to pass also the number of elements in the array used as a function argument.

CodePudding user response:

"**" simply refers to a pointer to a pointer. Array itself works as an pointer. Therefore we can say that int **argv == *argv[] = argv[][0].

CodePudding user response:

But how is **argv the same as *argv[] since **argv is a pointer to a pointer

Because, quoting n1570 6.7.6.3p7 (emphasis mine):

A declaration of a parameter as "array of type" shall be adjusted to "qualified pointer to type", where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.

Each element of the argv array, has type char *, which is a pointer to a char.

So according to 6.7.6.3p7, an array of char * will be adjusted to a pointer to a char *; i.e. char *argv[] (an array of pointer to chars) will be adjusted to char **argv (pointer to a pointer to a char).

how can **argv contain 10 different values since it is a pointer to a pointer?

Because it doesn't. Just because it is a pointer to a pointer, doesn't make it different from any other pointer (Well, except that their size, representation, and alignment requirements may differ).

The diagram below will probably help you understand what is actually going on (I've considered char *s to be 8 bytes in the diagram):

argv (points to the beginning of the array of pointer to chars)
------------------ --------- --------- 
    \             |         |         |
     \ argv[0]    |argv[1]  |argv[2]  | argv[3]
      \           |         |         |
       \          |         |         |
        V  char * V  char * V char *  V char *
         --------- --------- --------- --------- 
        |  0xf00  |  0xf08  |  0xf10  |   NULL  |   (0xf08 and 0xf10 are the pointers to the strings passed as parameters to your program.)
         --------- --------- --------- --------- 
             |           |        |
             |           |        |
             |           |        |
             V           V        V
      "my_program"     "hello" "world"      ("hello" and "world" are the parameters passed to your program.)

CodePudding user response:

Array and Pointers in C Language hold a very strong relationship. Generally, pointers are the variables which contain the addresses of some other variables and with arrays a pointer stores the starting address of the array. Array name itself acts as a pointer to the first element of the array and also if a pointer variable stores the base address of an array then we can manipulate all the array elements using the pointer variable only.

Difference between pointer and array in C: https://www.geeksforgeeks.org/difference-pointer-array-c/

  • Related