Thread: pointers to pointers and pointer arrays

  1. #1
    Registered User
    Join Date
    Dec 2013
    Posts
    241

    pointers to pointers and pointer arrays

    this is very dark corner in C , propably the most mis-understood subjects, pointers-array and
    pointers to pointers . I learn by myself and trying to get ahold of this subject
    is really hard.
    I'll post a few questions , thanks in advanced for the repliers!

    arrays of pointers:
    how can you excees elements in multi dimentional -pointer-arrays?
    for example , let us consider this pointer-array:
    Code:
    char *ptr[]={
    {"john","marr","dennis"},
    {"cat","dog","rat"},
    {"mom","dad","brother"}
    }
    how can we, for example, print out "dog" using pointers?

    and in this version?
    Code:
    char *ptr1[]={"john","marr","dennis"};
    char *ptr2[]={"cat","dog","rat"};
    char *ptr3[]={"mom","dad","brother"};
    
    char *ptr[]={
    *ptr1,*ptr2,*ptr3
    };
    pointers to pointer:
    1) what is the use of pointers to pointers? why would we make another pointer to pointer?
    what gain do we have from it ?
    2) one site I looked at gives the following example for function that swaps strings.
    Code:
    void swap_strings(char** str1, char** str2) {
    char* temp = *str1;
    *str1 = *str2;
    *str2 = temp;
    }
    the site indicates that this kind of function has to get pointer to pointer - why?
    strelen/strcpy etc. only use regular pointers..
    also , why does the temp in the end is not with * ?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Dave11
    for example , let us consider this pointer-array:
    Code:
    char *ptr[]={
    {"john","marr","dennis"},
    {"cat","dog","rat"},
    {"mom","dad","brother"}
    }
    how can we, for example, print out "dog" using pointers?
    It looks like you actually want an array of 3 arrays of 3 pointers to char, but you only declared an array of 3 pointers to char. Furthermore, since each pointer will point to the first character of a string literal, they should be pointers to const char instead:
    Code:
    const char *ptr[3][3] = {
        {"john", "marr", "dennis"},
        {"cat", "dog", "rat"},
        {"mom", "dad", "brother"}
    };
    upon which the example that you're looking for is just:
    Code:
    printf("%s\n", ptr[1][1]);
    Quote Originally Posted by Dave11
    1) what is the use of pointers to pointers? why would we make another pointer to pointer?
    what gain do we have from it ?
    What is the use of a pointer to some type T? Why would we make a pointer to some type T? What gain do we have from it? From there, imagine that T is a pointer type, upon which you would have (at least partially) answered your own question concerning possible uses of a pointer to a pointer.

    Quote Originally Posted by Dave11
    the site indicates that this kind of function has to get pointer to pointer - why?
    (...)
    why does the temp in the end is not with * ?
    Have you tried writing a program to use this function? Now, change the function to take a pointer to char (and modify the function call accordingly). Does it still work?

    If you still don't get it, write a similiar function to swap ints.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Dec 2013
    Posts
    241
    thank you laserlight! I knew I could count on you for an answer.

    about the first two : as far as I understand from your message the hirarchy of declaring
    pointers and arrays of pointer goes as follows:

    regular pointer (to single var) - *p
    pointer to one dimentional array - <name of the array>
    pointer to 2 dimentional array (array of strings, for example) - *p[]
    pointer to 3 dimentional array - *p[][]
    pointer to n dimentional array - *p[][]...[][]

    about the string swap , actually I took the challenge and wrote a function that does it,
    I didn't used any ** ..
    Code:
    void swap1 (char *a , char *b){
        char *a1,*b1;
        int i;
        for (a1=a;*a1;a1++); //size of first string
        for (b1=b;*b1;b1++); //size of second string
        
        char swap_string[(a1-a)>=(b1-b)?(a1-a):(b1-b)];
        
        for (i=0;i<a1-a;i++)
        swap_string[i]=*(a+i);
        
        for (i=0;i<b1-b;i++)
        *(a+i)=*(b+i);
        *(a+i)='\0';
        for (i=0;i<a1-a;i++)
        *(b+i)=swap_string[i];
        *(b+i)='\0';
        
    }
    (the function assumes that the strings are not dynamicly allocated)

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Dave11
    about the first two : as far as I understand from your message the hirarchy of declaring
    pointers and arrays of pointer goes as follows:

    regular pointer (to single var) - *p
    pointer to one dimentional array - <name of the array>
    pointer to 2 dimentional array (array of strings, for example) - *p[]
    pointer to 3 dimentional array - *p[][]
    pointer to n dimentional array - *p[][]...[][]
    No, that is not right. I suggest you try again, this time declaring a variable named x to be of whatever is your desired type. For example, for x to be a "regular" pointer to an int:
    Code:
    int *x;
    Keep in mind that an array of pointers and a pointer to an array is not the same thing:
    Code:
    int *x[N]; /* array of N pointers to int */
    int (*x)[N]; /* pointer to an array of N ints */
    Quote Originally Posted by Dave11
    about the string swap , actually I took the challenge and wrote a function that does it,
    I didn't used any ** ..
    Just because you saw one way to do something does not mean that that is the only way to do it, and just because you come up with an alternative way does not mean that what you saw earlier has no value. When it does work, your version has the advantage of working to swap the contents of two arrays. The version that you saw earlier swaps pointers to char that are each assumed to point to the first character of a string.

    Quote Originally Posted by Dave11
    (the function assumes that the strings are not dynamicly allocated)
    No, your function should work to swap strings that are stored in dynamically allocated arrays. Rather, it assumes that the arrays involved are large enough to hold the longer of the two strings involved, and it makes use of a temporary buffer whereas the version that you saw earlier only needs a temporary pointer.

    By the way, instead of writing *(a+i), just write a[i]. If you want the string length, just #include <string.h> and call strlen. Likewise, you can just call strcpy to populate swap_string instead of manually writing a loop since you know that the destination array has enough space.
    Last edited by laserlight; 02-22-2014 at 12:06 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Dec 2013
    Posts
    241
    I'm sorry that I couldn't answer until now, anyway..
    Quote Originally Posted by laserlight View Post
    No, that is not right. I suggest you try again, this time declaring a variable named x to be of whatever is your desired type. For example, for x to be a "regular" pointer to an int:
    Code:
    int *x;
    Keep in mind that an array of pointers and a pointer to an array is not the same thing:
    Code:
    int *x[N]; /* array of N pointers to int */
    int (*x)[N]; /* pointer to an array of N ints */
    .
    I phrased the sentences wrong , I meant array of pointers. I will try again with examples:
    Code:
    Char *p;    // regular pointer to char
    Char*p[]    //array of pointers, such as char *p[]={"rat","cat",dog"};
                    // the array will point to 'r' , 'c' and 'd'
    Char *p[][]// array of pointer to pointers , such as *p[][]={{"cat","dog"},{"rat","dog"}}
                   // the first lair will point to the first and second arrays , the second lair will point to 
                   //the beginning of strings themselves ('c','d','r','d')  
    Char *p[]…[] //this is array  of pointers to pointers to pointers, can be used for example 
                   //if we have array of schools, and in each school array of classes, and in each class array of students, then grades etc.
    Quote Originally Posted by laserlight View Post
    Just because you saw one way to do something does not mean that that is the only way to do it, and just because you come up with an alternative way does not mean that what you saw earlier has no value. When it does work, your version has the advantage of working to swap the contents of two arrays. The version that you saw earlier swaps pointers to char that are each assumed to point to the first character of a string.
    .
    So what the function does is actually swap the addresses of the strings rather than swap themselves? I don't get how this function works, or why the temp in the end does not have *..
    I still don't get why to use pointers to pointers when a pointer points at a regular non-array var.

    Quote Originally Posted by laserlight View Post
    By the way, instead of writing *(a+i), just write a[i]. If you want the string length, just #include <string.h> and call strlen. Likewise, you can just call strcpy to populate swap_string instead of manually writing a loop since you know that the destination array has enough space.
    I know, I just wanted to use the pointer style of writing rather than just regular arrays.
    Last edited by Dave11; 02-24-2014 at 04:07 PM.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Dave11
    So what the function does is actually swap the addresses of the strings rather than swap themselves?
    A string is a contiguous sequence of characters terminated by and including the first null character. So, what does it mean to swap two strings themselves? You cannot do that. It is like trying to swap 0 and 1 themselves. 0 is still 0, 1 is still 1, whether you write 0 and then 1 or 1 and then 0. You could reassign the meaning of the symbols and say that 0 means "one" and 1 means "zero", but I won't agree to your symbol reassignment, and that's that.

    So, when we talk about swapping strings, we are actually using shorthand to talk about swapping the contents of two arrays that each contain a string, i.e., after the swap, the contents of each array that constitute a string would have been exchanged. Or, we are using shorthand to talk about swapping the values of two pointers, each of which points to the first character of a string, i.e., after the swap, each pointer would point to what the other pointer pointed to.

    The approach that you took is the former; the approach of the example that you saw is the latter. Which one is appropriate depends on the situation.

    Quote Originally Posted by Dave11
    I don't get how this function works, or why the temp in the end does not have *..
    Do you understand how the function below works?
    Code:
    void swap(int* x, int* y) {
        int temp = *x;
        *x = *y;
        *y = temp;
    }
    Why does the temp at the end not have *?

    Let's do a small trick with a typedef:
    Code:
    typedef int T;
    Now, we shall rewrite the function in terms of T:
    Code:
    void swap(T* x, T* y) {
        T temp = *x;
        *x = *y;
        *y = temp;
    }
    Why does the temp at the end not have *?

    Great, let's revise the typedef:
    Code:
    typedef char* T;
    Again, we write:
    Code:
    void swap(T* x, T* y) {
        T temp = *x;
        *x = *y;
        *y = temp;
    }
    Why does the temp at the end not have *?

    One final trick. We revert from the version with the current typedef to a version without the typedef:
    Code:
    void swap(char** x, char** y) {
        char* temp = *x;
        *x = *y;
        *y = temp;
    }
    Why does the temp at the end not have *?

    Quote Originally Posted by Dave11
    I still don't get why to use pointers to pointers when a pointer points at a regular non-array var.
    Have you ever used malloc to dynamically allocate space for an array that will be used to store a string?

    Quote Originally Posted by Dave11
    I know, I just wanted to use the pointer style of writing rather than just regular arrays.
    It just makes your code more difficult to read. The array subscript notation is equivalent to the pointer notation, i.e., besides spelling, E1[E2] is identical to (*((E1)+(E2))). This is such that even if you wrote i[a] instead of a[i] for a valid index i, it would still be syntactically valid, though not recommended. So, if you mean a[i], then write a[i], not *(a + i), whether a is a pointer or an array (which would be converted to a pointer to its first element).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Array of pointers and pointer for arrays with argv
    By thames in forum C Programming
    Replies: 4
    Last Post: 12-02-2012, 10:24 AM
  2. Pointers to pointers with arrays
    By Nurumla in forum C Programming
    Replies: 3
    Last Post: 07-18-2011, 11:53 PM
  3. Replies: 7
    Last Post: 05-19-2010, 02:12 AM
  4. Passing pointers to arrays of char arrays
    By bobthebullet990 in forum C Programming
    Replies: 5
    Last Post: 03-31-2006, 05:31 AM
  5. pointer to pointers to arrays of strings??
    By Binkstone in forum C Programming
    Replies: 8
    Last Post: 09-14-2001, 02:56 AM