Thread: pointer to pointers to arrays of strings??

  1. #1
    Binkstone
    Guest

    Unhappy pointer to pointers to arrays of strings??

    Hi

    I am fairly new to C and have come up against 'pointers of pointers'.

    I understand the concept (I think) but am baffled by the example given in my text book. If any of you can help i would really be pleased. Here's the code, sorry its a bit long...




    #include <stdio.h>

    void StrPrint1(char **str1, int size); /*HERE BEGINS MY PROBLEM*/

    void StrPrint2(char *str2);

    main()

    { /*declare and initialise pointer array*/


    char *str[4] = { "first line", "second line",
    "third line",

    "last line\n"

    };



    int i, size = 4;


    StrPrint1(str, size); /*call function and pass args*/

    for( i=1; i<size; i++)
    StrPrint2(str[i]);

    return 0;

    }

    void StrPrint1(char **str1, int size)

    {
    int i;
    /*print all strings in an array of pointers to strings*/
    for(i=0; i<size; i++)
    printf("%s\n", str1[i]);

    }



    void StrPrint2(char *str2)

    {

    /*prints one string at a time*/
    printf("%s\n", str2);
    }

    Essentially what I don't get is the **str1 thing. Is it a pointer which points to the address of the array of pointers *str[4]?

    Why is it never assigned to anything?

    Or is it referring to str[4] as a 'pointer of pointers'?

    I think you can tell I am confused so the simpler the answers the better.

    buck71

  2. #2
    Unregistered
    Guest
    #include <stdio.h>

    void StrPrint2(char *str2); /* This is simple wraper over printf statement. You might have noticed. */

    void StrPrint1(char **str1, int size); /* Look the first parameter. It is an array of strings. Isn't it ?. That array is declared as follows. So you can say, **str is pointer to pointer, because "first line" ( which is *str) is a string ("points to character array({'f', 'i', 'r', 's', 't, ' ', 'l', 'i', 'n', 'e', '\0'}))




    char *str[4] = { "first line", "second line",
    "third line",
    "last line\n"
    };
    int i, size = 4;
    StrPrint1(str, size); /*call function and pass args*/
    for( i=1; i<size; i++)
    StrPrint2(str[i]);

    return 0;

    }

    void StrPrint1(char **str1, int size)

    {
    int i;
    /*print all strings in an array of pointers to strings*/
    for(i=0; i<size; i++)
    printf("%s\n", str1[i]);

    }



    void StrPrint2(char *str2)

    {

    /*prints one string at a time*/
    printf("%s\n", str2);
    }

  3. #3
    Unregistered
    Guest

    Arrow

    #include <stdio.h>

    void StrPrint2(char *str2); /* This is simple wraper over printf statement. You might have noticed. */

    void StrPrint1(char **str1, int size);
    /* Look the first parameter. It is an array of strings. Isn't it ?. That array is declared as follows.
    */

    char *str[4] = { "first line", "second line",
    "third line",
    "last line\n"
    };

    /*
    So you can say, **str is pointer to pointer, because "first line" ( which is *str) is a string ("points to character array({'f', 'i', 'r', 's', 't, ' ', 'l', 'i', 'n', 'e', '\0'}))
    */

    int i, size = 4;
    StrPrint1(str, size); /*call function and pass args*/
    for( i=1; i<size; i++)
    StrPrint2(str[i]);

    return 0;

    }

    void StrPrint1(char **str1, int size)

    {
    int i;
    /*print all strings in an array of pointers to strings*/
    for(i=0; i<size; i++)
    printf("%s\n", str1[i]);
    /* Since the **str1( which is infact the **str declared and passed to the function) contains 4 (size) strings, the loop prints the four strings ( elements 0,1,2,3 ) of the **str(**str1 in this function).*/

    }

    /* Hope you are not confused */



    void StrPrint2(char *str2)

    {

    /*prints one string at a time*/
    printf("%s\n", str2);
    }

  4. #4
    Registered User
    Join Date
    Aug 2001
    Posts
    9
    I was at a different machine so had to use a different name.

    What you seem to be saying is that:

    a normal pointer such as *ptr_1 contains a memory address for whatever it points to, say an integer.

    If that happens to be a string - str1 - then that in turn is a pointer to the first element in the array of characters which make it up? IS that right?

    In the declaration then **str1 the extra * denotes the fact that there's a string involved? I think I have this wrapped around my neck...

    Do I? That doesn't seem right to me.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Reading from left to right, the types remove one * from the pointer type until you're finally left with a single char. Each use of a * or [] within the code to dereference a pointer moves you one step to the right, so *Str1 for example would have the type char*

    This is what your example data would look like, as seen from within the StrPrint1 function.


    &nbsp;&nbsp;&nbsp;char**&nbsp;------->&nbsp;char*&nbsp;----->&nbsp;char
    &nbsp;
    &nbsp;+--------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+--------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+---+---+---+---+---+---+
    &nbsp;|&nbsp;&nbsp;Str1&nbsp;&nbsp;|----->|&nbsp;str[0]&nbsp;|---->|&nbsp;F&nbsp;|&nbsp;i&nbsp;|&nbsp;r&nbsp;|&nbsp; s&nbsp;|&nbsp;t&nbsp;|&nbsp;&nbsp;&nbsp;|...&nbsp; to&nbsp;the&nbsp;\0
    &nbsp;+--------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+--------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+---+---+---+---+---+---+
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;|&nbsp;str[1]&nbsp;|---->|&nbsp;S&nbsp;|&nbsp;e&nbsp;|&nbsp;c&nbsp;|&nbsp; o&nbsp;|&nbsp;n&nbsp;|&nbsp;d&nbsp;|...&nbsp;to&nb sp;the&nbsp;\0
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;+--------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+---+---+---+---+---+---+
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;|&nbsp;str[2]&nbsp;|---->|&nbsp;T&nbsp;|&nbsp;h&nbsp;|&nbsp;i&nbsp;|&nbsp; r&nbsp;|&nbsp;d&nbsp;|&nbsp;&nbsp;&nbsp;|...&nbsp; to&nbsp;the&nbsp;\0
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;+--------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+---+---+---+---+---+---+
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;|&nbsp;str[3]&nbsp;|---->|&nbsp;F&nbsp;|&nbsp;o&nbsp;|&nbsp;u&nbsp;|&nbsp; r&nbsp;|&nbsp;t&nbsp;|&nbsp;h&nbsp;|...&nbsp;to&nb sp;the&nbsp;\0
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;+--------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+---+---+---+---+---+---+


    When you print something with printf("%s"), the aim is to get to something which has a type of char* (this is what %s expects).

    void StrPrint2(char *str2) is already a char*, there is nothing to do, and printf can be called directly.

    void StrPrint1(char **str1, int size) starts off as a char**, so to print any single string, we need to dereference one level. str1[i] does this nicely.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Aug 2001
    Posts
    9
    Thanks Salem

    If I follow correctly then we have:

    StrPrint1(str, size)

    str1 as the name of the array, points to----->str1[0]--- which is a pointer to the first string "line one"

    So dereferencing has an extra layer to go through before it gets to the type of data wanted by %s.

    I hope I have that right. Its still a bit fuzzy.

  7. #7
    Unregistered
    Guest
    Maybe this will help as well
    http://pweb.netcom.com/~tjensen/ptr/pointers.htm

    Dunno if this will confuse you or not, but these function prototypes are all identical (as far as the compiler is concerned).
    The last one is perhaps the most helpful, since it matches the declaration of the str array you're passing as a parameter.

    Code:
    void StrPrint1(char **str1, int size);
    void StrPrint1(char *str1[], int size);
    void StrPrint1(char *str1[4], int size);

  8. #8
    Registered User biosx's Avatar
    Join Date
    Aug 2001
    Posts
    230
    Bravo, Salem.

    Great diagram.

  9. #9
    Registered User
    Join Date
    Aug 2001
    Posts
    9

    Thumbs up

    Yes, I agree biosx, that is a fantastic looking diagram.

    I am going to check that link now

    Thanks for all answers

    Buck

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pointers or Arrays?
    By magda3227 in forum C Programming
    Replies: 3
    Last Post: 07-09-2008, 09:52 AM
  2. Following CTools
    By EstateMatt in forum C Programming
    Replies: 5
    Last Post: 06-26-2008, 10:10 AM
  3. Help with arrays and pointers please...
    By crazyeyesz28 in forum C++ Programming
    Replies: 8
    Last Post: 03-17-2005, 01:48 PM
  4. delete and delete[]
    By Hunter2 in forum C++ Programming
    Replies: 13
    Last Post: 06-26-2003, 04:40 AM
  5. pointers & arrays
    By falconetti in forum C Programming
    Replies: 4
    Last Post: 12-18-2001, 11:55 PM