Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use char** argv or char* argv[]?

People also ask

What is the difference between argv and argv?

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.

Is it safe to modify argv?

Once argv has been passed into the main method, you can treat it like any other C array - change it in place as you like, just be aware of what you're doing with it.

Is int argc char argv necessary?

If you want your program to understand a single integer command line argument, you still have to use argc and argv . Something like this ought to do it: int main(int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "Need a command line argument.

What is a argv []?

The second parameter, argv (argument vector), is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.


As you are just learning C, I recommend you to really try to understand the differences between arrays and pointers first instead of the common things.

In the area of parameters and arrays, there are a few confusing rules that should be clear before going on. First, what you declare in a parameter list is treated special. There are such situations where things don't make sense as a function parameter in C. These are

  • Functions as parameters
  • Arrays as parameters

Arrays as parameters

The second maybe is not immediately clear. But it becomes clear when you consider that the size of an array dimension is part of the type in C (and an array whose dimension size isn't given has an incomplete type). So, if you would create a function that takes an array by-value (receives a copy), then it could do so only for one size! In addition, arrays can become large, and C tries to be as fast as possible.

In C, for these reasons, array-values are not existent. If you want to get the value of an array, what you get instead is a pointer to the first element of that array. And herein actually already lies the solution. Instead of drawing an array parameter invalid up-front, a C compiler will transform the type of the respective parameter to be a pointer. Remember this, it's very important. The parameter won't be an array, but instead it will be a pointer to the respective element type.

Now, if you try to pass an array, what is passed instead is a pointer to the arrays' first element.

Excursion: Functions as parameters

For completion, and because I think this will help you better understand the matter, let's look what the state of affairs is when you try to have a function as a parameter. Indeed, first it won't make any sense. How can a parameter be a function? Huh, we want a variable at that place, of course! So what the compiler does when that happens is, again, to transform the function into a function pointer. Trying to pass a function will pass a pointer to that respective function instead. So, the following are the same (analogous to the array example):

void f(void g(void));
void f(void (*g)(void));

Note that parentheses around *g is needed. Otherwise, it would specify a function returning void*, instead of a pointer to a function returning void.

Back to arrays

Now, I said at the beginning that arrays can have an incomplete type - which happens if you don't give a size yet. Since we already figured that an array parameter is not existent but instead any array parameter is a pointer, the array's size doesn't matter. That means, the compiler will translate all of the following, and all are the same thing:

int main(int c, char **argv);
int main(int c, char *argv[]);
int main(int c, char *argv[1]);
int main(int c, char *argv[42]);

Of course, it doesn't make much sense to be able to put any size in it, and it's just thrown away. For that reason, C99 came up with a new meaning for those numbers, and allows other things to appear between the brackets:

// says: argv is a non-null pointer pointing to at least 5 char*'s
// allows CPU to pre-load some memory. 
int main(int c, char *argv[static 5]);

// says: argv is a constant pointer pointing to a char*
int main(int c, char *argv[const]);

// says the same as the previous one
int main(int c, char ** const argv);

The last two lines say that you won't be able to change "argv" within the function - it has become a const pointer. Only few C compilers support those C99 features though. But these features make it clear that the "array" isn't actually one. It's a pointer.

A word of warning

Note that all i said above is true only when you have got an array as a parameter of a function. If you work with local arrays, an array won't be a pointer. It will behave as a pointer, because as explained earlier an array will be converted to a pointer when its value is read. But it should not be confused with pointers.

One classic example is the following:

char c[10]; 
char **c = &c; // does not work.

typedef char array[10];
array *pc = &c; // *does* work.

// same without typedef. Parens needed, because [...] has 
// higher precedence than '*'. Analogous to the function example above.
char (*array)[10] = &c;

You could use either. They're completely equivalent. See litb's comments and his answer.

It really depends how you want to use it (and you could use either in any case):

// echo-with-pointer-arithmetic.c
#include <stdio.h>
int main(int argc, char **argv)
{
  while (--argc > 0)
  {
    printf("%s ", *++argv);
  }
  printf("\n");
  return 0;
}

// echo-without-pointer-arithmetic.c
#include <stdio.h>
int main(int argc, char *argv[])
{
  int i;
  for (i=1; i<argc; i++)
  {
    printf("%s ", argv[i]);
  }
  printf("\n");
  return 0;
}

As for which is more common - it doesn't matter. Any experienced C programmer reading your code will see both as interchangeable (under the right conditions). Just like an experienced English speaker reads "they're" and "they are" equally easily.

More important is that you learn to read them and recognize how similar they are. You'll be reading more code than you write, and you'll need to be equally comfortable with both.


It doesn't make a difference, but I use char *argv[] because it shows that is a fixed size array of variable length strings (which are usually char *).


You can use either of the two forms, as in C arrays and pointers are interchangeable in function parameter lists. See http://en.wikipedia.org/wiki/C_(programming_language)#Array-pointer_interchangeability.


It doesn't really make a difference, but the latter is more readable. What you are given is an array of char pointers, like the second version says. It can be implicitly converted to a double char pointer like in the first version however.


you should declare it as char *argv[], because of all the many equivalent ways of declaring it, that comes closest to its intuitive meaning: an array of strings.