Bài học tương tác C++ cơ bản

Hàm trong lập trình

Hàm giống như một “máy nhỏ có tên”: đưa dữ liệu vào, xử lý theo nhiệm vụ đã định, rồi có thể trả kết quả ra. Bài này giúp em viết hàm rõ ràng, gọi hàm đúng cách, phân biệt tham trị - tham chiếu và tránh các lỗi rất hay gặp khi mới học.

Mục tiêu rõBiết viết và gọi hàm
Code mẫuC++ và Python dạng tab
Mô phỏngTham trị vs tham chiếu
Bài tập phân loạiDễ đến nâng cao
Tiến độ bài học
0%
Mục tiêu bài học

Sau bài này, học sinh cần làm được gì?

Hiểu hàm là gì

Biết vì sao dùng hàm giúp chương trình gọn, dễ đọc, dễ sửa.

Viết và gọi hàm

Biết định nghĩa hàm trong C++ và Python, gọi hàm trong chương trình chính.

Phân biệt truyền dữ liệu

Hiểu tham trị là bản sao, tham chiếu là tác động trực tiếp lên biến gốc.

Áp dụng thực tế

Viết hàm tính tổng mảng, tìm max, kiểm tra số nguyên tố, xử lý chuỗi.

Ví dụ đời sống: Khi muốn pha nước chanh nhiều lần, em không viết lại toàn bộ hướng dẫn từ đầu. Em đặt tên quy trình là phaNuocChanh(). Khi cần, chỉ việc gọi quy trình đó.
Mini slide 1

1. Hàm là gì?

Hàm là một khối lệnh có tên. Hàm nhận dữ liệu đầu vào, thực hiện một nhiệm vụ cụ thể, sau đó có thể trả về kết quả. Dùng hàm giúp tránh lặp code và làm chương trình rõ ràng hơn.

Dữ liệu vàoa = 3, b = 5
Hàm xử lýcong(a, b)
Kết quả ra8
Tránh lặp code

Viết một lần, dùng lại nhiều lần.

Dễ đọc

Nhìn tên hàm là hiểu nhiệm vụ: is_prime, sumArray.

Dễ sửa

Sai ở đâu sửa ở hàm đó, không phải tìm khắp chương trình.

Mini slide 2

2. Cú pháp hàm: nhìn đúng từng bộ phận

Khi học hàm, học sinh thường nhầm giữa kiểu trả về, tên hàm, tham sốgiá trị trả về. Hãy tách hàm thành từng phần như dưới đây.

int cong (int a, int b) {
    return a + b;
}
int

Kiểu dữ liệu mà hàm trả về. Ở đây kết quả là số nguyên.

cong

Tên hàm. Nên đặt tên thể hiện đúng nhiệm vụ.

int a, int b

Tham số đầu vào. Khi gọi hàm, ta truyền giá trị vào đây.

return

Trả kết quả về nơi gọi hàm. Hàm có kiểu trả về khác void cần có return.

#include 
using namespace std;

int cong(int a, int b) {
    return a + b;
}

int main() {
    cout << cong(3, 5); // in ra 8
    return 0;
}
def cong(a, b):
    return a + b

print(cong(3, 5))  # in ra 8
Ghi nhớ nhanh: Hàm có return thường dùng khi cần lấy kết quả để tính tiếp. Hàm void trong C++ thường dùng để in ra màn hình hoặc thay đổi dữ liệu thông qua tham chiếu.
Mini slide 3

3. Phân loại hàm để không nhầm

Hàm trả về giá trị

Ví dụ: max3(a,b,c), is_prime(n). Có return rõ ràng.

Hàm không trả về

C++ dùng void. Thường để in bảng, in dòng trang trí, hoặc thực hiện thao tác.

Hàm có tham số

Nhận dữ liệu vào. Ví dụ: cong(3,5) đưa 3 và 5 vào hàm.

Hàm dùng tham chiếu

Trong C++ dùng dấu & để thay đổi trực tiếp biến gốc.

Ví dụ đúng: dùng return để lấy kết quả

int binhPhuong(int x) {
    return x * x;
}

int main() {
    int y = binhPhuong(5); // y = 25
    cout << y;
}

Ví dụ đúng: void chỉ in kết quả

void inLoiChao(string name) {
    cout << "Xin chao " << name;
}

int main() {
    inLoiChao("Nam");
}
Dễ nhầm: Nếu hàm chỉ in ra màn hình thì chưa chắc đã “trả kết quả”. Muốn dùng kết quả để tính tiếp, nên viết hàm có kiểu trả về và dùng return.
Mini slide 4

4. Truyền tham trị và truyền tham chiếu trong C++

Đây là phần học sinh rất dễ nhầm. Hãy nhớ bằng hình ảnh: tham trị là đưa bản photo, còn tham chiếu là đưa chính quyển vở gốc cho hàm sửa trực tiếp.

void tangLen_Value(int x) {
    x = x + 1;
}

int main() {
    int a = 10;
    tangLen_Value(a);
    cout << a; // vẫn là 10
}
void tangLen_Ref(int &x) {
    x = x + 1;
}

int main() {
    int a = 10;
    tangLen_Ref(a);
    cout << a; // giờ là 11
}
def change_number(x):
    x = x + 1

n = 10
change_number(n)
print(n)  # vẫn là 10


def add_item(a):
    a.append(99)

arr = [1, 2, 3]
add_item(arr)
print(arr)  # [1, 2, 3, 99]

Mô phỏng biến a = 10

Chọn kiểu gọi hàm để xem biến gốc có đổi không.

Biến gốc a10
Trong hàm x?
Ban đầu: a = 10. Hãy chạy thử hai cách truyền.
Quy tắc an toàn cho học sinh mới học: Khi chỉ cần đọc dữ liệu mảng/vector, dùng const vector& a. Khi cần sửa biến gốc, mới dùng tham chiếu không có const, ví dụ int &x.
Mini slide 5

5. Hàm tính tổng mảng

Đây là ví dụ quan trọng vì trong bài thi, nhiều bài yêu cầu tách xử lý thành hàm: tính tổng, đếm số chẵn, tìm max, kiểm tra điều kiện, xử lý từng phần của mảng.

#include 
using namespace std;

long long sumArray(const vector& a) {
    long long s = 0;
    for (int x : a) s += x;
    return s;
}

int main() {
    int n;
    cin >> n;
    vector a(n);
    for (int i = 0; i < n; i++) cin >> a[i];

    cout << sumArray(a);
    return 0;
}
def sum_array(a):
    s = 0
    for x in a:
        s += x
    return s

n = int(input())
arr = list(map(int, input().split()))
print(sum_array(arr))

Thực hành nhanh

Nhập các số cách nhau bởi dấu cách. Ví dụ: 4 7 2 10 6

Kết quả sẽ hiện ở đây.

Khi nào nên tách hàm?

Nên tách hàm khi một đoạn code có nhiệm vụ rõ ràng như: tính tổng, tìm max, kiểm tra nguyên tố, đảo chuỗi, đếm chữ số.
Chưa cần tách hàm nếu đoạn code quá ngắn, chỉ dùng một lần và không có nhiệm vụ riêng rõ ràng.
Mini slide 6

6. Các lỗi học sinh hay nhầm và cách tránh

Lỗi 1: Hàm có kiểu trả về nhưng quên return

Sai: int f(){ cout << 5; }. Đúng: nếu kiểu là int, cần return một số nguyên.

Lỗi 2: Nhầm in ra với trả về

cout chỉ in ra màn hình. return mới đưa kết quả về để tính tiếp.

Lỗi 3: Muốn đổi biến gốc nhưng truyền tham trị

Nếu muốn hàm làm thay đổi biến gốc trong C++, cần dùng &, ví dụ void tang(int &x).

Lỗi 4: Gọi hàm trước khi C++ biết hàm

Nên đặt hàm trước main, hoặc khai báo nguyên mẫu hàm trước main.

Ví dụ sai

int max2(int a, int b) {
    if (a > b) cout << a;
    else cout << b;
}

int main() {
    int x = max2(4, 7); // sai vì max2 không return
}

Sửa đúng

int max2(int a, int b) {
    if (a > b) return a;
    return b;
}

int main() {
    int x = max2(4, 7);
    cout << x; // 7
}
Kiểm tra nhanh

Quiz nhỏ: Em có nhầm không?

Câu 1. Hàm nào phù hợp để tính và trả về tổng hai số?
Chọn một đáp án.
Câu 2. Muốn hàm làm biến a tăng từ 10 thành 11 trong C++ thì viết tham số thế nào?
Chọn một đáp án.
Bài tập phân loại

7. Bài tập tự luyện theo mức độ

Các bài dưới đây được chia nhóm để học sinh không nhầm: nhóm nào cần return, nhóm nào dùng vòng lặp, nhóm nào xử lý mảng/chuỗi, nhóm nào cần tham chiếu.

Mức 1 - Hàm trả về giá trị đơn giản
Nhận biết kiểu trả về và return
  • Viết hàm max3(a, b, c) trả về số lớn nhất trong ba số.
  • Viết hàm square(x) trả về bình phương của x.
  • Viết hàm abs_val(x) trả về giá trị tuyệt đối của x.
Mức 2 - Hàm có điều kiện và vòng lặp
Rèn tư duy kiểm tra điều kiện
  • Viết hàm is_even(n) kiểm tra n có phải số chẵn không.
  • Viết hàm is_prime(n) kiểm tra n có phải số nguyên tố không.
  • Viết hàm count_divisor(n) trả về số lượng ước của n.
Mức 3 - Hàm với mảng và chuỗi
Phù hợp bài thi xử lý dữ liệu
  • Viết hàm sumArray(a) tính tổng mảng.
  • Viết hàm countEven(a) đếm số chẵn trong mảng.
  • Viết hàm reverse_string(s) trả về chuỗi đảo ngược.
Mức 4 - Hàm dùng tham chiếu C++
Chỉ dùng khi cần sửa biến gốc
  • Viết hàm swap2(int &a, int &b) đổi chỗ hai số.
  • Viết hàm increase(int &x) làm x tăng thêm 1.
  • Viết hàm normalize(int &x): nếu x < 0 thì gán x = 0.

bool is_prime(int n) {
    if (n < 2) return false;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) return false;
    }
    return true;
}

def reverse_string(s):
    return s[::-1]

s = input()
print(reverse_string(s))

void swap2(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}

int main() {
    int x = 4, y = 9;
    swap2(x, y);
    cout << x << " " << y; // 9 4
}
Bài tiếp theo

Đọc / Ghi file

Sau khi biết tách chương trình thành các hàm rõ ràng, em sẽ học cách đọc dữ liệu từ file .INP và ghi kết quả ra file .OUT giống các bài thi lập trình.

➡ Tiếp theo: Đọc / Ghi file để xử lý dữ liệu từ .INP, .OUT như bài thi thật.