Truyền cấu trúc theo giá trị
Thuộc phần Logic và luồng điều khiển trong hành trình C của Coddy. Bài học 46 trên 63.
Bây giờ bạn đã biết cách làm việc với struct và con trỏ đến struct, đã đến lúc học cách truyền toàn bộ struct vào hàm. Khi truyền struct vào hàm dưới dạng tham số, C sử dụng cơ chế truyền theo giá trị, nghĩa là hàm nhận được một bản sao hoàn chỉnh của struct.
Đây là cú pháp của một hàm (function) nhận tham số (parameter) kiểu struct:
void functionName(struct StructureName parameterName) {
// Thân hàm
}Lấy struct Point quen thuộc làm ví dụ:
void printPoint(struct Point p) {
printf("Point coordinates: (%d, %d)\n", p.x, p.y);
}Điều quan trọng cần hiểu là mọi thay đổi bạn thực hiện với struct bên trong hàm sẽ không ảnh hưởng đến struct ban đầu trong hàm gọi. Lý do là hàm thao tác với bản sao dữ liệu riêng.
Cách này hữu ích khi bạn muốn đọc hoặc hiển thị dữ liệu struct mà không lo vô tình sửa đổi dữ liệu gốc. Tuy nhiên, hãy nhớ rằng việc sao chép các struct lớn có thể kém hiệu quả về bộ nhớ và hiệu năng.
Thử thách
DễTạo một chương trình C minh họa cách truyền cấu trúc vào hàm theo giá trị. Chương trình của bạn cần:
- Định nghĩa một
structtên làRectanglevới các thành viên sau:- Một số nguyên
widthđể lưu chiều rộng của hình chữ nhật - Một số nguyên
heightđể lưu chiều cao của hình chữ nhật - Một mảng ký tự
colorcó kích thước 15 để lưu màu của hình chữ nhật
- Một số nguyên
- Viết một hàm (function) tên là
displayRectangleđể:- Nhận một cấu trúc
Rectanglelàm tham số (truyền theo giá trị) - In thông tin hình chữ nhật theo đúng định dạng sau:
Rectangle Details:Width: [width]Height: [height]Color: [color]Area: [area]
- Tính và in diện tích (chiều rộng × chiều cao)
- Nhận một cấu trúc
- Viết một hàm tên là
modifyRectangleđể:- Nhận một cấu trúc
Rectanglelàm tham số (truyền theo giá trị) - Nhân đôi cả chiều rộng và chiều cao của hình chữ nhật
- Đổi màu thành "Modified"
- In
Inside modifyRectangle function: - Gọi
displayRectangleđể hiển thị hình chữ nhật đã chỉnh sửa
- Nhận một cấu trúc
- Trong hàm main:
- Tạo một biến
Rectangletên làrect - Đọc chiều rộng, chiều cao và màu từ đầu vào, rồi gán chúng cho các thành viên của cấu trúc
- In
Original rectangle: - Gọi
displayRectangleđể hiển thị hình chữ nhật ban đầu - Gọi
modifyRectanglevới hình chữ nhật - In
After modifyRectangle call: - Gọi lại
displayRectangleđể cho thấy hình chữ nhật ban đầu không thay đổi
- Tạo một biến
Thử thách này minh họa khái niệm quan trọng về truyền theo giá trị với cấu trúc: khi bạn truyền một cấu trúc vào hàm, hàm sẽ nhận được một bản sao đầy đủ của cấu trúc đó. Mọi thay đổi bên trong hàm chỉ ảnh hưởng đến bản sao, không ảnh hưởng đến cấu trúc ban đầu trong hàm gọi.
Tự làm thử
#include <stdio.h>
#include <string.h>
// TODO: Định nghĩa struct Rectangle tại đây
// TODO: Viết hàm (function) displayRectangle tại đây
// TODO: Viết hàm modifyRectangle tại đây
int main() {
// Đọc đầu vào
int width, height;
char color[15];
scanf("%d", &width);
scanf("%d", &height);
scanf("%s", color);
// TODO: Tạo biến Rectangle và gán các giá trị đầu vào
// TODO: In ra "Original rectangle:" và gọi displayRectangle
// TODO: Gọi modifyRectangle
// TODO: In ra "After modifyRectangle call:" và gọi lại displayRectangle
return 0;
}Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Logic và luồng điều khiển
1Nền tảng về con trỏ
Con trỏ là gì?Khai báo con trỏToán tử lấy địa chỉ (&)Toán tử giải tham chiếu (*)Con trỏ NULLÔn tập: kiến thức cơ bản về con trỏ4Dự án: Công cụ xử lý văn bản đơn giản
Tổng quan dự ánĐếm ký tự2Con trỏ và mảng
Tên mảng dưới dạng con trỏPhần tử mảng và con trỏPhép toán con trỏSo sánh con trỏÔn tập: duyệt mảng bằng con trỏ5Con trỏ và hàm
Truyền theo giá trịTruyền con trỏ vào hàmSửa đổi biến qua con trỏVí dụ kinh điển: hoán đổiTruyền mảng vào hàmÔn tập: đối số con trỏ hàm8Cấu trúc và con trỏ
Con trỏ đến cấu trúcToán tử mũi tên (->)Truyền cấu trúc theo giá trịTruyền con trỏ cấu trúcCấp phát động cho cấu trúcÔn tập: sửa đổi cấu trúc bằng con trỏ3Mảng ký tự và chuỗi
Chuỗi dưới dạng mảng charKý tự kết thúc nullNhập chuỗi bằng scanfDùng strlen()Dùng strcpy()Dùng strcat()Dùng strcmp()Ôn tập: các hàm xử lý chuỗi cơ bản6Quản lý bộ nhớ
Bộ nhớ ngăn xếp và bộ nhớ heapCấp phát động với malloc()Dùng sizeof() để cấp phátKiểm tra lỗi cấp phátGiải phóng bộ nhớ với free()Cấp phát với calloc()Ôn tập: Mảng động9Dự án: Nhập thông tin liên hệ đơn giản
Định nghĩa struct ContactHàm tạo liên hệTự luyện tập: Trình biên dịch C online