CArrays of Structures

Arrays of Structures

A single struct models one record. Real programs almost always need many records of the same shape — a classroom of students, a list of products, a batch of sensor readings. Since a struct is just a type like any other, you can declare an array of them exactly the way you would declare an array of ints or doubles.

Declaring an array of structs

C
struct Point {
    int x;
    int y;
};

struct Point points[10];   /* an array of 10 Point structs */

points is laid out in memory as ten Point structs, back to back, exactly the way an int[10] is laid out as ten ints back to back. Each element is a full, independent struct.

Accessing fields of individual elements

Combine array indexing with dot access: points[i] selects the i-th struct in the array, and .field then reaches into that struct.

C
#include <stdio.h>

struct Point {
    int x;
    int y;
};

int main(void) {
    struct Point points[3] = {
        {0, 0},
        {1, 2},
        {3, 4}
    };

    for (int i = 0; i < 3; i++) {
        printf("points[%d] = (%d, %d)\n", i, points[i].x, points[i].y);
    }

    /* Modifying one element does not touch the others. */
    points[1].x = 100;
    printf("points[1] is now (%d, %d)\n", points[1].x, points[1].y);

    return 0;
}
points[0] = (0, 0)
points[1] = (1, 2)
points[2] = (3, 4)
points[1] is now (100, 2)
A realistic worked example: student records

Arrays of structs are the natural way to represent a table of records. Here, an array of Student structs stores a small roster, and a loop computes the class average GPA.

C
#include <stdio.h>

struct Student {
    char name[30];
    int  id;
    double gpa;
};

int main(void) {
    struct Student roster[4] = {
        { "Ada",     1, 3.9 },
        { "Alan",    2, 3.7 },
        { "Grace",   3, 4.0 },
        { "Charles", 4, 3.4 }
    };

    double total = 0.0;
    for (int i = 0; i < 4; i++) {
        printf("%-8s (ID %d): GPA %.2f\n",
               roster[i].name, roster[i].id, roster[i].gpa);
        total += roster[i].gpa;
    }

    printf("Class average GPA: %.2f\n", total / 4);
    return 0;
}
Ada      (ID 1): GPA 3.90
Alan     (ID 2): GPA 3.70
Grace    (ID 3): GPA 4.00
Charles  (ID 4): GPA 3.40
Class average GPA: 3.75
Passing an array of structs to a function

Just like an array of any other type, an array of structs decays to a pointer to its first element when passed to a function. The function typically also receives the element count as a separate parameter, since the pointer alone carries no size information.

C
#include <stdio.h>

struct Student {
    char name[30];
    int  id;
    double gpa;
};

double averageGpa(const struct Student roster[], int count) {
    double total = 0.0;
    for (int i = 0; i < count; i++) {
        total += roster[i].gpa;
    }
    return total / count;
}

int main(void) {
    struct Student roster[3] = {
        { "Ada",   1, 3.9 },
        { "Alan",  2, 3.7 },
        { "Grace", 3, 4.0 }
    };

    printf("Average GPA: %.2f\n", averageGpa(roster, 3));
    return 0;
}
Average GPA: 3.87
Why const struct Student roster[]
Writing the parameter as `const struct Student roster[]` (equivalent to `const struct Student *roster`) documents that the function only reads the records and never modifies the caller's array — the same array-decays-to-pointer behavior covered on the arrays and functions page applies here without any special-casing for structs.
Memory layout at a glance

Expression

Meaning

points[0]

The first struct in the array

points[i].x

The x member of the i-th struct

&points[i]

A pointer to the i-th struct — useful for passing one element by pointer

sizeof(points)

Total size in bytes of the whole array (element size × element count)

  • Declare an array of structs the same way you would any other array: struct T name[N].

  • Combine indexing and dot access: array[i].field.

  • Each element is an independent struct — modifying one does not affect the others.

  • An array of structs decays to a pointer to its first element when passed to a function, same as any other array.

  • Pass the element count alongside the array, since the pointer carries no length information.

Coming up: unions and enums
With structs, pointers, functions, and arrays of structs covered, the next pages turn to two related tools: unions, which overlap memory instead of separating it, and enums, for naming sets of related integer constants.