Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Notation of **argv in main function [duplicate]

Tags:

c

main

argv

argc

Possible Duplicate:
argc and argv in main

I'm having difficulty understanding the notation used for the general main function declaration, i.e. int main(int argc, char *argv[]). I understand that what is actually passed to the main function is a pointer to a pointer to char, but I find the notation difficult. For instance:

Why does **argv point to the first char and not the whole string? Likewise, why does *argv[0] point to the same thing as the previous example.

Why does *argv point to the whole first string, instead of the first char like the previous example?

This is a little unrelated, but why does *argv + 1 point a string 'minus the first char' instead of pointing to the next string in the array?

like image 773
hcaulfield57 Avatar asked Nov 13 '12 15:11

hcaulfield57


Video Answer


2 Answers

Consider a program with argc == 3.

   argv
     |
     v
+---------+         +----------------+
| argv[0] |-------->| program name\0 |
+---------+         +-------------+--+
| argv[1] |-------->| argument1\0 |
+---------+         +-------------+
| argv[2] |-------->| argument2\0 |
+---------+         +-------------+
|    0    |
+---------+

The variable argv points to the start of an array of pointers. argv[0] is the first pointer. It points at the program name (or, if the system cannot determine the program name, then the string for argv[0] will be an empty string; argv[0][0] == '\0'). argv[1] points to the first argument, argv[2] points to the second argument, and argv[3] == 0 (equivalently argv[argc] == 0).

The other detail you need to know, of course, is that array[i] == *(array + i) for any array.

You ask specifically:

  • Why does **argv point to the first char and not the whole string?

*argv is equivalent to *(argv + 0) and hence argv[0]. It is a char *. When you dereference a char *, you get the 'first' character in the string. And **argv is therefore equivalent to *(argv[0]) or *(argv[0] + 0) or argv[0][0].

(It can be legitimately argued that **argv is a character, not a pointer, so it doesn't 'point to the first char'. It is simply another name for the 'p' of "program name\0".)

  • Likewise, why does *argv[0] point to the same thing as the previous example.

As noted before, argv[0] is a pointer to the string; therefore *argv[0] must be the first character in the string.

  • Why does *argv point to the whole first string, instead of the first char like the previous example?

This is a question of convention. *argv points at the first character of the first string. If you interpret it as a pointer to a string, it points to 'the whole string', in the same way that char *pqr = "Hello world\n"; points at 'the whole string'. If you interpret it as a pointer to a single character, it points to the first character of the string. Think of it as like wave-particle duality, only here it is character-string duality.

  • Why does *argv + 1 point a string 'minus the first char' instead of pointing to the next string in the array?

*argv + 1 is (*argv) + 1. As already discussed, *argv points at the first character of the first string. If you add 1 to a pointer, it points at the next item; since *argv points at a character, *argv+1 points to the next character.

*(argv + 1) points to the (first character of the) next string.

like image 189
Jonathan Leffler Avatar answered Sep 27 '22 17:09

Jonathan Leffler


It all falls down to pointer arithmetic.

*argv[0] = *(*(argv + 0)) = **argv

Since [] has higher precedence than unary *.

On the other hand, *argv gives the first cell in the array, an array containing pointers. What does this pointer point to? Why a char array, a string, of course.

*argv + 1 gives what it gives because + has lower precedence than unary *, so first we get a pointer to a string, and than we add 1 to it, thus getting a pointer the the second character in the string.

like image 44
StoryTeller - Unslander Monica Avatar answered Sep 27 '22 18:09

StoryTeller - Unslander Monica