Search…

Struct Trong Lập Trình C Và Tư Duy Trừu Tượng Hoá

19/09/20204 min read
Ứng dụng và tư duy trừa tượng hoá của struct trong lập trình C/C++.

Đặt vấn đề

Giả sử STDIO tổ chức lưu trữ thông tin của các tác giả bằng ngôn ngữ C và có hơn 50 account được cấp quyền author (Gọi tắt là M).

Mỗi author cần lưu trữ một số thông tin, cụ thể như sau:

  • Name.
  • Job.
  • Phone number.
  • Articles (Danh sách bài viết của tác giả đó).
  • About.
  • ...

Theo thông thường, tạo ra các mảng tương ứng: char* name[M], char* job[M], long phone_number[M], char* articles[M], char* about[M], ...

Giả sử STDIO manager quản lý các author, muốn cập nhật thông tin cho một author, có prototype của hàm như sau:

void UpdateAuthorInfo(
char* &name, char* &job, long &phone_number, char* &articles, char* &about);

Vấn đề trở nên phức tạp khi STDIO quyết định bổ sung một vài thông tin cho author. Khi đó, không phải chỉ khai báo thêm các biến, mà các hàm liên quan cũng cần thay đổi theo, dễ xảy ra tình trạng sơ sót khi hệ thống ngày càng lớn.

Để giải quyết vấn đề đó, STDIO quyết định nâng cấp hệ thống bằng cách sử dụng struct, gom nhóm các thông tin kể trên và biểu diễn thành một đối tượng duy nhất - SAuthor (Cách thức gom nhóm sẽ được trình bày ở phần dưới). Lúc này các mảng lưu trữ thông tin ở trên sẽ được thay bằng một mảng duy nhất: SAuthor* authors[M]. Khi đó, hàm UpdateAuthorInfo được tối giản lại như sau:

void UpdateAuthorInfo(SAuthor* &author);

Mỗi đối tượng SAuthor đại diện cho một author, lưu trữ tất cả thông tin trong cùng một cấu trúc dữ liệu. Khi cần cập nhật thêm tính năng, STDIO manager sẽ khai báo thêm thành phần bên trong cấu trúc SAuthor và xử lý thêm tại các hàm liên quan.

Ở ví dụ nói trên, làm rõ luận điểm: Sử dụng struct để trừu tượng hoá các thông tin có liên quan với nhau thành một đối tượng duy nhất. Mặt khác, struct sau khi được định nghĩa có thể sử dụng như bất cứ kiểu dữ liệu thông thường nào, do đó Lập trình viên dễ dàng tiếp cận với struct như với các kiểu dữ liệu cơ bản.

Khai báo và sử dụng

Để khai báo một struct, sử dụng cú pháp như sau:

struct SExample
{
	<data_type>		m_variable;
	// ...
};

Lưu ý dấu chấm phẩy ; sau khi khai báo struct là bắt buộc. Các thành phần của struct được khai báo giống với một biến bình thường, cách nhau bởi dấu chấm phẩy. Các thành phần này có thể được truy cập thông qua các toán tử . hay -> (tương ứng với khai báo bình thường và khai báo kiểu con trỏ).

Như vậy, với ví dụ ở phần Đặt vấn đề, STDIO manager có thể lập trình cấu trúc SAuthor như sau:

struct SAuthor
{
	char* 		m_name;
	char*		m_job;
	long        m_phoneNumber;
	char*		m_articles;
	char*		m_about;
	// ...
};

Một struct có thể chứa struct khác như một thành phần của nó. Như vậy, có thể sử dụng liên tục các toán tử . hoặc -> để truy xuất đến thành phần của các thành phần (struct) này.

Tiền tố S trong SExamplem_ trong m_variable ở ví dụ trên có thể được loại bỏ. Tuy nhiên, với STDIO các tiền tố này nên được sử dụng để phân biệt với các cấu trúc và kiểu dữ liệu khác. Có thể tham khảo thêm bài viết STDIO Coding Convention để xây dựng quy tắc riêng cho mình.

Sau khi khai báo, struct có thể được đặt lại tên khác bằng từ khoá typedef. Có thể xem thêm bài viết typedef Và enum.

Ứng dụng struct

Ngày nay, cùng với sự phát triển của ngôn ngữ C++ thì struct vẫn được lập trình viên sử dụng trong nhiều trường hợp.

Biểu diễn Hình chữ nhật. Để biểu diễn một hình chữ nhật, cần chiều dài và chiều rộng, cùng với một điểm xác định "vị trí" của hình (thường là toạ độ của điểm top-left). Nếu hình chữ nhật này chỉ được sử dụng 1 lần, ví dụ trong trường hợp khởi tạo một cửa sổ Windows, có thể bỏ qua khái niệm struct. Tuy nhiên nếu việc sử dụng được lặp đi lặp lại thì một cách tự nhiên, có khai báo struct như sau:

struct SRectangle
{
	float x, y;
	float width, height;
};

Ngoài ra, có thể khai báo kết hợp để tạo ra cấu trúc SRectangle như sau:

struct SVector2
{
	float x, y;
};

struct SRectangle
{
	struct SVector2		m_topLeft;
	float 				width, height;
};

Biểu diễn Sin (project Sins):

struct Sin
{
	struct Sprite*		m_sin;
	struct SColor3B		m_color;
	
	struct Sprite*		m_darkForce;
	bool			    m_isSealed;
	
	struct Animate*		m_effect;
};
IO Stream

IO Stream Co., Ltd

30 Trinh Dinh Thao, Hoa Thanh ward, Tan Phu district, Ho Chi Minh city, Vietnam
+84 28 22 00 11 12
developer@iostream.co

383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024