Structures and Arrays, Part II

When it comes to structures and pointers, the structure-pointer notation is used only when the structure itself is allocated as a pointer (block of memory), not when a structure member is a pointer. Let me review from last week’s Lesson:

Consider structure one that has a pointer member name.

If one is a standard structure variable: one.name

If one is allocated as a pointer: one->name

That’s it. Only when the structure is allocated as a pointer do you use the -> notation. This rule holds true even when members are arrays, as shown in this code:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

int main()
{
    struct player {
        char name[32];
        int scores[10];
    } *one;
    int x;

    /* allocate structure */
    one = (struct player *)malloc( sizeof(struct player) * 1 );
    if( one==NULL )
    {
        fprintf(stderr,"Unable to allocate structure\n");
        exit(1);
    }

    /* assign player name */
    strcpy(one->name,"Billy Zlotnick");

    /* create random scores */
    srand( (unsigned)time(NULL) );
    for( x=0; x<10; x++)
        one->scores[x] = rand() % 100;

    /* output results */
    printf("%s's scores:\n",one->name);
    for( x=0; x<10; x++)
        printf(" %3d",one->scores[x]);
    putchar('\n');

    return(0);
}

Variable one is a pointer (memory location) referencing structure player. It’s allocated at Line 15. Structure pointer notation is used at Lines 23, 28, and 33.

For the array notation (Lines 28 and 33), this format is used: one->scores[x].

In the following update to the code, three player pointer structures are assigned to array p[]. The three structures are allocated individually in a for loop starting at Line 15.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

int main()
{
    struct player {
        char name[32];
        int scores[10];
    } *p[3];
    int x,y;

    /* allocate structures */
    for( y=0; y<3; y++ )
    {
        p[y] = (struct player *)malloc( sizeof(struct player) * 1 );
        if( p[y]==NULL )
        {
            fprintf(stderr,"Unable to allocate structure %d\n",y);
            exit(1);
        }
    }

    /* assign player names */
    strcpy(p[0]->name,"Billy Zlotnick");
    strcpy(p[1]->name,"Franny Blortz");
    strcpy(p[2]->name,"Oscar Papadapolous");

    /* create random scores */
    srand( (unsigned)time(NULL) );
    for( y=0; y<3; y++)
    {
        for( x=0; x<10; x++)
            p[y]->scores[x] = rand() % 100;
    }

    /* output results */
    for( y=0; y<3; y++)
    {
        printf("%s's scores:\n",p[y]->name);
        for( x=0; x<10; x++)
            printf(" %3d",p[y]->scores[x]);
        putchar('\n');
    }

    return(0);
}

Because array p[] is a pointer, the -> notation is used to reference its members. Brackets must be used for each individual structure element; at line Line 26 you see p[0]->name reference the name member of the first structure element.

Also check out Lines 35 and 43, which use p[y]->scores[x] to reference both structure array elements as well as array member scores’ elements.

By the way, you can allocate memory for three player structure pointers at once, as shown in this code:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

int main()
{
    struct player {
        char name[32];
        int scores[10];
    } *p;
    int x,y;

    /* allocate structures */
    p = (struct player *)malloc( sizeof(struct player) * 3 );
    if( p==NULL )
    {
        fprintf(stderr,"Unable to allocate structures\n");
        exit(1);
    }

    /* assign player names */
    strcpy((p+0)->name,"Billy Zlotnick");
    strcpy((p+1)->name,"Franny Blortz");
    strcpy((p+2)->name,"Oscar Papadapolous");

    /* create random scores */
    srand( (unsigned)time(NULL) );
    for( y=0; y<3; y++)
    {
        for( x=0; x<10; x++)
            (p+y)->scores[x] = rand() % 100;
    }

    /* output results */
    for( y=0; y<3; y++)
    {
        printf("%s's scores:\n",(p+y)->name);
        for( x=0; x<10; x++)
            printf(" %3d",(p+y)->scores[x]);
        putchar('\n');
    }

    return(0);
}

At Line 5, the malloc() function allocates three struct player chunks. Because of this allocation, pointer math must be used to reference the individual structures, as shown in Lines 23, 24, 25, 32, and 40. For example, (p+1)->name accesses the name member of the second p player structure allocated.

The array member scores maintains its format: (p+y)->scores[x], but otherwise the operators used to reference the allocated pointer structure array thingy get crazy. I continue down this path in next week’s Lesson.

Leave a Reply