Menu
CoddyTech

Ôn tập: mảng tổng quát

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 53 trên 61.

challenge icon

Thử thách

Dễ

Hãy xây dựng một vùng chứa GenericArray: một cấu trúc dữ liệu linh hoạt có thể chứa cả số nguyên và chuỗi trong cùng một tập hợp bằng cách sử dụng con trỏ void*.

Bạn sẽ sắp xếp code trong ba tệp:

  • generic_array.h: Định nghĩa struct GenericArray với ba thành viên: một mảng void** để chứa các con trỏ, một int để lưu số lượng hiện tại và một int để lưu sức chứa. Khai báo nguyên mẫu các hàm để tạo mảng, thêm phần tử, lấy phần tử theo chỉ số và giải phóng mảng.
  • generic_array.c: Triển khai chức năng của vùng chứa:
    • create_array: cấp phát một GenericArray với sức chứa ban đầu đã cho và khởi tạo count bằng 0
    • add_element: lưu một con trỏ void* vào vị trí còn trống tiếp theo và tăng count (giả sử sức chứa đủ lớn)
    • get_element: trả về void* tại chỉ số được chỉ định
    • free_array: giải phóng mảng items và chính struct GenericArray
  • main.c: Minh họa cách dùng mảng tổng quát bằng cách lưu cả số nguyên và chuỗi. Đọc số phần tử cần thêm, sau đó đọc ký hiệu kiểu dữ liệu (i cho số nguyên, s cho chuỗi), theo sau là giá trị của từng phần tử. Sau khi thêm tất cả phần tử, duyệt qua mảng và in ra từng giá trị. Với số nguyên, in trực tiếp số đó. Với chuỗi, in trực tiếp văn bản.

Chương trình của bạn sẽ nhận:

  1. Số phần tử cần thêm
  2. Với mỗi phần tử: một ký hiệu kiểu dữ liệu (i hoặc s), theo sau là giá trị

Khi thêm số nguyên, hãy cấp phát bộ nhớ cho int và lưu con trỏ. Khi thêm chuỗi, hãy cấp phát bộ nhớ và sao chép chuỗi. Khi lấy phần tử, ép kiểu về kiểu dữ liệu phù hợp để in ra.

Quan trọng: Để theo dõi kiểu dữ liệu khi in, bạn có thể dùng một mảng song song đơn giản chứa các ký hiệu kiểu dữ liệu trong main, hoặc lưu ký tự ký hiệu kiểu dữ liệu bên cạnh từng phần tử.

Ví dụ đầu ra khi đầu vào là 3, tiếp theo là i 42, s Hello, i 100:

42
Hello
100

Ví dụ đầu ra khi đầu vào là 4, tiếp theo là s World, s Generic, i -5, s Arrays:

World
Generic
-5
Arrays

Nhớ dùng include guard trong tệp header. Bản thân vùng chứa không cần biết nó lưu những kiểu dữ liệu nào. Nó chỉ chứa các con trỏ void*. Code thêm và lấy phần tử chịu trách nhiệm biết kiểu dữ liệu.

Tự làm thử

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "generic_array.h"

int main() {
    int n;
    scanf("%d", &n);
    
    // TODO: Tạo một GenericArray có sức chứa n
    
    // TODO: Tạo một mảng song song để theo dõi kiểu dữ liệu (mảng char kích thước n)
    
    // TODO: Với mỗi phần tử:
    // - Đọc ký hiệu chỉ kiểu dữ liệu (i hoặc s)
    // - Đọc giá trị
    // - Nếu là số nguyên: cấp phát bộ nhớ cho int, lưu giá trị rồi thêm vào mảng
    // - Nếu là chuỗi: cấp phát bộ nhớ cho chuỗi, sao chép giá trị rồi thêm vào mảng
    // - Lưu ký hiệu chỉ kiểu dữ liệu vào mảng song song
    
    // TODO: Duyệt mảng và in ra từng phần tử
    // - Kiểm tra kiểu dữ liệu trong mảng song song
    // - Ép void* về kiểu phù hợp rồi in ra
    
    // TODO: Giải phóng toàn bộ bộ nhớ đã cấp phát (số nguyên, chuỗi và mảng)
    
    return 0;
}

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