Lesson 127 min read

Structs & Typedef

A struct is like a custom form β€” you design the fields, C fills them in.

Designing Your Own Data Type

Imagine you're building a student database. Each student has a name, an age, and a GPA. You could juggle three separate arrays β€” one for names, one for ages, one for GPAs β€” but that's like storing a person's ID, photo, and address in three different filing cabinets. Messy.

A struct lets you bundle related data into a single package. Think of it as designing a custom form: you pick the fields, and C lets you stamp out as many copies as you need.

Defining and Using a Struct

#include <stdio.h>
#include <string.h>
struct Student {
char name[50];
int age;
float gpa;
};
int main() {
struct Student alice;
strcpy(alice.name, "Alice");
alice.age = 20;
alice.gpa = 3.85;
printf("Name: %s\n", alice.name);
printf("Age: %d\n", alice.age);
printf("GPA: %.2f\n", alice.gpa);
return 0;
}
Output
Name: Alice
Age:  20
GPA:  3.85

typedef β€” The Shorthand

Typing struct Student everywhere gets old fast. typedef lets you create an alias so you can just write Student instead. It's like giving your form a short name for the label maker.

typedef Makes Life Easier

#include <stdio.h>
#include <string.h>
typedef struct {
char name[50];
int age;
float gpa;
} Student;
int main() {
// No need to write "struct Student" anymore!
Student bob;
strcpy(bob.name, "Bob");
bob.age = 22;
bob.gpa = 3.42;
printf("%s is %d years old with a %.2f GPA\n",
bob.name, bob.age, bob.gpa);
return 0;
}
Output
Bob is 22 years old with a 3.42 GPA

Dot (.) vs Arrow (->)

When you have a struct variable, use the dot operator to access fields: alice.name. But when you have a pointer to a struct, use the arrow operator: ptr->name.

The arrow is just shorthand for (*ptr).name β€” dereferencing the pointer first, then accessing the field. But the arrow is much cleaner.

Pointer to Struct with Arrow Operator

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[50];
int age;
} Person;
void birthday(Person *p) {
p->age++; // Arrow operator for pointer-to-struct
printf("Happy birthday, %s! You're now %d.\n",
p->name, p->age);
}
int main() {
Person john;
strcpy(john.name, "John");
john.age = 29;
printf("Before: %s is %d\n", john.name, john.age);
birthday(&john); // Pass pointer to avoid copying
printf("After: %s is %d\n", john.name, john.age);
return 0;
}
Output
Before: John is 29
Happy birthday, John! You're now 30.
After:  John is 30
Note: When you pass a struct to a function, C copies the ENTIRE struct β€” every byte of it. For a struct with a 1000-char array inside, that's 1000+ bytes copied on every call. For large structs, always pass a pointer instead.

Nested Structs

Structs can contain other structs β€” like a form that has a sub-section. An Address struct inside a Person struct keeps things organized.

Nested Structs

#include <stdio.h>
#include <string.h>
typedef struct {
char street[100];
char city[50];
int zip;
} Address;
typedef struct {
char name[50];
Address home; // Struct inside a struct
} Person;
int main() {
Person p;
strcpy(p.name, "Carol");
strcpy(p.home.street, "123 Main St");
strcpy(p.home.city, "Springfield");
p.home.zip = 62704;
printf("%s lives at %s, %s %d\n",
p.name, p.home.street,
p.home.city, p.home.zip);
return 0;
}
Output
Carol lives at 123 Main St, Springfield 62704

Array of Structs

Need a class roster? An inventory list? Just make an array of structs. Each element is a complete record β€” like a row in a spreadsheet.

Array of Structs

#include <stdio.h>
#include <string.h>
typedef struct {
char name[50];
int score;
} Player;
int main() {
Player leaderboard[3];
strcpy(leaderboard[0].name, "Alice");
leaderboard[0].score = 950;
strcpy(leaderboard[1].name, "Bob");
leaderboard[1].score = 870;
strcpy(leaderboard[2].name, "Carol");
leaderboard[2].score = 920;
printf("=== Leaderboard ===\n");
for (int i = 0; i < 3; i++) {
printf("%d. %-10s %d pts\n",
i + 1, leaderboard[i].name,
leaderboard[i].score);
}
return 0;
}
Output
=== Leaderboard ===
1. Alice      950 pts
2. Bob        870 pts
3. Carol      920 pts
Note: Structs in C don't have methods (functions inside them) like classes in C++ or Java. If you want a function that operates on a struct, pass the struct (or a pointer to it) as a parameter.
Challenge

Quick check

What does typedef do when used with a struct?
← Dynamic MemoryFile I/O β†’