Skip to content

Bài 12: Giá trị trả về (Return Values)

📖 Giới thiệu

Giá trị trả về (return value) là kết quả mà hàm trả về cho nơi gọi hàm sau khi thực hiện xong nhiệm vụ. Giống như khi bạn hỏi "2 + 3 bằng bao nhiêu?", câu trả lời "5" chính là giá trị trả về.

Trong C++, hàm có thể:

  • Trả về một giá trị: Tính toán và đưa ra kết quả
  • Không trả về gì (void): Chỉ thực hiện hành động
  • Trả về sớm: Dừng thực hiện giữa chừng

Việc hiểu rõ return values giúp:

  • Tái sử dụng kết quả: Lưu và dùng lại
  • Liên kết các hàm: Kết quả hàm này làm input hàm khác
  • Kiểm tra trạng thái: Hàm báo cáo thành công/thất bại
  • Tối ưu code: Giảm thiểu việc tính toán lặp lại

🔧 Cú pháp

Hàm có giá trị trả về

cpp
// Cú pháp cơ bản
kiểu_dữ_liệu tên_hàm(tham_số) {
    // Code thực thi
    return giá_trị;
}

// Ví dụ đơn giản
int cong(int a, int b) {
    return a + b;  // Trả về tổng
}

double chia(double a, double b) {
    return a / b;  // Trả về thương
}

bool laSoChan(int n) {
    return n % 2 == 0;  // Trả về true/false
}

Hàm void (không trả về)

cpp
void xinChao() {
    cout << "Xin chào!" << endl;
    // Không có return, hoặc return; (không giá trị)
}

void inThongTin(string ten, int tuoi) {
    cout << "Tên: " << ten << ", Tuổi: " << tuoi << endl;
    return;  // Có thể có hoặc không
}

🔬 Phân tích & Giải thích

1. Return sớm (Early Return)

cpp
// Ví dụ đơn giản - kiểm tra số âm
int layGiaTriTuyetDoi(int n) {
    if (n < 0) {
        return -n;  // Return sớm nếu âm
    }
    return n;       // Return bình thường nếu dương
}

// Ví dụ phức tạp - tính điểm xếp loại
string xepLoaiHocLuc(double diem) {
    if (diem < 0 || diem > 10) {
        return "Điểm không hợp lệ";  // Return sớm
    }
    
    if (diem >= 9) return "Xuất sắc";
    if (diem >= 8) return "Giỏi"; 
    if (diem >= 6.5) return "Khá";
    if (diem >= 5) return "Trung bình";
    return "Yếu";
}

2. Return nhiều giá trị (thông qua struct/pair)

cpp
#include <utility>  // cho pair

// Sử dụng pair để trả về 2 giá trị
pair<int, int> chiaVaDu(int a, int b) {
    int thuong = a / b;
    int du = a % b;
    return make_pair(thuong, du);
}

// Sử dụng struct tự định nghĩa
struct KetQuaToan {
    int tong;
    int hieu;
    int tich;
    double thuong;
};

KetQuaToan tinhToanDayDu(int a, int b) {
    KetQuaToan kq;
    kq.tong = a + b;
    kq.hieu = a - b;
    kq.tich = a * b;
    kq.thuong = (double)a / b;
    return kq;
}

3. Return reference và const

cpp
// Trả về reference (tham chiếu)
int& layPhanTuMax(int& a, int& b) {
    return (a > b) ? a : b;  // Trả về tham chiếu
}

// Trả về const reference
const string& layTenDaiNhat(const string& ten1, const string& ten2) {
    return (ten1.length() > ten2.length()) ? ten1 : ten2;
}

💻 Ví dụ minh họa

Ví dụ 1: Máy tính đơn giản

cpp
#include <iostream>
using namespace std;

// Các hàm tính toán cơ bản
int cong(int a, int b) {
    return a + b;
}

int tru(int a, int b) {
    return a - b;
}

int nhan(int a, int b) {
    return a * b;
}

double chia(int a, int b) {
    if (b == 0) {
        cout << "Lỗi: Không thể chia cho 0!" << endl;
        return 0;  // Trả về giá trị mặc định
    }
    return (double)a / b;
}

int main() {
    int x = 10, y = 3;
    
    cout << "x = " << x << ", y = " << y << endl;
    cout << "x + y = " << cong(x, y) << endl;
    cout << "x - y = " << tru(x, y) << endl;
    cout << "x * y = " << nhan(x, y) << endl;
    cout << "x / y = " << chia(x, y) << endl;
    
    return 0;
}

Kết quả:

x = 10, y = 3
x + y = 13
x - y = 7
x * y = 30
x / y = 3.33333

Ví dụ 2: Tìm kiếm trong mảng

cpp
#include <iostream>
using namespace std;

// Tìm vị trí phần tử trong mảng
int timViTri(int arr[], int size, int giaTriCanTim) {
    for (int i = 0; i < size; i++) {
        if (arr[i] == giaTriCanTim) {
            return i;  // Trả về vị trí tìm thấy
        }
    }
    return -1;  // Trả về -1 nếu không tìm thấy
}

// Đếm số lần xuất hiện
int demSoLan(int arr[], int size, int giaTriCanDem) {
    int dem = 0;
    for (int i = 0; i < size; i++) {
        if (arr[i] == giaTriCanDem) {
            dem++;
        }
    }
    return dem;
}

// Tìm giá trị lớn nhất
int timMax(int arr[], int size) {
    if (size <= 0) {
        cout << "Mảng rỗng!" << endl;
        return 0;
    }
    
    int max = arr[0];
    for (int i = 1; i < size; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    return max;
}

int main() {
    int mang[] = {5, 2, 8, 2, 9, 1, 2};
    int kichThuoc = 7;
    
    cout << "Mảng: ";
    for (int i = 0; i < kichThuoc; i++) {
        cout << mang[i] << " ";
    }
    cout << endl;
    
    // Sử dụng các hàm
    int viTri = timViTri(mang, kichThuoc, 8);
    cout << "Vị trí của số 8: " << viTri << endl;
    
    int soLan = demSoLan(mang, kichThuoc, 2);
    cout << "Số 2 xuất hiện " << soLan << " lần" << endl;
    
    int max = timMax(mang, kichThuoc);
    cout << "Giá trị lớn nhất: " << max << endl;
    
    return 0;
}

Kết quả:

Mảng: 5 2 8 2 9 1 2 
Vị trí của số 8: 2
Số 2 xuất hiện 3 lần
Giá trị lớn nhất: 9

Ví dụ 3: Hệ thống quản lý học sinh

cpp
#include <iostream>
#include <string>
using namespace std;

// Struct lưu thông tin học sinh
struct HocSinh {
    string ten;
    double diemToan;
    double diemVan;
    double diemAnh;
    double diemTrungBinh;
    string xepLoai;
};

// Tính điểm trung bình
double tinhDiemTrungBinh(double toan, double van, double anh) {
    return (toan + van + anh) / 3.0;
}

// Xếp loại học lực
string xepLoaiHocLuc(double diemTB) {
    if (diemTB >= 9.0) return "Xuất sắc";
    if (diemTB >= 8.0) return "Giỏi";
    if (diemTB >= 6.5) return "Khá";
    if (diemTB >= 5.0) return "Trung bình";
    return "Yếu";
}

// Kiểm tra học sinh có đạt hay không
bool kiemTraDat(double diemTB) {
    return diemTB >= 5.0;
}

// Xử lý thông tin học sinh
HocSinh xuLyHocSinh(string ten, double toan, double van, double anh) {
    HocSinh hs;
    hs.ten = ten;
    hs.diemToan = toan;
    hs.diemVan = van;
    hs.diemAnh = anh;
    hs.diemTrungBinh = tinhDiemTrungBinh(toan, van, anh);
    hs.xepLoai = xepLoaiHocLuc(hs.diemTrungBinh);
    return hs;
}

// In thông tin học sinh
void inThongTin(const HocSinh& hs) {
    cout << "\n=== THÔNG TIN HỌC SINH ===" << endl;
    cout << "Tên: " << hs.ten << endl;
    cout << "Điểm Toán: " << hs.diemToan << endl;
    cout << "Điểm Văn: " << hs.diemVan << endl;
    cout << "Điểm Anh: " << hs.diemAnh << endl;
    cout << "Điểm TB: " << hs.diemTrungBinh << endl;
    cout << "Xếp loại: " << hs.xepLoai << endl;
    cout << "Kết quả: " << (kiemTraDat(hs.diemTrungBinh) ? "ĐẠT" : "KHÔNG ĐẠT") << endl;
}

int main() {
    // Nhập thông tin học sinh
    string ten;
    double toan, van, anh;
    
    cout << "Nhập tên học sinh: ";
    getline(cin, ten);
    
    cout << "Nhập điểm Toán: ";
    cin >> toan;
    
    cout << "Nhập điểm Văn: ";
    cin >> van;
    
    cout << "Nhập điểm Anh: ";
    cin >> anh;
    
    // Xử lý và in kết quả
    HocSinh hocSinh = xuLyHocSinh(ten, toan, van, anh);
    inThongTin(hocSinh);
    
    return 0;
}

Kết quả mẫu:

Nhập tên học sinh: Nguyễn Văn An
Nhập điểm Toán: 8.5
Nhập điểm Văn: 7.0
Nhập điểm Anh: 9.0

=== THÔNG TIN HỌC SINH ===
Tên: Nguyễn Văn An
Điểm Toán: 8.5
Điểm Văn: 7
Điểm Anh: 9
Điểm TB: 8.16667
Xếp loại: Giỏi
Kết quả: ĐẠT

🏋️ Thực hành

Bài tập 1: Hàm toán học cơ bản

Viết các hàm sau và test chúng:

cpp
// 1. Tính lũy thừa
int luuThua(int co_so, int so_mu);

// 2. Tính giai thừa  
int giaiThua(int n);

// 3. Kiểm tra số nguyên tố
bool laSoNguyenTo(int n);

// 4. Tìm ước chung lớn nhất
int ucln(int a, int b);

Bài tập 2: Xử lý chuỗi

Viết các hàm xử lý chuỗi:

cpp
// 1. Đếm số từ trong chuỗi
int demSoTu(string str);

// 2. Chuyển thành chữ hoa
string chuyenHoa(string str);

// 3. Đảo ngược chuỗi
string daoNguoc(string str);

// 4. Kiểm tra palindrome
bool laPalindrome(string str);

Bài tập 3: Xử lý mảng nâng cao

cpp
// 1. Sắp xếp mảng tăng dần
void sapXepTang(int arr[], int size);

// 2. Tìm phần tử xuất hiện nhiều nhất
int timPhanTuPhoBien(int arr[], int size);

// 3. Loại bỏ phần tử trùng lặp
int loaiBoTrung(int arr[], int size);

// 4. Tìm dãy con tăng dài nhất
int dayConTangDaiNhat(int arr[], int size);

📋 Tóm tắt

Các điểm quan trọng về Return Values:

  1. Mục đích: Trả kết quả về nơi gọi hàm
  2. Kiểu dữ liệu: Phải khớp với kiểu khai báo
  3. Return sớm: Có thể dừng hàm bất cứ lúc nào
  4. Void functions: Không trả về giá trị
  5. Multiple returns: Dùng struct/pair cho nhiều giá trị

Best Practices:

  • Consistent return: Mọi đường dẫn đều có return
  • Meaningful values: Giá trị trả về có ý nghĩa rõ ràng
  • Error handling: Xử lý trường hợp lỗi hợp lý
  • Documentation: Ghi chú ý nghĩa giá trị trả về

Tiếp theo:

Bài tiếp theo sẽ học về Phạm vi biến (Variable Scope) - cách biến hoạt động trong các hàm khác nhau và quy tắc truy cập biến.

Khóa học C++ miễn phí