1. Mở đầu: Vì sao cần hiểu rõ cơ chế truyền tham số?
Trong C++, cách một hàm nhận và thao tác với dữ liệu có ảnh hưởng trực tiếp đến hiệu năng, độ an toàn và tính đúng đắn của chương trình. Hai khái niệm nền tảng nhưng thường gây nhầm lẫn cho người mới học là truyền tham trị (call-by-value) và truyền tham chiếu (call-by-reference). Để hiểu đúng hai cơ chế này, trước hết chúng ta cần quay lại những khái niệm cơ bản hơn: phạm vi biến (scope) và vòng đời biến (lifetime). Đây là nền tảng để lý giải vì sao một thay đổi trong hàm có thể (hoặc không thể) ảnh hưởng đến dữ liệu ở phía người gọi.
#include <iostream>
bool MyLocalFunction(int myInt)
{
bool isBelowThreshold = myInt < 42 ? true : false;
return isBelowThreshold;
}
int main()
{
bool res = MyLocalFunction(23);
return 0;
}
Ví dụ trên cho thấy một tập hợp các biến cục bộ (hoặc tự động), có timelife gắn liền với hàm mà chúng nằm trong. Khi hàm MyLocalFunction được gọi, biến cục bộ isBelowThreshold được cấp phát trên ngăn xếp. Khi hàm kết thúc, nó lại được giải phóng.
Phạm vi và vòng đời biến trong C++
Thời gian tồn tại từ lúc một biến được cấp phát bộ nhớ cho đến khi bộ nhớ đó được giải phóng được gọi là vòng đời (lifetime) của biến. Việc truy cập một biến sau khi vòng đời của nó kết thúc là một lỗi lập trình nghiêm trọng và có thể dẫn đến hành vi không xác định. Trong C++, các biến cục bộ (local variables) có vòng đời gắn chặt với phạm vi (scope) mà chúng được khai báo. Chúng chỉ tồn tại khi luồng thực thi đang ở trong phạm vi đó. Khi hàm kết thúc, toàn bộ các biến cục bộ của hàm sẽ bị giải phóng khỏi ngăn xếp và không còn tồn tại nữa. Một điểm quan trọng cần nhấn mạnh là: tham số của hàm cũng là biến cục bộ. Khi một hàm được gọi, các tham số của nó được khởi tạo và tồn tại như các biến cục bộ trong suốt thời gian hàm thực thi.


