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
- Missing
struct: If onlyPoint p;is used, a compilation error occurs when typedef is not used. → Habit of usingtypedefin definitions. - Structure comparison:
if (p1 == p2)is a compilation error. Comparison must be made between members. - Passing large structure values: Copy the entire structure on each call → Pointer passing is recommended.
- Use
.for pointer:ptr.xis an error.ptr->xor(*ptr).x. - 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
typedefimproves 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
ex04tobirthdaytovoid birthday(Person p)(passing by value)?