[C Series 10] Designing Data with struct, enum, and typedef

한국어 버전

After using arrays and pointers to manage sequences, we now need a way to bundle values that have different meanings. [[struct|struct]] defines those bundles, [[enum|enum]] names the allowed states, and [[typedef|typedef]] keeps long declarations readable.

New Terms in This Chapter

  1. Structure: Syntax for combining different data types into a user-defined type
  2. Enum: A type that assigns names to a list of integer constants for clarity
  3. Typedef: A keyword that attaches a shorter alias to an existing declaration
  4. Dot Operator: The . used to access fields inside a structure variable

Key Ideas

Study Notes

  • Time: 60–70 minutes
  • Prep: familiarity with arrays, pointers, and function parameters
  • Goal: define structures, initialize them, access them via pointers, and explain what enums and typedefs do

We focus on three learning goals:

  1. Define structures and initialize them with values
  2. Use enums to name state codes and improve readability
  3. Apply typedef to shorten long declarations, including pointer and function signatures

Hold on to these mental hooks:

  • struct: bundle different fields into one concept
  • enum: give names to frequently used states
  • typedef: create a shorter alias for a long declaration

Follow Along with Code

Defining and Initializing a Structure

#include <stdio.h>

struct Student {
    char name[16];
    int grade;
    double average;
};

int main(void) {
    struct Student alice = {"Alice", 2, 88.5};

    printf("name = %s\n", alice.name);
    printf("grade = %d\n", alice.grade);
    printf("average = %.1f\n", alice.average);

    return 0;
}

struct Student combines a string, an integer, and a double. Matching the initializer order with the structure definition makes it easy to set up a value. The string field is a fixed-length array, so you can print it with printf("%s").

Structure Pointers and ->

#include <stdio.h>

struct Point {
    int x;
    int y;
};

void move(struct Point *p, int dx, int dy) {
    p->x += dx;
    p->y += dy;
}

int main(void) {
    struct Point p = {0, 0};
    move(&p, 3, -2);
    printf("(%d, %d)\n", p.x, p.y);
    return 0;
}

Remember that (*p).x and p->x are equivalent. Passing a pointer to a structure lets the function modify the original data and saves memory compared to copying the entire structure.

Defining States with an Enum

#include <stdio.h>

enum Status {
    STATUS_OK = 0,
    STATUS_WARNING = 1,
    STATUS_ERROR = 2
};

void print_status(enum Status status) {
    if (status == STATUS_OK) {
        printf("OK\n");
    } else if (status == STATUS_WARNING) {
        printf("Warning\n");
    } else {
        printf("Error\n");
    }
}

int main(void) {
    print_status(STATUS_WARNING);
    return 0;
}

Enums are stored as integers, but named constants mean you no longer have to guess what each number stands for. When you do not assign explicit values, the constants default to 0, 1, 2, and so on, so only assign numbers directly when you need a specific code.

Using typedef to Simplify Declarations

typedef struct {
    char title[32];
    int year;
} Book;

typedef enum {
    LEVEL_BEGINNER,
    LEVEL_INTERMEDIATE,
    LEVEL_ADVANCED
} Level;

int main(void) {
    Book book = {"C Basics", 2026};
    Level level = LEVEL_BEGINNER;

    return 0;
}

typedef does not create a brand-new type; it creates an alias. After typedef struct { ... } Book;, you can use Book instead of the longer struct form. This example uses an anonymous struct because the alias Book is the name we want to use in practice. Enums can receive aliases the same way. Remember: use . when you access fields on a structure variable directly, such as student.name, and use -> when you access fields through a pointer, such as student_ptr->name.

Combining Structure Arrays and Functions

#include <stdio.h>

typedef struct {
    char name[16];
    int score;
} Result;

void print_higher(const Result *results, size_t length, int min_score) {
    size_t i;

    for (i = 0; i < length; i++) {
        if (results[i].score >= min_score) {
            printf("%s: %d\n", results[i].name, results[i].score);
        }
    }
}

int main(void) {
    Result results[3] = {
        {"Ana", 82},
        {"Ben", 76},
        {"Cara", 91}
    };

    print_higher(results, 3, 80);
    return 0;
}

Structure arrays behave like regular arrays, except each element holds multiple fields. Mix pointer arithmetic with . or -> to read each field cleanly.

Why It Matters

Structures and enums are the core units for expressing meaning in C. Plain variables make it hard to explain the relationship between values; structures make the data model explicit. Enums replace magic numbers with named states, which helps debugging and maintenance. typedef keeps headers and shared code readable by shortening complex declarations.

Practice in CodeSandbox

The sandbox below uses CodeSandbox's Universal starter. For C, the key learning loop is still compile and run in the terminal, so recreate the lesson code as a source file and repeat that cycle directly.

Live Practice

C Practice Sandbox

CodeSandbox

Run the starter project in CodeSandbox, compare it with the lesson code, and keep experimenting.

Universal starterCterminal
  1. Fork the starter and create a practice file such as hello.c
  2. Paste in the lesson code and compile it if clang or gcc is available
  3. Edit the code, rebuild it, and compare the new output

For C, the terminal build loop matters more than a browser preview. Compiler availability can vary by environment, so first confirm that clang or gcc is present in the Universal starter.

Practice

  • Follow: Compile the struct Student and enum Status examples to verify the output.
  • Extend: Define a typedef struct named Task and represent its state with an enum TaskState, then print a small list.
  • Debug: Compare passing a structure by value versus passing a pointer and observe the difference with printf.
  • Done When: You can describe the process for defining a structure, an enum, and a typedef in a single sentence each.

Wrap-Up

We used struct, enum, and typedef to structure data. Next time we will split our definitions and functions across header files and .c files so larger programs stay organized.

💬 댓글

이 글에 대한 의견을 남겨주세요