Structs: your own types
Group related values into one type with struct, name it with typedef, and reach through pointers with ->.
- Define a
structand create values of it - Name struct types with
typedef - Access members through a pointer with
->
Real data comes in bundles: a point has an x and a y; a student has a name, an id and a grade. A struct groups several values - its members - into one new type, so you can pass the bundle around as a single thing.
1#include <stdio.h>
2
3struct Point {
4 int x;
5 int y;
6};
7
8int main(void) {
9 struct Point p = {3, 4};
10 p.x = p.x + 10;
11 printf("(%d, %d)\n", p.x, p.y);
12 return 0;
13}(13, 4)
The definition creates a type called struct Point; it does not create any variable. struct Point p = {3, 4}; then makes one, with members initialized in order. The dot operator reaches a member: p.x. You can also name members in the initializer, which is clearer: struct Point p = {.x = 3, .y = 4};.
typedef
Writing struct everywhere gets tedious. typedef gives a type a shorter name:
1#include <stdio.h>
2
3typedef struct {
4 char name[32];
5 int id;
6 double gpa;
7} Student;
8
9int main(void) {
10 Student s = {.name = "Grace", .id = 1906, .gpa = 3.9};
11 printf("%s (#%d): %.1f\n", s.name, s.id, s.gpa);
12 return 0;
13}Grace (#1906): 3.9
Structs and functions
Structs are passed by value like any other variable: the function gets a copy of the whole struct. That is fine for small structs, but for large ones - or when the function must modify the original - pass a pointer. C has a special operator for members through a pointer: p->x means (*p).x.
1#include <stdio.h>
2
3typedef struct {
4 char owner[32];
5 long balance_cents;
6} Account;
7
8void deposit(Account *account, long cents) {
9 account->balance_cents += cents;
10}
11
12void print_account(const Account *account) {
13 printf("%s: $%ld.%02ld\n", account->owner,
14 account->balance_cents / 100, account->balance_cents % 100);
15}
16
17int main(void) {
18 Account a = {.owner = "Linus", .balance_cents = 1050};
19 deposit(&a, 275);
20 print_account(&a);
21 return 0;
22}Linus: $13.25
Arrays of structs
Structs combine naturally with arrays - an array of Student is a tiny database. Loop over it just like any other array, and use . on each element: students[i].gpa.
Key takeaways
A
structgroups related members into one type;typedefgives it a convenient name.Use
.on a struct and->through a pointer to a struct (p->xis(*p).x).Structs are copied when passed; pass
T *to modify andconst T *to read large structs cheaply.
Lesson quiz
5 questions · pass with 4 correct · up to 50 XP
Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.
Practice: write real C
These run for real. Write the program, press Run tests, and read what the compiler tells you - learning to read compiler messages is half of learning C.
Distance between points
Define a Point type with double members x and y, and write double distance(Point a, Point b) returning the straight-line distance, sqrt((ax - bx)² + (ay - by)²). Read four numbers (x1 y1 x2 y2) and print the distance with 2 decimals.
For 0 0 3 4 print 5.00.
- 3-4-5 triangle
- Same point
- Negative coordinates
Your code is compiled with gcc 14 (-Wall -Wextra) and run on Compiler Explorer (godbolt.org), a free public service.
Top of the class
The input starts with a count n (at most 50), then n lines of name score. Store them in an array of a Student struct and print the name and score of the student with the highest score (the first one wins ties):
Top: Ada 97- Three students
- Tie keeps the first
Your code is compiled with gcc 14 (-Wall -Wextra) and run on Compiler Explorer (godbolt.org), a free public service.
Questions about this lesson
Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.
Sign in to ask questions, help other learners, and earn XP for taking part.
Loading posts…