Bài 3.5: Bài tập thực hành kiểu dữ liệu nâng cao trong C++

Chào mừng bạn quay trở lại với chuỗi bài viết về C++ của FullhouseDev! Sau khi đã nắm vững các kiến thức cơ bản về biến, kiểu dữ liệu nguyên thủy và câu lệnh điều khiển, đã đến lúc chúng ta lặn sâu hơn vào thế giới của các kiểu dữ liệu mạnh mẽlinh hoạt hơn trong C++. Lý thuyết là quan trọng, nhưng thực hành mới là chìa khóa để biến kiến thức thành kỹ năng.

Bài viết này sẽ tập trung vào việc thực hành với một số kiểu dữ liệu "nâng cao" (so với kiểu nguyên thủy) thường gặp: mảng (arrays), chuỗi ký tự (string), cấu trúc (struct) và một giới thiệu ngắn gọn về vector (vector). Chúng ta sẽ đi qua từng phần với các ví dụ code C++ ngắn gọn, dễ hiểucó giải thích để bạn có thể bắt tay vào code ngay lập tức!


1. Làm Quen Với Mảng (Arrays) - Tập Hợp Cùng Loại

Mảng là một tập hợp các phần tử có cùng kiểu dữ liệu, được lưu trữ liền kề trong bộ nhớ. Chúng ta sử dụng mảng khi muốn xử lý một nhóm dữ liệu cùng loại một cách có tổ chức. Kích thước của mảng thường được xác định tại thời điểm biên dịch.

Hãy tưởng tượng bạn muốn lưu trữ điểm của 5 môn học. Thay vì tạo 5 biến riêng lẻ (diemMon1, diemMon2, ...), bạn có thể dùng một mảng:

#include <iostream>

int main() {
    // Khai báo một mảng số nguyên tên 'diem' có kích thước 5
    // Các phần tử được đánh số từ 0 đến 4
    int diem[5]; 

    // Gán giá trị cho các phần tử của mảng
    diem[0] = 90; // Điểm môn 1 (vị trí 0)
    diem[1] = 85; // Điểm môn 2 (vị trí 1)
    diem[2] = 92; // Điểm môn 3 (vị trí 2)
    diem[3] = 78; // Điểm môn 4 (vị trí 3)
    diem[4] = 95; // Điểm môn 5 (vị trí 4)

    // In giá trị của một phần tử cụ thể
    cout << "Diem mon thu 3 (vi tri 2): " << diem[2] << endl; 

    // Tính tổng điểm sử dụng vòng lặp
    int tongDiem = 0;
    // Lặp qua từng phần tử từ vị trí 0 đến 4
    for (int i = 0; i < 5; ++i) {
        tongDiem += diem[i]; // Cộng giá trị của phần tử thứ i vào tongDiem
    }

    cout << "Tong diem cua 5 mon: " << tongDiem << endl;

    return 0;
}

Giải thích:

  • int diem[5];: Khai báo một mảng tên diem có 5 phần tử, mỗi phần tử là kiểu int. Các vị trí (chỉ số) của mảng bắt đầu từ 0.
  • diem[0] = 90;: Gán giá trị 90 cho phần tử đầu tiên của mảng (ở vị trí chỉ số 0).
  • cout << diem[2];: Truy cập và in giá trị của phần tử ở vị trí chỉ số 2 (là môn thứ 3).
  • Vòng lặp for: Duyệt qua tất cả các phần tử của mảng từ chỉ số 0 đến 4 để tính tổng.

Bài tập cho bạn: Thử thay đổi kích thước mảng, tính điểm trung bình, hoặc tìm điểm cao nhất/thấp nhất trong mảng điểm này nhé!


2. Sức Mạnh Của Chuỗi Ký Tự (string)

Trong C++, khi nói đến xử lý văn bản, string là lựa chọn hiện đại và linh hoạt hơn nhiều so với mảng ký tự kiểu C (như char[]). string là một lớp (class) trong Thư viện Chuẩn C++ (Standard Library), cung cấp nhiều phương thức tiện lợi.

Hãy xem cách làm việc với tên người dùng chẳng hạn:

#include <iostream>
#include <string> // Phải include thư viện string

int main() {
    // Khai báo một biến chuỗi
    string tenSinhVien;

    // Yêu cầu người dùng nhập tên
    cout << "Nhap ten sinh vien: ";
    // Sử dụng getline để đọc cả dòng, bao gồm cả khoảng trắng
    getline(cin, tenSinhVien); 

    // In tên vừa nhập
    cout << "Ten da nhap: " << tenSinhVien << endl;

    // Lấy độ dài của chuỗi
    cout << "Do dai cua ten: " << tenSinhVien.length() << " ky tu" << endl; 
    // Hoặc cout << tenSinhVien.size(); - size() và length() thường giống nhau cho string

    // Nối chuỗi (concatenation)
    string loiChao = "Xin chao, ";
    string thongBao = loiChao + tenSinhVien + "!"; // Dùng toán tử '+' để nối chuỗi
    cout << thongBao << endl;

    return 0;
}

Giải thích:

  • #include <string>: Bắt buộc phải có để sử dụng lớp string.
  • string tenSinhVien;: Khai báo một biến kiểu string.
  • getline(cin, tenSinhVien);: Đây là cách nên dùng để đọc chuỗi nhập từ bàn phím khi chuỗi có thể chứa khoảng trắng. cin >> tenSinhVien chỉ đọc đến khoảng trắng đầu tiên.
  • tenSinhVien.length(): Một phương thức của đối tượng string trả về số ký tự trong chuỗi.
  • loiChao + tenSinhVien + "!": Sử dụng toán tử + để nối các chuỗi lại với nhau, tạo thành một chuỗi mới.

Bài tập cho bạn: Hãy thử tìm xem một ký tự hoặc một từ cụ thể có tồn tại trong chuỗi tenSinhVien hay không bằng cách tìm hiểu các phương thức khác của string như find().


3. Tổ Chức Dữ Liệu Với Struct

Khi bạn có các dữ liệu liên quan nhưng thuộc các kiểu khác nhau, việc nhóm chúng lại thành một đơn vị duy nhất sẽ giúp code của bạn gọn gàngdễ quản lý hơn. Đó chính là lúc chúng ta cần đến struct (cấu trúc).

Hãy tạo một cấu trúc để lưu thông tin của một cuốn sách:

#include <iostream>
#include <string>

// Định nghĩa một cấu trúc tên Sach
struct Sach {
    string tieuDe;
    string tacGia;
    int namXuatBan;
    float giaTien;
}; // Đừng quên dấu chấm phẩy ở cuối định nghĩa struct!

int main() {
    // Khai báo một biến kiểu Sach
    Sach cuonSach1;

    // Gán giá trị cho các thành viên (member) của struct
    cuonSach1.tieuDe = "Nha Gia Kim";
    cuonSach1.tacGia = "Paulo Coelho";
    cuonSach1.namXuatBan = 1988;
    cuonSach1.giaTien = 120.50;

    // In thông tin của cuốn sách
    cout << "Thong tin sach:" << endl;
    // Truy cập các thành viên sử dụng toán tử '.'
    cout << "Tieu de: " << cuonSach1.tieuDe << endl; 
    cout << "Tac gia: " << cuonSach1.tacGia << endl;
    cout << "Nam xuat ban: " << cuonSach1.namXuatBan << endl;
    cout << "Gia tien: " << cuonSach1.giaTien << " VND" << endl;

    // Có thể khai báo và khởi tạo ngay lập tức
    Sach cuonSach2 = {"Hoang Tu Be", "Antoine de Saint-Exupéry", 1943, 95.00};

    cout << "\nThong tin sach thu 2:" << endl;
    cout << "Tieu de: " << cuonSach2.tieuDe << endl;

    return 0;
}

Giải thích:

  • struct Sach { ... };: Định nghĩa một kiểu dữ liệu mới tên là Sach. Kiểu dữ liệu này chứa các thành viên (tieuDe, tacGia, namXuatBan, giaTien) với các kiểu dữ liệu khác nhau. Dấu chấm phẩy ; sau dấu ngoặc nhọn đóng } là bắt buộc.
  • Sach cuonSach1;: Khai báo một biến (hay còn gọi là đối tượng) có kiểu Sach.
  • cuonSach1.tieuDe = "Nha Gia Kim";: Sử dụng toán tử chấm (.) để truy cập và gán giá trị cho thành viên tieuDe của đối tượng cuonSach1.
  • Sach cuonSach2 = { ... };: Cách khởi tạo nhanh một đối tượng struct bằng cách liệt kê giá trị cho các thành viên theo thứ tự định nghĩa.

Bài tập cho bạn: Tạo một struct để lưu thông tin sinh viên (Mã số, Tên, Tuổi, Điểm trung bình) và thử tạo 2-3 sinh viên khác nhau.


4. Giới Thiệu Sơ Lược Về Vector (vector) - Mảng Linh Hoạt

Mảng cố định có nhược điểm là kích thước không thể thay đổi sau khi được tạo. vector, một kiểu dữ liệu container khác từ STL, giải quyết vấn đề này. vector là một mảng động, có thể tự động co giãn kích thước khi bạn thêm hoặc bớt phần tử.

Đây là một ví dụ đơn giản về cách sử dụng vector:

#include <iostream>
#include <vector> // Phải include thư viện vector

int main() {
    // Khai báo một vector chứa các số nguyên
    vector<int> danhSachSo; 

    // Thêm phần tử vào cuối vector
    danhSachSo.push_back(10); // Vector có 1 phần tử: {10}
    danhSachSo.push_back(25); // Vector có 2 phần tử: {10, 25}
    danhSachSo.push_back(5);  // Vector có 3 phần tử: {10, 25, 5}

    // Kích thước vector hiện tại
    cout << "Kich thuoc vector: " << danhSachSo.size() << endl; // Dùng size()

    // Truy cập các phần tử (giống mảng, dùng chỉ số)
    cout << "Phan tu dau tien: " << danhSachSo[0] << endl; // Truy cập phần tử ở chỉ số 0

    // Duyệt qua tất cả các phần tử trong vector
    cout << "Cac phan tu trong vector: ";
    for (int i = 0; i < danhSachSo.size(); ++i) {
        cout << danhSachSo[i] << " ";
    }
    cout << endl;

    // Thêm một phần tử nữa
    danhSachSo.push_back(30); // Vector bây giờ có 4 phần tử

    // Kích thước vector sau khi thêm
    cout << "Kich thuoc vector sau khi them: " << danhSachSo.size() << endl;

    return 0;
}

Giải thích:

  • #include <vector>: Cần thiết để sử dụng vector.
  • vector<int> danhSachSo;: Khai báo một vector có thể chứa các phần tử kiểu int. <int> bên trong dấu ngoặc nhọn <> chỉ định kiểu dữ liệu mà vector này sẽ lưu trữ.
  • danhSachSo.push_back(10);: Phương thức push_back() được dùng để thêm một phần tử mới vào cuối vector. Vector sẽ tự động tăng kích thước nếu cần.
  • danhSachSo.size(): Trả về số lượng phần tử hiện có trong vector.
  • danhSachSo[i]: Truy cập phần tử tại chỉ số i, tương tự như mảng cố định.

Bài tập cho bạn: Thử tạo một vector chứa các đối tượng Sach mà bạn đã định nghĩa ở mục 3. Thêm 2-3 cuốn sách vào vector đó và duyệt qua vector để in thông tin của từng cuốn sách.

Comments

There are no comments at the moment.