█
LastWrite
  • > Curriculum
  • > Pricing
  • > For Educators
  • > About
  • > Contact
Log InGet Started

Questions, concerns, bug reports, or suggestions? We read every message, write to us at [email protected].

More ways to reach us →
LastWrite

Structured computer science lessons for aspiring developers and security professionals.

[email protected]

(201) 785-7951

Mon–Fri, 9 AM–5 PM EST

Learn

  • Curriculum
  • Pricing

Company

  • About
  • For Educators & Schools
  • Contact Us

Legal

  • Terms of Service
  • Privacy Policy
© 2026 LastWrite. All rights reserved.
Curriculum/Programming Languages/C/Structs and Unions
40 minIntermediate

Structs and Unions

After this lesson, you will be able to: Define structs, use typedef, nested structs, unions for memory-saving variants.

Structs let you compose multiple values into one unit. The closest thing C has to objects.

Prerequisites:Memory Management

struct + typedef

Group related fields.

tsx
struct Point {
double x;
double y;
};
// Use
struct Point p1 = {1.0, 2.0};
struct Point p2 = { .x = 3.0, .y = 4.0 }; // designated initializer (C99+)
p1.x = 10.0;
// typedef saves the `struct` prefix
typedef struct {
double x, y;
} Point;
Point p3 = { .x = 1.0, .y = 2.0 };
// Pointer to struct
Point *pp = &p3;
printf("%f\n", pp->x); // shortcut for (*pp).x

Functions that take struct pointers

More efficient than passing by value for large structs.

tsx
typedef struct {
char name[64];
int age;
double balance;
} User;
void promote(User *u) {
u->balance *= 1.10; // 10% bonus
}
// const for read-only access (best practice)
void print(const User *u) {
printf("%s (%d): $%.2f\n", u->name, u->age, u->balance);
}

Unions

Variant types sharing memory.

tsx
// Tagged union, common pattern for sum types
typedef enum { TAG_INT, TAG_FLOAT, TAG_STR } ValueTag;
typedef struct {
ValueTag tag;
union {
int i;
double f;
char *s;
} data;
} Value;
Value v = { .tag = TAG_INT, .data.i = 42 };
switch (v.tag) {
case TAG_INT: printf("%d\n", v.data.i); break;
case TAG_FLOAT: printf("%f\n", v.data.f); break;
case TAG_STR: printf("%s\n", v.data.s); break;
}
// Memory: union is sized to fit the LARGEST member.
// Reading a member you didn't write is type-punning, implementation-defined.

Common mistakes only experienced C devs avoid

Forgetting structs are passed by VALUE. Use pointers for big structs. Not initializing all fields. Garbage values in uninitialized fields. Use designated initialisers + `{0}` for the rest. Reading the wrong union member. Tagged unions are the safe pattern. Struct padding, `sizeof(struct)` may be larger than sum of fields due to alignment.

Quick Check

Why pass `const Point *p` instead of `Point p`?

Pick the senior answer.

Sign in and purchase access to unlock this lesson.

Sign in to purchase
←Memory Management
Back to C
File I/O→