Structures
Your own record typesA structure bundles related values — a name, an age, some marks — into one variable of a type you define yourself. In the lab below you create and copy a struct, keep a whole class of students in an array of structures, and look inside memory to see where each member sits and why sizeof is sometimes bigger than you expect.
- structgroups values of different types
- p.xone member of p
- sizeofmay include padding
Ready
Keyboard: ← → step · Space play / pause · R reset · Esc exit classroom mode
The ideas behind the lab
Exactly what you watched happen, in plain steps.
Define a type, then make variables of it
struct Name { members }; defines a new type — a blueprint that lists the members and their types. It uses no memory by itself. Then struct Name v; creates a variable with all those members side by side. Reach a member with the dot: v.member. Structs can be initialised with { }, copied with =, put in arrays and nested inside other structs.
struct Point { // the type (no memory yet)
int x;
int y;
}; // note the semicolon!
struct Point p = {3, 4}; // a variable: 8 bytes
p.x = 10; // one member
struct Point q = p; // copies both members
struct Point pts[10]; // an array of 10 points
| Member | Size | Offset | Why |
|---|---|---|---|
| char c | 1 | 0 | The first member starts at offset 0 |
| (padding) | 3 | 1–3 | int must start at a multiple of 4 |
| int i | 4 | 4 | |
| char d | 1 | 8 | |
| (padding) | 3 | 9–11 | The size is rounded up to a multiple of 4 |
| sizeof(struct S) | 12 | — | Reordered as int, char, char it is only 8 |
Defining and creating
- struct Student { char name[20]; int age; double gpa; }; — end with a semicolon.
- The definition usually goes above main, so every function can use the type.
- struct Student s; creates one variable; its members are garbage until set.
- Initialise in order: struct Student s = {"Ann", 19, 8.5};
- Or by name (C99): struct Student s = {.age = 19, .name = "Ann"};
Using members
- s.age = 20; — the dot selects one member.
- A member is an ordinary variable: s.age++, scanf("%d", &s.age).
- Text members are char arrays: use strcpy(s.name, "Bob"), not =.
- Whole structs can be assigned: t = s; copies every member, arrays too.
- Structs cannot be compared with == — compare the members one by one.
Arrays, nesting and size
- struct Student cls[30]; — cls[i].age is the age of student i.
- A member can be another struct: b.published.year.
- Members are placed in order, each at a multiple of its own size (alignment).
- The gaps are padding; the total is rounded up too.
- Ordering members from largest to smallest often saves memory. Always use sizeof.
Books with a nested date
Every line, explained.
#include <stdio.h>
#include <string.h>
struct Date {
int day, month, year;
};
struct Book {
char title[30];
double price;
struct Date published;
A struct inside a struct.
};
int main(void)
{
struct Book b = {"C Basics", 299.50, {15, 8, 2024}};
Nested braces for the nested struct.
struct Book shelf[2];
An array of structs.
shelf[0] = b;
Copies the whole book, title included.
strcpy(shelf[1].title, "Pointers");
A char array member needs strcpy.
shelf[1].price = 349.00;
shelf[1].published.day = 1;
Two dots: book → date → day.
shelf[1].published.month = 1;
shelf[1].published.year = 2025;
for (int i = 0; i < 2; i++)
printf("%s %.2f %d\n", shelf[i].title, shelf[i].price, shelf[i].published.year);
C Basics 299.50 2024 / Pointers 349.00 2025
printf("%zu bytes per book\n", sizeof(struct Book));
30 + 2 padding + 8 + 12 = 52 → rounded to 56
return 0;
}
Spot the bug
Mistakes almost every beginner makes — and how to fix them.
Missing semicolon after the definition
struct Point { int x; int y; }
int main(void) { … }
struct Point { int x; int y; };
int main(void) { … }
Without ; the compiler reads the next line as part of the struct declaration — confusing errors follow.
Forgetting the word struct
Point p; // error in C
struct Point p; // or use typedef (Module 35)
In C the type's full name is "struct Point".
Assigning text with =
s.name = "Ann";
strcpy(s.name, "Ann");
name is a char array, and arrays cannot be assigned. (Copying the whole struct with = is fine.)
Comparing structs with ==
if (p == q) …
if (p.x == q.x && p.y == q.y) …
C has no == for structs; compare the members.
Assuming sizeof is the sum of the members
// char + int + char = 6 bytes?
printf("%zu", sizeof(struct S)); // 12
Padding is added for alignment. Never hard-code a struct's size.
Check your understanding
Answer each question — you will see the explanation straight away.
struct P { int x; int y; }; struct P a = {1, 2}; — what is a.y?
The values fill the members in order.
struct P a = {1, 2}; struct P b = a; b.x = 9; — what is a.x?
b is a separate copy.
Which operator selects a member of a struct variable?
The dot: s.member. (-> is for pointers, Module 35.)
struct S { char c; int i; }; — what is sizeof(struct S) on a typical system?
1 byte, 3 padding, 4 bytes = 8.
struct Student cls[30]; — how do you get the age of the 5th student?
Index the array first, then select the member; the 5th has index 4.
Structures quiz
Test yourself: 10 questions, 70% to pass. Create a free account to take the quiz, save your progress and work towards the certificate.