Menu
CoddyTech

Con trỏ 'Self'

Thuộc phần Lập trình hướng đối tượng trong hành trình C của Coddy. Bài học 7 trên 61.

Trong các ngôn ngữ hướng đối tượng như Python hoặc Java, khi bạn gọi object.method(), ngôn ngữ sẽ tự động truyền chính đối tượng đó vào phương thức. Trong C, bạn phải tự làm việc này bằng cách truyền con trỏ đến struct làm đối số đầu tiên.

Con trỏ này thường được đặt tên là self (mượn từ Python) hoặc this (từ C++). Nó giúp hàm truy cập dữ liệu của struct để đọc hoặc chỉnh sửa dữ liệu đó:

typedef struct {
    int health;
} Player;

void player_take_damage(Player *self, int amount) {
    self->health -= amount;
}

Con trỏ self giúp hàm hoạt động như một phương thức. Nó biết cần chỉnh sửa người chơi nào. Nếu không có nó, hàm sẽ không có cách nào truy cập vào thực thể cụ thể của cấu trúc. Khi gọi hàm này, bạn truyền địa chỉ của cấu trúc:

Player hero = {100};
player_take_damage(&hero, 25);
// hero.health hiện là 75

Dùng con trỏ thay vì truyền trực tiếp struct là điều cần thiết để chỉnh sửa. Nếu bạn truyền struct theo giá trị, hàm sẽ nhận một bản sao và mọi thay đổi sẽ mất khi hàm trả về. Con trỏ đảm bảo các thay đổi vẫn được giữ lại trong struct ban đầu.

challenge icon

Thử thách

Dễ

Hãy tạo một module Timer để theo dõi số giây đã trôi qua. Bạn sẽ luyện tập cách dùng mẫu con trỏ "self" để thay đổi trạng thái bên trong của một struct thông qua các hàm hoạt động như phương thức.

Bạn sẽ tạo ba tệp:

  • timer.h: Khai báo một struct Timer có một thành viên duy nhất là int seconds. Đồng thời khai báo hai hàm: timer_tick (nhận con trỏ đến Timer và cộng thêm số giây được chỉ định) và timer_reset (nhận con trỏ đến Timer và đặt seconds về 0). Dùng include guard với ký hiệu TIMER_H.
  • timer.c: Triển khai cả hai hàm. Hàm timer_tick nhận Timer *self và int amount, sau đó cộng amount vào số giây của timer. Hàm timer_reset nhận Timer *self và đặt số giây của nó về 0.
  • main.c: Tạo một Timer, thực hiện các thao tác trên đó và hiển thị kết quả.

Bạn sẽ nhận được hai đầu vào số nguyên: số giây ban đầu của timer và số giây cần cộng thêm bằng tick.

Trong tệp main:

  1. Khởi tạo một Timer với giá trị số giây ban đầu
  2. Gọi timer_tick để cộng thêm số giây đã chỉ định
  3. In ra số giây hiện tại
  4. Gọi timer_reset để đặt lại timer
  5. In ra số giây một lần nữa (phải là 0)

In kết quả theo định dạng sau:

After tick: {seconds}
After reset: {seconds}

Ví dụ, với giá trị ban đầu là 30 và cộng thêm 15 giây, đầu ra sẽ là:

After tick: 45
After reset: 0

Tự làm thử

#include <stdio.h>
#include "timer.h"

int main() {
    int initial_seconds, amount_to_add;
    scanf("%d", &initial_seconds);
    scanf("%d", &amount_to_add);
    
    // TODO: Tạo một Timer và khởi tạo bằng initial_seconds
    
    // TODO: Gọi timer_tick để cộng thêm amount_to_add giây
    
    // TODO: In số giây hiện tại theo định dạng: "After tick: {seconds}"
    
    // TODO: Gọi timer_reset để đặt lại bộ đếm thời gian
    
    // TODO: In lại số giây theo định dạng: "After reset: {seconds}"
    
    return 0;
}
quiz iconTự kiểm tra

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 Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch C online