The difference between char * argv [] and char ** argv for the second argument to main ()

CODE 1

#include<stdio.h> int main(int argc, char *argv[]) { int j; printf("%d", argv[1][0]); return 0; } 

CODE 2

 #include<stdio.h> int main(int argc, char **argv) { int j; printf("%d", argv[1][0]); return 0; } 

CODE 1 and CODE 2 both give the same output. but argument 2 of the main function in CODE 1 and CODE 2 is different. An array of pointers is created over the data section at compile time. argv is an array of pointers. Then we must declare the argument in the main function as a pointer to a pointer to a symbol, i.e. ** argv. How to declare correctly, as in CODE 1?

+7
c arrays parameter-passing pointers argv
source share
4 answers

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

+8
source share

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

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

So, in the code below, in a char array, x, x is a pointer to the first element, '1', which is a character. Therefore, he points to a symbol.

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

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

When you receive something in a function, the basic rule is that you must specify the type of thing you receive. So either you just say you want to get char **, or you can also say char * arr [].

In the first case, we do not need to think about anything complicated. We just know that we get a char * array. Don't we know that? So we get it and use it.

In the second case, it is simple, as I explained above, that arr is char **, you can put this as its type and get it safely. Now the system knows the type of material that we received, we can access the following elements simply by using the annotation of the array. For example, we got the starting address of the array, we can, of course, move on to the next elements, and, as we know, this is a type, we know what it contains, and how we can use it in the future. We know that it contains a pointer to char, so we can legitimately access them.

 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); } 
+8
source share

They are exactly the same. ยง5.1.2.2.2 of standard C11:

The function called when the program starts is called main . the implementation does not declare a prototype for this function. It must be defined with an int return type and no parameters:

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

or with two parameters (called argc and argv , although any names can be used since they are local to the function in which they are declared):

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

or equivalent; 10) or in some other implementations in a way.

10) Thus, int can be replaced with a typedef name defined as int , or type argv can be written as char ** argv , etc.

Obviously, the intention is for both declarations to be the same. In addition, the rule is described in ยง6.7.6.3 / 7:

Declaring a parameter as a type array must be adjusted to a qualified type pointer, where type qualifiers (if any) are those that are specified in [ and ] for outputting the array type ....

+5
source share

Declaring an array like this

 char array[] 

makes it const, which means you CANNOT have the following code

 char array[] = "hello"; array = "hey"; 

although the second line is smaller and should match your error

error: array type 'char [6]' is not assigned

if you have **argv you can write

 main(int argc, char **argv) { char **other_array; /* * do stuff with other_array */ argv = other_array; } 

if you have *argv[] then

 main(int argc, char *argv[]) { char **other_array; /* * do stuff with other_array */ argv = other_array; } 

gives you this warning

warning: assigning 'const char **' from 'char **' discards qualifiers in nested pointer types

so technically this is a little optimization, as if you wrote const

+2
source share

All Articles