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
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.
#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.
#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.
#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
Memory layout at a glance
Expression | Meaning |
|---|---|
| The first struct in the array |
| The x member of the i-th struct |
| A pointer to the i-th struct — useful for passing one element by pointer |
| 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.