Difference between char *argv[] and char **argv for the second argument to main() [duplicate] Difference between char *argv[] and char **argv for the second argument to main() [duplicate] arrays arrays

Difference between char *argv[] and char **argv for the second argument to main() [duplicate]


It is fundamental to c that char** x and char* x[] are two ways of expressing the same thing. Both declare that the parameter receives a pointer to an array of pointers. Recall that you can always write:

 char *parray[100]; char **x; x = &parray[0];

and then use x identically.


Basically, char* argv[] means array of char pointers, whereas char** argv means pointer to a char pointer.

In any array, the name of the array is a pointer to first element of the array, that is, it contains the address of the first element.

So in the code given below, in char array x, x is a pointer to first element, '1', which is a character. So it's pointer to a character.

And in array arr, arr is pointer first element, x, which is itself a pointer to a character. So it a pointer to another pointer.

Hence, x is char*, and arr is char**.

While receiving something in a function, basic rule is that, you have to tell the type of the thing you are receiving. So either you simply say that you want to receive a char**, or you can also say char* arr[].

In first case, we don't need to think anything complex. We simply know, we are receiving an array of char*. Don't we know this? So, we receive it, and use it.

In second case, it is simple, as i have explained above that arr is a char**, you can put this as it's type and receive it safely. Now the system knows the type of the stuff we have received, we can access next elements by simply using array annotation. It's like, we have received the starting address of the array, we can surely go to the next elements, and as we know it's type, we know what it contains and how we can use that further. We know it contains pointer to char, so we can legally access them as well.

void func1(char* arr[]){    //function body}void func2(char** arr){    //function body}int main(){    //x, y and z are pointer to char    char x[3]={'1', '2', '3'};    char y[3]={'4', '5', '6'};    char z[3]={'7', '8', '9'};    //arr is pointer to char pointer    char* arr[3]={x, y, z};    func1(arr);    func2(arr);}


They're exactly the same. §5.1.2.2.2 of the C11 standard states:

The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:

int main(void) { /* ... */ }

or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):

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

or equivalent;10) or in some other implementation-defined manner.

10) Thus, int can be replaced by a typedef name defined as int, or the type of argv can be written as char ** argv, and so on.

Clearly the intent is for both declarations to be identical. On top of that, the rule is described in §6.7.6.3/7:

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