Bytebook Compiler

Structures, Files & More

Structures, Unions & Enums

Group related data with struct, name types with typedef, use arrays of structures and pointers to them, and compare structures with unions and enums.

5 min read8 runnable examples4-question quiz

Real things have several properties. A student has a roll number, a name and a CGPA. A structure (struct) bundles variables of different types into one new type.

C
#include <stdio.h>
#include <string.h>

struct Student {
    int roll;
    char name[30];
    float cgpa;
};

int main(void) {
    struct Student s1 = {101, "Asha Rao", 9.1f};
    struct Student s2;
    s2.roll = 102;                        // the dot operator accesses members
    strcpy(s2.name, "Ravi Kumar");
    s2.cgpa = 8.4f;

    printf("%d  %-12s %.1f\n", s1.roll, s1.name, s1.cgpa);
    printf("%d  %-12s %.1f\n", s2.roll, s2.name, s2.cgpa);
    return 0;
}
Output
101  Asha Rao     9.1
102  Ravi Kumar   8.4

typedef

typedef gives a type a shorter name, so you can write Student instead of struct Student:

C
#include <stdio.h>

typedef struct {
    double x, y;
} Point;

double area(Point a, Point b, Point c) {   // triangle area from three corners
    double v = (a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y)) / 2;
    return v < 0 ? -v : v;
}

int main(void) {
    Point a = {0, 0}, b = {4, 0}, c = {0, 3};
    printf("Area = %.1f\n", area(a, b, c));
    return 0;
}
Output
Area = 6.0

Arrays of structures

C
#include <stdio.h>

typedef struct {
    int roll;
    char name[20];
    int marks;
} Student;

int main(void) {
    Student cls[50];
    int n, top = 0;
    printf("How many students? ");
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        printf("Roll, name, marks: ");
        scanf("%d %19s %d", &cls[i].roll, cls[i].name, &cls[i].marks);
        if (cls[i].marks > cls[top].marks) top = i;
    }
    printf("Topper: %s (roll %d) with %d marks\n", cls[top].name, cls[top].roll, cls[top].marks);
    return 0;
}
Output
How many students? 3
Roll, name, marks: 1 Asha 88
Roll, name, marks: 2 Ravi 95
Roll, name, marks: 3 Meera 79
Topper: Ravi (roll 2) with 95 marks
Sample input is includedTry it Yourself

Pointers to structures and the arrow operator

With a pointer to a struct, use -> to reach a member. p->marks is shorthand for (*p).marks:

C
#include <stdio.h>

typedef struct {
    char name[20];
    int balance;
} Account;

void deposit(Account *acc, int amount) {     // pass by pointer: no copy, changes stick
    acc->balance += amount;
}

int main(void) {
    Account a = {"Priya", 500};
    Account *p = &a;
    deposit(p, 250);
    printf("%s has Rs %d\n", p->name, p->balance);
    printf("Same thing: %d\n", (*p).balance);
    return 0;
}
Output
Priya has Rs 750
Same thing: 750

Passing a pointer to a large struct is faster than passing the struct itself, because nothing is copied.

Nested structures

C
#include <stdio.h>

typedef struct { int day, month, year; } Date;
typedef struct { char title[40]; Date due; } Assignment;

int main(void) {
    Assignment a = {"Linked list lab", {14, 11, 2026}};
    printf("%s is due on %02d/%02d/%d\n", a.title, a.due.day, a.due.month, a.due.year);
    return 0;
}
Output
Linked list lab is due on 14/11/2026

Structure size and padding

The compiler may insert unused padding bytes so each member starts at an address the CPU can read quickly. So a struct can be bigger than the sum of its members:

C
#include <stdio.h>

struct A { char c; int i; char d; };     // 1 + (3 pad) + 4 + 1 + (3 pad) = 12
struct B { int i; char c; char d; };     // 4 + 1 + 1 + (2 pad) = 8

int main(void) {
    printf("sizeof(struct A) = %zu\n", sizeof(struct A));
    printf("sizeof(struct B) = %zu\n", sizeof(struct B));
    return 0;
}
Output
sizeof(struct A) = 12
sizeof(struct B) = 8

Unions

A union looks like a struct, but all its members share the same memory. Its size is the size of its largest member, and only one member holds a meaningful value at a time.

C
#include <stdio.h>

union Value {
    int i;
    float f;
    char c;
};

int main(void) {
    union Value v;
    printf("sizeof(union Value) = %zu\n", sizeof(v));
    v.i = 65;
    printf("as int: %d, as char: %c\n", v.i, v.c);   // same bytes, read as a char
    v.f = 3.5f;                                       // overwrites the int
    printf("as float: %.1f\n", v.f);
    return 0;
}
Output
sizeof(union Value) = 4
as int: 65, as char: A
as float: 3.5
Structure Union
Each member has its own memory All members share one memory location
Size ≥ sum of member sizes Size = largest member (plus padding)
All members usable at once Only the last written member is valid

Enumerations

An enum gives names to integer constants, which makes code self-explanatory:

C
#include <stdio.h>

enum Day { MON = 1, TUE, WED, THU, FRI, SAT, SUN };   // TUE = 2, WED = 3 ...

int main(void) {
    enum Day today = FRI;
    printf("Friday is day %d\n", today);
    if (today == SAT || today == SUN) printf("Weekend!\n");
    else printf("%d day(s) to the weekend\n", SAT - today);
    return 0;
}
Output
Friday is day 5
1 day(s) to the weekend

Test yourself

4 questions · pick an answer to check it instantly

  1. 1

    Given struct Student *p;, how do you access the roll member?

  2. 2

    What is the size of union { int i; double d; char c; } on a typical 64-bit machine?

  3. 3

    Why might sizeof(struct { char a; int b; }) be 8 instead of 5?

  4. 4

    In enum Color { RED, GREEN = 5, BLUE }; what is BLUE?