Structures
A struct is like a custom form — it packages different types of information (name, age, grade) together into a single unit you can manage as a whole.
struct Definition and Declaration
Defining a Struct Type
struct Student {
char name[20];
int age;
float score;
};
This defines a type struct Student. Note that the trailing semicolon is required.
Declaring Struct Variables
struct Student s1;
struct Student s2, s3;
You can also declare variables at the same time as defining the type:
struct Point {
int x;
int y;
} p1, p2;
Anonymous Struct
If you only need it once, you can omit the type name:
struct {
int width;
int height;
} box;
Struct Variable Initialization
Sequential Initialization
struct Student s1 = {"Zhang", 20, 89.5};
Designated Initializer (C99)
struct Student s2 = {.name = "Li", .score = 92.0, .age = 21};
Partial Initialization
struct Student s3 = {"Wang"};
name is initialized; the remaining members are automatically set to 0.
Member Access
Dot Operator .
Access members through a struct variable:
struct Student s = {"Zhao", 19, 78.5};
printf("Name: %s\n", s.name);
printf("Age: %d\n", s.age);
s.score = 85.0;
Arrow Operator ->
Access members through a struct pointer:
struct Student s = {"Zhao", 19, 78.5};
struct Student *ps = &s;
printf("Name: %s\n", ps->name);
ps->age = 20;
ps->name is equivalent to (*ps).name. The -> operator is syntactic sugar — more concise when working with pointers.
Example
#include <stdio.h>
struct Book {
char title[50];
char author[30];
float price;
};
int main(void) {
struct Book b1 = {.title = "The C Programming Language", .author = "K&R", .price = 45.0};
struct Book *pb = &b1;
printf("Title: %s\n", pb->title);
printf("Author: %s\n", pb->author);
printf("Price: %.1f\n", pb->price);
pb->price = 55.0;
printf("After discount: %.1f\n", b1.price);
return 0;
}
Title: The C Programming Language
Author: K&R
Price: 45.0
After discount: 55.0
Struct Array
Place multiple structs in an array for unified management.
struct Student class[3] = {
{"Zhang", 20, 89.5},
{"Li", 21, 92.0},
{"Wang", 19, 78.0}
};
for (int i = 0; i < 3; i++) {
printf("%s %d %.1f\n", class[i].name, class[i].age, class[i].score);
}
Zhang 20 89.5
Li 21 92.0
Wang 19 78.0
Traverse a struct array with a pointer:
struct Student *p = class;
for (int i = 0; i < 3; i++, p++) {
printf("%s %.1f\n", p->name, p->score);
}
Struct Pointer
The most common use of struct pointers: avoid copying the entire struct when passing it between functions.
void print_student(struct Student *ps) {
printf("%s, age %d, score %.1f\n", ps->name, ps->age, ps->score);
}
int main(void) {
struct Student s = {"Zhang", 20, 89.5};
print_student(&s);
return 0;
}
Zhang, age 20, score 89.5
Struct as Function Parameter
Pass by Value
void add_score(struct Student s, float bonus) {
s.score += bonus;
}
Pass by Pointer
void add_score(struct Student *s, float bonus) {
s->score += bonus;
}
Modifications through the pointer inside the function directly affect the original variable.
Example
#include <stdio.h>
struct Score {
char name[20];
int chinese;
int math;
int english;
};
int total(struct Score *s) {
return s->chinese + s->math + s->english;
}
void boost(struct Score *s, int bonus) {
s->chinese += bonus;
s->math += bonus;
s->english += bonus;
}
int main(void) {
struct Score stu = {.name = "Zhou", .chinese = 80, .math = 75, .english = 88};
printf("Original total: %d\n", total(&stu));
boost(&stu, 5);
printf("After bonus: %d\n", total(&stu));
return 0;
}
Original total: 243
After bonus: 258
Struct Assignment and Comparison
Assignment
Structs of the same type can be directly assigned — members are copied one by one:
struct Student s1 = {"Zhang", 20, 89.5};
struct Student s2;
s2 = s1;
Comparison
== or !=. You must compare members individually:
int equal(struct Student *a, struct Student *b) {
return a->age == b->age && a->score == b->score;
}
Nested Structs
A struct member can itself be another struct:
struct Date {
int year;
int month;
int day;
};
struct Employee {
char name[20];
struct Date birthday;
float salary;
};
struct Employee e = {"Chen", {1995, 6, 15}, 8000.0};
printf("Birthday: %d-%02d-%02d\n", e.birthday.year, e.birthday.month, e.birthday.day);
Birthday: 1995-06-15
❓ FAQ
. and ->?. accesses members through a struct variable; -> accesses members through a struct pointer. p->name is equivalent to (*p).name.==?== comparison for structs. You must compare members individually or use memcmp (but beware of padding bytes).const struct Student *s.📖 Summary
structpackages members of different types into a custom type- Initialization can use sequential values or C99 designated initializers
.name = ... - Use
.to access members through a variable,->through a pointer - Struct arrays allow batch management of same-type data
- Prefer passing struct pointers as function parameters to avoid copy overhead
- Structs can be nested — a member can itself be a struct
📝 Exercises
- Define
struct Rectanglewith width and height. Write functionsfloat area(struct Rectangle *r)andfloat perimeter(struct Rectangle *r), then calculate and print the results in main - Define
struct Dateand write a functionint date_compare(struct Date *a, struct Date *b)that returns -1/0/1 indicating whether a is earlier than / equal to / later than b - Define a student struct array (5 students), sort by score from highest to lowest, and print the results



