C Language track

Lesson 11 · Level 3: Advanced

Structs

User-defined types and memory layout

Level 3: Advanced4 min readFree lesson

A structure is a tool that groups several related values into one data type. A bundle such as "name is string, age is int, score is double" is treated as one variable.

Learning Objectives

  • Define a new data type as struct.
  • Increase usability by assigning an alias to typedef.
  • Use the -> operator on the structure pointer.
  • Manage a collection of records using a structure array.

Why do you need a structure? — Problem with scattered variables

If you create student information as a separate variable:

char  s1_name[32]; int s1_age; double s1_score;
char  s2_name[32]; int s2_age; double s2_score;
/*... What if there are 100 students?*/

Even if they are grouped into an array, if the data types are different, they cannot be stored in one array. A structure groups members of different data types into a group.

typedef struct {
    char name[32];
    int  age;
    double score;
} Student;

Student arr[100];   //100 students in one arrangement

Key concepts

1) Definition and initialization

struct Point {
    int x;
    int y;
};

struct Point p1 = {3, 4};
struct Point p2 = {.x = 1, .y = 2};   //Directed initialization (C99)

2) Clean with typedef

typedef struct {
    double x;
    double y;
} Point;

Point p = {10, 20};   //Use without struct keyword

3) Member access — . vs ->

Point p = {3, 4};
Point *ptr = &p;

p.x;        //Dot (.) operator: accessing members in structure variables
ptr->x;     //Arrow (->): Accessing members from pointers. Shortened version of (*ptr).x
p (value) ptr (pointer)
   ┌──────┐             ┌──────┐
   │ x: 3 │  ◄─────────│ &p   │
   │ y: 4 │             └──────┘
   └──────┘
   p.x = 3              ptr->x = 3

4) Structure array

typedef struct { char name[32]; int score; } Student;
Student class_[3] = {
    {"Kim", 90}, {"Lee", 85}, {"Park", 78},
};
class_[1].score;   // 85

Each element is an independent structure. Member access is arr[i].member.

5) Structures and functions

If you pass a large structure by value, it will be copied in its entirety, making it inefficient. Passing by pointer is idiomatic:

void birthday(Person *p) { p->age++; }
birthday(&someone);

See as example

Example 1 — ex01_basic.c: Point structure

struct Point p1 = {3, 4};
struct Point p2 = {.x = 1, .y = 2};
p1.x = 10;

Execution result

p1 = (3, 4)
p2 = (1, 2)
After changing p1.x = (10, 4)

Bottom line: Members can be read and written like regular variables.

Example 2 — ex02_typedef.c: Distance between two points

typedef struct { double x, y; } Point;
double distance(Point a, Point b) {
    return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}

Execution result

Distance: 5.00

Key point: The structure can be written as is (passed by value) as function Argument/return-value.

Example 3 — ex03_struct_array.c: Student roster average

Student class_[] = {
    {"Kim",  90}, {"Lee",  85}, {"Park", 78}, {"Choi", 92},
};

Execution result

Kim    : 90
Lee    : 85
Park   : 78
Choi   : 92
Average: 86.25

Key point: Struct array + loop is the start of a small database.

Example 4 — ex04_pointer.c: Modifying member by pointer

typedef struct { char name[32]; int age; } Person;
void birthday(Person *p) { p->age += 1; }

Execution result

Before birthday: Hong Gil-dong, 20 years old
Birthday after: Hong Gil-dong, 21 years old

Bottom line: If a function wants to change the caller's structure, it must pass a pointer.

A different perspective — the “resume” analogy

┌──────── Resume (struct Person) ────────┐
│ Name: Hong Gil-dong │
│ Age: 21 │
│ Height: 175.5 │
│ Student ID photo (...) │
   └─────────────────────────────────────┘

One resume is for one person (one Person structure). “100 resumes = 100 Person arrays”.

. vs -> actually does the same thing.

ptr->x   ≡   (*ptr).x      //completely equivalent

Common Mistakes

  1. Missing struct: If only Point p; is used, a compilation error occurs when typedef is not used. → Habit of using typedef in definitions.
  2. Structure comparison: if (p1 == p2) is a compilation error. Comparison must be made between members.
  3. Passing large structure values: Copy the entire structure on each call → Pointer passing is recommended.
  4. Use . for pointer: ptr.x is an error. ptr->x or (*ptr).x.
  5. Padding: sizeof(Student) may be larger than the member sum (due to memory alignment).

Cleanup

  • A structure groups members of different data types into one data type.
  • Creating an alias as typedef improves usability.
  • Access members using . as a structure variable and -> as a pointer.
  • Avoid copying large structures by passing them to functions as pointers.
  • Structure arrays are a natural representation of small databases.

Try it yourself

cd src
gcc -std=c11 -Wall -o ex01 ex01_basic.c        && ./ex01
gcc -std=c11 -Wall -o ex02 ex02_typedef.c -lm  && ./ex02
gcc -std=c11 -Wall -o ex03 ex03_struct_array.c && ./ex03
gcc -std=c11 -Wall -o ex04 ex04_pointer.c      && ./ex04

Application:

  • Print the name of the student with the highest average in ex03.
  • How will the result change if I change ex04 to birthday to void birthday(Person p) (passing by value)?

Example files

The runnable files used in this lesson. Copy them into your own project and experiment.

src/ex01_basic.cC
#include <stdio.h>

struct Point {
    int x;
    int y;
};

int main(void) {
    struct Point p1 = {3, 4};
    struct Point p2 = {.x = 1, .y = 2};

    printf("p1 = (%d, %d)\n", p1.x, p1.y);
    printf("p2 = (%d, %d)\n", p2.x, p2.y);

    p1.x = 10;
    printf("After changing p1.x = (%d, %d)\n", p1.x, p1.y);
    return 0;
}
src/ex02_typedef.cC
#include <stdio.h>
#include <math.h>

typedef struct {
    double x;
    double y;
} Point;

double distance(Point a, Point b) {
    double dx = a.x - b.x;
    double dy = a.y - b.y;
    return sqrt(dx * dx + dy * dy);
}

int main(void) {
    Point p = {0, 0};
    Point q = {3, 4};

    printf("Distance: %.2f\n", distance(p, q));   /* 5.00 */
    return 0;
}
src/ex03_struct_array.cC
#include <stdio.h>

typedef struct {
    char name[32];
    int  score;
} Student;

int main(void) {
    Student class_[] = {
        {"Kim",  90},
        {"Lee",  85},
        {"Park", 78},
        {"Choi", 92},
    };
    int n = (int)(sizeof(class_) / sizeof(class_[0]));

    int sum = 0;
    for (int i = 0; i < n; i++) {
        printf("%-6s : %d\n", class_[i].name, class_[i].score);
        sum += class_[i].score;
    }
    printf("Average: %.2f\n", (double)sum / n);
    return 0;
}
src/ex04_pointer.cC
#include <stdio.h>

typedef struct {
    char name[32];
    int  age;
} Person;

void birthday(Person *p) {
    p->age += 1;       /*Access members with arrows*/
}

int main(void) {
    Person p = {"Hong Gil-dong", 20};

    printf("Before birthday: %s, %d years old\n", p.name, p.age);
    birthday(&p);
    printf("After birthday: %s, %d years old\n", p.name, p.age);
    return 0;
}

Assignment

Problem 1

Define the 2D vector structure Vec2 { double x, y; } and Implement Vec2 add(Vec2 a, Vec2 b) and double dot(Vec2 a, Vec2 b) functions Print an example of usage.

  • File name: hw01.c

Problem 2

Create a student list (name, Korean, English, math) for 5 students, Print the average of each student, then print the name of the student with the highest average.

  • File name: hw02.c

Problem 3

About rectangular structure Rect { int w, h; } Implement int area(const Rect *r), int perimeter(const Rect *r). Practice using struct pointers.

  • File name: hw03.c
Show the reference solution

Try the assignment yourself first — comparing your attempt with a working solution is where most of the learning happens.

hw01.cC
#include <stdio.h>

typedef struct {
    double x;
    double y;
} Vec2;

Vec2 add(Vec2 a, Vec2 b) {
    Vec2 r = {a.x + b.x, a.y + b.y};
    return r;
}

double dot(Vec2 a, Vec2 b) {
    return a.x * b.x + a.y * b.y;
}

int main(void) {
    Vec2 a = {1, 2}, b = {3, 4};
    Vec2 c = add(a, b);

    printf("a + b = (%.1f, %.1f)\n", c.x, c.y);
    printf("a . b = %.1f\n", dot(a, b));
    return 0;
}
hw02.cC
#include <stdio.h>

typedef struct {
    char name[32];
    int kor, eng, math;
} Student;

int main(void) {
    Student arr[5] = {
        {"Kim",  90, 85, 92},
        {"Lee",  78, 88, 70},
        {"Park", 95, 91, 89},
        {"Choi", 60, 70, 65},
        {"Han",  88, 76, 82},
    };

    int top_idx = 0;
    double top_avg = 0;

    for (int i = 0; i < 5; i++) {
        double avg = (arr[i].kor + arr[i].eng + arr[i].math) / 3.0;
        printf("%-6s average %.2f\n", arr[i].name, avg);
        if (avg > top_avg) { top_avg = avg; top_idx = i; }
    }

    printf("\nHighest average: %s (%.2f)\n", arr[top_idx].name, top_avg);
    return 0;
}
hw03.cC
#include <stdio.h>

typedef struct {
    int w;
    int h;
} Rect;

int area(const Rect *r)      { return r->w * r->h; }
int perimeter(const Rect *r) { return 2 * (r->w + r->h); }

int main(void) {
    Rect r = {5, 3};
    printf("Area: %d\n", area(&r));
    printf("Perimeter: %d\n", perimeter(&r));
    return 0;
}

Learn this lesson with a mentor

Work through the C Language track on your own, or join a guided cohort at our Pitampura campus and online.

Call NowEnroll Now