Chào bạn! Sử dụng con trỏ trong C/C++ để quản lý sinh viên là một cách tuyệt vời để hiểu về quản lý bộ nhớ động. Thay vì khai báo một mảng cố định (gây lãng phí hoặc thiếu hụt bộ nhớ), chúng ta sẽ cấp phát vùng nhớ vừa đủ cho số lượng sinh viên thực tế.
Dưới đây là một chương trình demo đơn giản, viết bằng C++, tập trung vào việc sử dụng con trỏ để quản lý danh sách sinh viên.
1. Cấu trúc chương trình
Chúng ta sẽ sử dụng một struct để định nghĩa sinh viên và một con trỏ kiểu SinhVien* để quản lý mảng động.
Cấp phát động (new): Dòng SinhVien* danhSach = new SinhVien[n]; yêu cầu hệ điều hành cấp một vùng nhớ liên tục đủ cho n sinh viên và trả về địa chỉ ô nhớ đầu tiên cho con trỏ danhSach.
Toán tử ->: Khi bạn có một con trỏ trỏ đến một struct, thay vì dùng dấu chấm . (như sv.id), bạn phải dùng -> (như sv->id) để truy cập các thuộc tính bên trong.
Pointer Arithmetic (Toán tử con trỏ): Trong hàm xuất, (ds + i) sẽ nhảy đến địa chỉ của sinh viên thứ i. Đây là bản chất của cách mảng hoạt động trong C++.
Giải phóng bộ nhớ (delete[]): Khác với biến thông thường, bộ nhớ cấp phát bởi new sẽ không tự mất đi khi hàm kết thúc. Bạn phải dùng delete[] để tránh hiện tượng rò rỉ bộ nhớ (memory leak).
SOURCE
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
// Định nghĩa cấu trúc Sinh Viên
struct SinhVien {
int id;
string hoTen;
float diemGPA;
};
// Hàm nhập thông tin 1 sinh viên dùng con trỏ
void nhapSinhVien(SinhVien* sv) {
cout << "Nhap ID: ";
cin >> sv->id;
cin.ignore(); // Xóa bộ nhớ đệm
cout << "Nhap ho ten: ";
getline(cin, sv->hoTen);
cout << "Nhap diem GPA: ";
cin >> sv->diemGPA;
}
// Hàm xuất danh sách sinh viên
void xuatDanhSach(SinhVien* ds, int n) {
cout << "\n--- DANH SACH SINH VIEN ---\n";
cout << left << setw(5) << "ID" << setw(20) << "Ho Ten" << setw(5) << "GPA" << endl;
for (int i = 0; i < n; i++) {
// Truy cập phần tử bằng pointer arithmetic: (ds + i)
cout << left << setw(5) << (ds + i)->id
<< setw(20) << (ds + i)->hoTen
<< setw(5) << (ds + i)->diemGPA << endl;
}
}
int main() {
int n;
cout << "Nhap so luong sinh vien: ";
cin >> n;
// 1. Cấp phát bộ nhớ động (Sử dụng con trỏ)
SinhVien* danhSach = new SinhVien[n];
// 2. Nhập dữ liệu
for (int i = 0; i < n; i++) {
cout << "\nNhap sinh vien thu " << i + 1 << ":" << endl;
nhapSinhVien(&danhSach[i]); // Truyền địa chỉ của phần tử thứ i
}
// 3. Xuất dữ liệu
xuatDanhSach(danhSach, n);
// 4. Giải phóng bộ nhớ (Rất quan trọng khi dùng con trỏ)
delete[] danhSach;
danhSach = nullptr;
cout << "\nDa giai phong bo nho. Ket thuc chuong trinh.";
return 0;
}
Chào bạn! Sử dụng con trỏ trong C/C++ để quản lý sinh viên là một cách tuyệt vời để hiểu về quản lý bộ nhớ động. Thay vì khai báo một mảng cố định (gây lãng phí hoặc thiếu hụt bộ nhớ), chúng ta sẽ cấp phát vùng nhớ vừa đủ cho số lượng sinh viên thực tế.
Dưới đây là một chương trình demo đơn giản, viết bằng C++, tập trung vào việc sử dụng con trỏ để quản lý danh sách sinh viên.
1. Cấu trúc chương trình
Chúng ta sẽ sử dụng một struct để định nghĩa sinh viên và một con trỏ kiểu SinhVien* để quản lý mảng động.
Cấp phát động (new): Dòng SinhVien* danhSach = new SinhVien[n]; yêu cầu hệ điều hành cấp một vùng nhớ liên tục đủ cho n sinh viên và trả về địa chỉ ô nhớ đầu tiên cho con trỏ danhSach.
Toán tử ->: Khi bạn có một con trỏ trỏ đến một struct, thay vì dùng dấu chấm . (như sv.id), bạn phải dùng -> (như sv->id) để truy cập các thuộc tính bên trong.
Pointer Arithmetic (Toán tử con trỏ): Trong hàm xuất, (ds + i) sẽ nhảy đến địa chỉ của sinh viên thứ i. Đây là bản chất của cách mảng hoạt động trong C++.
Giải phóng bộ nhớ (delete[]): Khác với biến thông thường, bộ nhớ cấp phát bởi new sẽ không tự mất đi khi hàm kết thúc. Bạn phải dùng delete[] để tránh hiện tượng rò rỉ bộ nhớ (memory leak).
SOURCE
CHÚC CÁC BẠN THÀNH CÔNG !