Array of const pointers to const struct

This is a discussion on Array of const pointers to const struct within the C Programming forums, part of the General Programming Boards category; I'm a little confused about how to use const. I have a struct person and I have an array of ...

  1. #1
    Registered User
    Join Date
    Jul 2011
    Posts
    9

    Array of const pointers to const struct

    I'm a little confused about how to use const. I have a struct person and I have an array of pointers to person structs. I want to have a showgroup() method that takes an array of pointers to person, prints the person structs and makes sure the pointers to struct are not modified nor are the structs themselves modified. Am I doing this right?


    Code:
    struct person {
        char fname[40];
        char lname[40];
    };
    
    // Array of const pointers to const person struct's?
    void showgroup(const struct person * const group[], int n);
    ...
    
    struct person group[10];
    struct person *pgroup[10];
    
    for (x = 0; x < 10; x++)
        pgroup[x] = &group[x];
    
    showgroup(pgroup, n);

  2. #2
    Registered User
    Join Date
    Apr 2006
    Posts
    2,037
    Yep. Looks right.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,498
    Here's how to read what you wrote:
    Code:
    void showgroup(const struct person * const group[], int n);
    group is an array of constant pointers to constant person structs. The const always goes with what's just to it's left. If it's on the far left, it goes with what's immediately to it's right. You could also have written:
    Code:
    void showgroup(struct person const * const group[], int n);
    But if you have trouble writing/reading it, try it out and see. Write a function that tries to change what an array element points to and the contents of what it points to and see if you get compiler errors. You don't even need the for loop or function call. Here's my person.c:
    Code:
    struct person {
        char fname[40];
        char lname[40];
    };
    
    
    void showgroup(const struct person * const group[], int n)
    {
        // change what an array element points to
        *(group[0]) = NULL;
        // change the contents of what an array element points to
        group[0]->fname[0] = '\0';
    }
    Now compile:
    Code:
    $ gcc -Wall person.c
    person.c: In function ‘showgroup’:
    person.c:9: error: assignment of read-only location ‘**group’
    person.c:11: error: assignment of read-only location ‘(*group)->fname[0]’
    Looks like you can't change the pointers in the array, or the contents of what they point to.

    EDIT: Read this link for how to interpret, and write, complex C declarations: http://www.unixwiz.net/techtips/reading-cdecl.html.

  4. #4
    Registered User
    Join Date
    Jul 2011
    Posts
    9
    Perfect, thanks for the explanation! I have two more questions.

    First, when I try to call the function, I get a warning:
    warning: passing argument 1 of 'showgroup' from incompatible pointer type

    Code:
    struct person *pgroup[10];
    
    showgroup(pgroup, 10);
    I'm assuming I need to cast to const somehow but I'm not sure.

    Question two:

    I have a showsorted() function declared with the same arguments as before:

    Code:
    void showsorted(const struct person * const group[], int n)
    {
        int x;
        int y;
        struct person * copy[n];
        struct person * tmp;
    
        for (x = 0; x < n; x++)
                 copy[x] = &group[x];  // compiler shows warning here
    
         for (x = 0; x < n - 1; x++) {
                 for (y = x + 1; y < n; y++) {
                          if (strcmp(copy[x]->lname, copy[y]->lname) > 0) {
                                 tmp = copy[x];
                                 copy[x] = copy[y];
                                 copy[y] = tmp;
                         }
                 }
         }
        showgroup(copy, n);
    }
    I get the following warning:
    warning: assignment from incompatible pointer type

    So, I thought about it and came up with this (seems pretty messy):

    Code:
    void showsorted(const struct seat * const group[], int n)
    {
            int x;
            int y;
            const struct person * const * copy[n];
            const struct person * const * tmp;
    
            for (x = 0; x < n; x++)
                    copy[x] = &group[x];
    
            for (x = 0; x < n - 1; x++) {
                    for (y = x + 1; y < n; y++) {
                            if (strcmp((*copy[x])->lname,
                                    (*copy[y])->lname) > 0) {
                                    tmp = copy[x];
                                    copy[x] = copy[y];
                                    copy[y] = tmp;
                            }
                    }
            }
            //showgroup(copy, n);
            for (x = 0; x < n; x++) {
                    printf("fname: %s lname: %s\n",
                            (*copy[x])->fname, (*copy[x])->lname);
            }
            return;
    }
    Of course, I can't tell if it will work because I am stuck on actually calling the functions.
    Last edited by albundy; 08-24-2011 at 09:05 PM.

  5. #5
    Registered User
    Join Date
    Jul 2011
    Posts
    9
    I think I just found the answer.

    showgroup((const struct person * const *)pgroup, 10);

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 04-20-2011, 01:19 PM
  2. question about const pointers and const ints
    By WarDoGG in forum C Programming
    Replies: 9
    Last Post: 01-08-2011, 01:11 PM
  3. Replies: 3
    Last Post: 11-15-2009, 03:57 AM
  4. Replies: 1
    Last Post: 04-03-2009, 08:52 AM
  5. Replies: 7
    Last Post: 04-28-2008, 09:20 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21