2

When we are taking arguments from the command line, like this:

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

It is my understanding that argv is a pointer to an array of pointers, which hold the address of the arguments passed in.

Since this is the case, why is it that we can access the commnand line arguments by using

argv[i]

without dereferencing it, as it contains pointer?

  • 1
    `argv` is a pointer to a pointer, not to an array of pointers. It just so happens that what it points to is the first in an array. – StoryTeller - Unslander Monica Mar 21 '17 at 10:26
  • 2
    Following [the clockwise/spiral rule](http://c-faq.com/decl/spiral.anderson.html) the declaration `char *argv[]` will tell you that `argv` is an array of pointers to `char`. I.e. an array of strings. Technically it's not really correct, since you can't pass arrays as arguments, but for all practical reasons that's how you should see `argv`: As an array of strings. – Some programmer dude Mar 21 '17 at 10:29
  • moreover you should check `argc` before access `argv` elements. This grants to avoid accessing that array out of bounds – LPs Mar 21 '17 at 10:30
  • 1
    `argv` is (a pointer to the first element of) an array of pointers, not a pointer to an array. – Kerrek SB Mar 21 '17 at 10:36
  • "why is it that we can access the commnand line arguments by using argv[i]" Depends on how you use it. If you want to use it as a string, you don't have to de-reference it. If you want to use individual characters, you have to de-reference it. – Lundin Mar 21 '17 at 10:55
  • @StoryTeller To be picky, `argv` is indeed an array of pointers. But since it is a function parameter, it gets implicitly adjusted by the compiler to a pointer to the first item of that array. Which makes it a pointer-to-pointer. – Lundin Mar 21 '17 at 10:57
  • @Lundin - [Indeed, and I believe we've had this discussion before :)](http://stackoverflow.com/questions/42065293/differences-when-using-in-c/42065425#42065425) – StoryTeller - Unslander Monica Mar 21 '17 at 11:50

2 Answers2

2

You are forgetting that a string (char *) is accessed via it's starting address, not an absolute value... What value would you store for a string? How much memory should the generic 'string' type use, and thus how long can a 'string' be?

A string in C consists of a number of printable characters, terminated by a nul (\0). These are stored in memory.

The char *argv[] parameter is specifying that there is an array of char * elements. As we've established above, a char * is a string (or an array of char elements).

The char *argv[] parameter can just as legally be declared char **argv.

For example, you can print the absolute values of each character of a string, along with their address in memory:

#include <stdio.h>

int main(void) {
    char *my_string = "Hello World";
    int i;

    for (i = 0; my_string[i] != '\0'; i++) {
        printf("%c - 0x%02hhX - %p\n", my_string[i], my_string[i], &(my_string[i]));
    }

    return 0;
}

Here, we are dereferencing the pointer to get a single character by using my_string[i].

Output:

H - 0x48 - 0x400614
e - 0x65 - 0x400615
l - 0x6C - 0x400616
l - 0x6C - 0x400617
o - 0x6F - 0x400618
  - 0x20 - 0x400619
W - 0x57 - 0x40061a
o - 0x6F - 0x40061b
r - 0x72 - 0x40061c
l - 0x6C - 0x40061d
d - 0x64 - 0x40061e

You could equally implement this program like so (note the dereferences):

#include <stdio.h>

int main(void) {
    char *my_string = "Hello World";
    char *s;

    /* s = my_string
     * is equivelant to:
     * s = &(my_string[0]) */

    for (s = my_string; *s != '\0'; s++) {
        printf("%c - 0x%02hhX - %p\n", *s, *s, s);
    }

    return 0;
}
Attie
  • 6,690
  • 2
  • 24
  • 34
  • You should be using `int main(void)`, not `void main(void)` as the former is the standard signature of `main` according to the C11 standard. – Spikatrix Mar 21 '17 at 12:28
1

In the main function: int argc is the number of strings pointed to by char *argv[] Array

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

int argc :

int argc define how many string passed in the main function.

char *argv[] :

char *argv[] store every word/argument in this array.

Example :

#include <stdio.h>
int main(int argc, char const *argv[]){
  for(int i=0; i<argc; i++){
    printf("%s\n", argv[i]);
  }
  return 0;
}

Compile :

gcc -o c example.c

Run :

./c one two there four five

Output :

./c
one
two
there
four
five
Sumon Sarker
  • 2,707
  • 1
  • 23
  • 36