0

My teacher gave me a correction of an exercise and it contains code using double pointers. Since I am fairly new to C I have difficulty comprehending what the code does. I know the basics of a single pointer ,but somehow I lose my way on the double pointer route.

The code:

#include <stdio.h>

main(int argc, char** argv){
    printf("\nHello ");
    char** runner = argv;
    ++runner;
    while(*(runner+2) != 0){
        **runner = toupper(**runner);     
        printf("%s, ",*runner);         
        ++runner;
    }

    **runner = toupper(**runner);   
    printf("%s ",*runner);    
    ++runner;
    **runner = toupper(**runner);   
    printf("and %s!",*runner);   
}

-The first issue I have is understanding why the main function uses a double pointer? -The second issue ,after initializing the double pointer ,runner, it is being told to point to one place further. But how on earth can you know where it points to ,if it points to a pointer which in its own turn points to a place you have no idea of?

  • Since I have problems understanding these first two things I can't continue and don't know how the code further works.

Thank you for your time

BURNS
  • 711
  • 1
  • 9
  • 20
  • 1
    Oh boy how writes such a code? I think I understand it but it's quiet hard. – rekire Nov 03 '13 at 11:24
  • This is really easy: the `argv` is a pointer to an array of pointers, each pointing to the first character of an commandline argument. – musicmatze Nov 03 '13 at 11:25
  • And runner is incremented to skip the first char* string, which is typically a path to the program itself (although it can be arbitrary, can of worms) – John Smith Nov 03 '13 at 11:31
  • As number of `**`'s increases - meaning pointer to pointer's, program complexity increases and becomes difficult to understand it. – Sunil Bojanapally Nov 03 '13 at 12:03

4 Answers4

3

Let's try to explain it:

main(int argc, char** argv){

Normal main function just there is the returntype missing that may cause problems. (c90 vs c99 AFIK). The first parameter is the count of parameters which is >1 (because the first parameter is the binary name (helpful for multi call applications like busybox)). The second parameter are the parameter as a string aka char-array, which comes for the shell which called this binary.

printf("\nHello ");
char** runner = argv;
++runner;

printing out hello with skipping the first argument of that binary (which is the binary name)

while(*(runner+2) != 0){

Checking if the third byte of the current parameter is the null byte. IMHO this can cause problems if there is no second parameter.

    **runner = toupper(**runner);

Converting it to uppercase.

    printf("%s, ",*runner);

Printing out that parameter

    ++runner;

Jumping to the next argument.

}
**runner = toupper(**runner);   
printf("%s ",*runner);    
++runner;
**runner = toupper(**runner);   
printf("and %s!",*runner);

Almost the same as in the loop just it takes the next two parameter which comes after a 2 byte parameter.

rekire
  • 47,260
  • 30
  • 167
  • 264
  • `**runner = toupper(**runner)` only makes the first character uppercase. – cyphar Nov 03 '13 at 12:50
  • Wouldn't it be better if at line 4'runner++' is replaced with '(*runner)++;' ?Since you actually want the pointer to which it is pointing to move one byte? Or does it directly point to the array instead of indirectly? – BURNS Nov 03 '13 at 13:31
1

When an array of pointers is passed to a function, it "decays" to a pointer to pointer. This is precisely what happens with argv of main: it is a pointer to pointers to char. Sometimes, the main declaration is written as the equivalent

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

to be more explicit about passing an array of pointers.

With the understanding of what's going on, it is easy to see that

char** runner = argv;
++runner;

is logically equivalent to this:

char** runner = &argv[1];

The author simply skips over the initial argument of main, and go straight to the command arguments proper, which start at index 1.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0

Why the main function uses a double pointer?

The main function receives 2 arguments: the number of arguments passed to the command line (argc means arguments count) and an array containing the arguments.

An argument is a string, so it's a char* in C. And you have an array of strings, so the type of argv is char**.

The second issue ,after initializing the double pointer ,runner, it is being told to point to one place further. But how on earth can you know where it points to ,if it points to a pointer which in its own turn points to a place you have no idea of?

runner points to the same array as pointed by argv. But now when you do ++runner, it will point to the next element in the array of arguments. In C, the first string is actually the name of the command, so runner now points to the first argument passed in the command line.

Maxime Chéramy
  • 17,761
  • 8
  • 54
  • 75
0

I havent run your code but I can give you some inside on why a double pointer is used.

Argv holds the arguments. Argv[0] is the program name, argv[1] is the first argument, etc. So that is why the "++runner;" is incremented first to access the first argument.

Double pointers in this case allow you to index locations in memory by easily incrementing and then when you get there you access your data which in turn it happens to be another char*.

opcode
  • 419
  • 5
  • 11