Thread: structure array function

  1. #1
    Advanced Novice linucksrox's Avatar
    Join Date
    Apr 2004
    Location
    Michigan
    Posts
    198

    structure array function

    I'm trying to pass a structure array to a function so that the function uses a pointer to the array. everything works fine until I try to do what I was taught, which is trying to use the "->" operator. here's my sample code that works fine with no errors:
    Code:
    #include <stdio.h>
    
    struct person {
        char fname[50];
        char mname[50];
        char lname[50];
    };
    
    struct ssinfo {
        char ssnum[10];
        struct person name;
    };
    
    void printssinfo(struct ssinfo *peoples);
    
    int main(void)
    {
        struct ssinfo people[5] =
        {
                       {"123456789", {"Eric", "David", "Daly"} },
                       {"987654321", {"Ricky", "Alfred", "Andrews"} },
                       {"102938475", {"Isabel", "", "Loft"} },
                       {"019283746", {"Chris", "", "Yaeworth"} },
                       {"784632583", {"Jeffrey", "David", "Steinberg"} }
        };
    
        printssinfo(people);
    
        puts("\n\nPress any key to continue...");
        getch();
        return 0;
    }
    
    void printssinfo(struct ssinfo *peoples)
    {
        int ctr;
    
        for (ctr = 0; ctr < 5; ctr++)
        {
          printf("%s, %s ", peoples[ctr].name.lname, peoples[ctr].name.fname);
          if (peoples[ctr].name.mname[0] != '\0')
          {
            printf("%c. ", peoples[ctr].name.mname[0]);
          }
          printf("-- %s\n", peoples[ctr].ssnum);
        }
    }
    why does it work fine using "." but not using "->" like I thought I was supposed to be using?

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Remember that any time you pass an array to a function, it's in effect a pointer. Thus, you always end up using it like a "normal" variable, not a pointer. See, you're doing two things:
    Code:
    void printssinfo(struct ssinfo *peoples);
    Which is just a pointer to one instance of a structure. Thus, you could do:
    Code:
    int main( void )
    {
        int x = 0;
        ...people here...
        for( x = 0; x < 5; x++ )
            printssinfo( &people[x] );
    }
    And modify your function so it's like...
    Code:
    void printssinfo( struct ssinfo *s )
    {
        printf("%s, %s ", s->name.lname, s->name.fname );
        ...blah blah blah...
    }
    But what you're doing instead, is passing an array like you'd normally pass an array. Thus, it is not a pointer to an instance, it's a "normal array", so you treat it like you normally would use an array.

    Quzah.
    }
    Hope is the first step on the road to disappointment.

  3. #3
    Advanced Novice linucksrox's Avatar
    Join Date
    Apr 2004
    Location
    Michigan
    Posts
    198
    i'm not sure i understand, because isn't
    Code:
    printssinfo(people);
    the same thing as
    Code:
    printssinfo(&people[0]);
    ? and in that case wouldn't that be passing the address of one instance of the array as well? why can't you do something like
    Code:
    int main(void)
    {
        struct ssinfo people[5] = {bla bla};
    
        printssinfo(people);
        return 0;
    }
    
    void printssinfo( struct ssinfo *s )
    {
        printf("%s, %s ", s[2]->name.lname, s[2]->name.fname );
        ...blah blah blah...
    }
    wait if i wanted to do that, couldn't i just simply make the function argument an array of pointers to struct ssinfo? like
    Code:
    void printssinfo(struct ssinfo *s[5]);
    ?

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    void foo1( struct bar * ); /* a function that takes a pointer to a structure */
    void foo2( struct bar * ); /* a function that takes an array of structures */
    Now think about each of these. Forget that they're structures:
    Code:
    void foo1( int *bar ); /* a function that takes a pointer to an object */
    void foo2( int *bar ); /* a function that takes an array of objects */
    How do you use a single object which is being pointed to when passed?
    Code:
    void foo( int *bar )
    {
        *bar = blahblahblah;
    }
    How do you use an array when passed?
    Code:
    void foo2( int *x )
    {
        x[0] = blahblahblah;
    }
    There you can see two ways of doing the same thing. However, remember that when you use an array, you're using the [ ] to effectively dereference it for you. That's why when you're using structures, and you use it as if it were an array, you use the . instead of the -> operator.

    Now, then, you have two ways (three, if you pass a pointer to an array, .. no, not a pointer to a member of the array, a pointer to the whole array members of the array.)

    So, if you want to use [ ], then use your dot. If you want the arrow, use it as a pointer, and move down the chain. Or, if you want to use both, use a pointer to an array.
    Code:
    void foo1( struct bar * x )
    {
        x->foobar = blahblahblah;
    }
    
    void foo2( struct bar * x )
    {
        x[0].foobar = blahblahblah;
    }
    But remember, just because an array can act like a pointer some times, doesn't mean it can in all cases.

    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    SleepWalker tjohnsson's Avatar
    Join Date
    Apr 2004
    Posts
    70
    in couple words:

    int plah[5]; // array of integers
    plah without [] is pointer
    plah[3] is an integer
    and *(plah+3) is plah[3];

    Code:
            int n[5] = { 1,2,3,4,5 };
    
            printf ( "1. n = %d\n", n );
            printf ( "2. n[3] = %d\n", n[3]  );
            printf ( "3. *(n+3) = %d\n", *(n+3) );
    
    prints:
    
    1. n = 2289432 // pointer address
    2. n[3] = 4         // fourth element
    3. *(n+3) = 4     // fourth element

  6. #6
    Registered User pinko_liberal's Avatar
    Join Date
    Oct 2001
    Posts
    284
    Quote Originally Posted by tjohnsson
    in couple words:
    plah without [] is pointer
    [/code]
    No, plah is an array.
    sizeof plah = 5*sizeof(int) which in all probability will be larger than sizeof(int *)
    try this out
    Code:
    #include <stdio.h>
    
    int
    main(void)
    {
         int plah[5];
         int *blah;
         printf("sizeof plah=%d\tsizeof blah=%d\n",(int) sizeof plah,(int) sizeof blah);
         return 0;
    }
    Last edited by pinko_liberal; 06-11-2004 at 07:19 AM. Reason: typo
    The one who says it cannot be done should never interrupt the one who is doing it.

  7. #7
    SleepWalker tjohnsson's Avatar
    Join Date
    Apr 2004
    Posts
    70
    Quote Originally Posted by pinko_liberal
    No, plah is an array.
    sizeof plah = 5*sizeof(int) which in all probability will be larger than sizeof(int *)
    try this out...
    No plah is a pointer
    read your self, this explains also why it has a different size.

    http://www.absoft.com/Products/Compi.../clrc03ary.htm

    by the way... there's misprint on my last message
    1. n = 2289432 // pointer address
    pointer value is address of array first element...

  8. #8
    Registered User pinko_liberal's Avatar
    Join Date
    Oct 2001
    Posts
    284
    Quote Originally Posted by tjohnsson
    No plah is a pointer
    read your self, this explains also why it has a different size.

    http://www.absoft.com/Products/Compi.../clrc03ary.htm

    by the way... there's misprint on my last message
    1. n = 2289432 // pointer address
    pointer value is address of array first element...
    Please read the webpage
    Except in certain contexts, an unsubscripted array name (for example, region instead of region[4]) represents a pointer whose value is the address of the first element of the array, provided that the array has previously been declared.
    Representing a pointer is not the same as being a pointer.

    If plah is a pointer you can assign values to it, why don't you try doing something like

    Code:
    int plah[20],x;
    int *blah;  
    blah=&x;
    plah=blah;
    and see what happens.

    However when a pointer is assigned the value plah it points to the address of the first element of the array which it represents.

    Code:
    int plah[20];
    int *blah;
    blah=plah; /* equivalent to blah=&plah[0]*/
    The one who says it cannot be done should never interrupt the one who is doing it.

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Pinko's right. You're wrong. Read the FAQ on the topic.

    Quzah.
    Hope is the first step on the road to disappointment.

  10. #10
    SleepWalker tjohnsson's Avatar
    Join Date
    Apr 2004
    Posts
    70
    I Still wont agree with that...

    If plah is a pointer you can assign values to it,
    cause it's declared as an array, it's pointer value is read only.

    but we can compare
    ( a == &a[0] )

  11. #11
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I Still wont agree with that...
    Then start being more specific so that people won't misunderstand you. An array is not a pointer, this much is certain. However, in most cases, an array name is converted to a pointer to the first element of the array before use.
    My best code is written with the delete key.

  12. #12
    SleepWalker tjohnsson's Avatar
    Join Date
    Apr 2004
    Posts
    70
    Quote Originally Posted by Prelude
    >I Still wont agree with that...
    Then start being more specific so that people won't misunderstand you. ...
    plah without [] is array name,
    plah without [] is pointer and
    access to an array is provided via plah.

    This what i mean is described better here:

    http://www-ee.eng.hawaii.edu/Courses...tion2.1.3.html
    http://www-ee.eng.hawaii.edu/Courses...on2.1.3.2.html

    this kind of declaration...
    func ( a[static 10], b[static 10] ) {
    ......
    }
    a and b is also called 'pointer' in C99 standard
    on chapter "array declarations".

  13. #13
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    It still is not a pointer. An array name is not a pointer. If it were, you could simply assign it to something else:
    Code:
    char foo[] = "foo";
    char bar[] = "bar";
    char *ffoo, *bbar;
    
    foo = bar; /* If "foo" were in fact a pointer, you could do this. */
    ffoo = foo; /* "ffoo" is in fact a pointer, so yes, you can do this */
    bbar = foo;
    Likewise, you can't pass a pointer to an array to a function, and assign it something else. If it were a "normal pointer", you could:
    Code:
    #include <stdio.h>
    void foobar( char **ffoo, char **bbar )
    {
            *ffoo = *bbar;
    }
    
    int main( void )
    {
            char foo[] = "hello";
            char bar[] = "world";
            char *ffoo = foo;
            char *bbar = bar;
    
            foobar( &foo, &bar ); /* Ooops, it's not a pointer. Gee, too bad. */
            printf("%s\n", foo );
            printf("%s\n", bar );
    
            foobar( &ffoo, &bbar ); /* Well, these are, thus, this is valid. */
            printf("%s\n", ffoo );
            printf("%s\n", bbar );
            return 0;
    }
    So as much as you want it to be a "real pointer", it's not. It never will be. You can't give it new lvalues. You can't treat it fully like you would a real pointer. Thus, it's not a "real pointer".

    :beatingadeadhorse:

    Damn. I was sure there was a little smiley for that...

    Quzah.
    Hope is the first step on the road to disappointment.

  14. #14
    SleepWalker tjohnsson's Avatar
    Join Date
    Apr 2004
    Posts
    70
    foobar( &foo, &bar ); /* Ooops, it's not a pointer. Gee, too bad. */
    ...
    void foobar( char **ffoo, char **bbar )
    {
    *ffoo = *bbar;
    }
    &foo, &bar does not have much effect
    because ( &foo == foo )

    pointer foo and bar is declared as an array...

    :thathorseisjustaimageofyou:
    Last edited by tjohnsson; 06-16-2004 at 12:15 AM. Reason: deleted reason for editing...

  15. #15
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >It just looks like you just don't get it
    Um, your example is wrong. A pointer to a pointer is not the same as a pointer to an array. Your understanding is close, but not quite right. An array name is not a pointer, it's an array. When used in a value context, that name is converted to a pointer to the first element of the array and when used in an object context the name remains an array. The only object contexts for an array are as an operand to the sizeof or address-of operators, and as a string literal initializer.

    The end result is for the most part the same with your understanding, but how it goes about it is where your confusion lies I think.
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  2. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM
  3. Creating a student grade book-how?
    By Hopelessly confused in forum C Programming
    Replies: 5
    Last Post: 10-03-2002, 08:43 PM
  4. I need help with passing pointers in function calls
    By vien_mti in forum C Programming
    Replies: 3
    Last Post: 04-24-2002, 10:00 AM
  5. qt help
    By Unregistered in forum Linux Programming
    Replies: 1
    Last Post: 04-20-2002, 09:51 AM