Reference trong C++ là gì?
Reference trong C++ là một tên gọi khác cho cùng một vùng dữ liệu đã có sẵn. Bạn có thể xem reference như “bí danh” của biến gốc. Khi hai tên cùng trỏ tới một dữ liệu, thay đổi qua tên nào thì dữ liệu thật cũng thay đổi. So với pointer, reference trong C++ thường dễ đọc hơn và rất hay xuất hiện khi truyền tham số vào hàm.
Nếu pointer làm việc rõ ràng với địa chỉ, thì reference tập trung vào việc dùng chung cùng một dữ liệu theo cú pháp gần với biến thường. Đây là lý do nhiều người mới thấy reference dễ tiếp cận hơn con trỏ.
Cú pháp cơ bản của reference trong C++
#include <iostream>
using namespace std;
int main() {
int x = 10;
int& y = x;
cout << x << endl;
cout << y << endl;
return 0;
}
Trong ví dụ trên, y không phải bản sao của x. Nó là một tên khác của chính x.
Khi bạn mới học, rất dễ nghĩ rằng int& y = x; nghĩa là sao chép x sang y. Thực ra không phải. Reference không tạo ra vùng dữ liệu độc lập mới. Nó chỉ tạo thêm một cách gọi khác cho biến cũ.
int x = 10;
int& y = x;
y = 50;
cout << x << endl;
Khi đổi y, giá trị của x cũng đổi theo.
Bạn có thể tự kiểm tra bằng cách in cả hai biến trước và sau khi thay đổi. Kết quả sẽ cho thấy x và y luôn đi cùng nhau vì chúng cùng tham chiếu tới một dữ liệu.
Một điểm rất quan trọng là reference phải được gắn với biến ngay khi khai báo. Bạn không thể viết:
int& y;Vì C++ cần biết ngay y là bí danh của biến nào.
Cách dùng reference trong C++ khi truyền tham số
Reference rất hữu ích khi bạn muốn hàm thay đổi trực tiếp biến gốc.
#include <iostream>
using namespace std;
void tangLenMot(int& so) {
so++;
}
int main() {
int x = 7;
tangLenMot(x);
cout << x << endl;
return 0;
}
Vì tham số là reference, hàm tangLenMot tác động trực tiếp lên biến ban đầu.
Đây là tình huống rất phổ biến trong thực tế. Nếu bạn truyền tham số theo kiểu thông thường, hàm chỉ nhận một bản sao và thay đổi trong hàm sẽ không ảnh hưởng tới biến bên ngoài.
So sánh nhanh:
#include <iostream>
using namespace std;
void tangBanSao(int so) {
so++;
}
void tangTrucTiep(int& so) {
so++;
}
int main() {
int x = 5;
tangBanSao(x);
cout << x << endl;
tangTrucTiep(x);
cout << x << endl;
return 0;
}
Sau lần gọi tangBanSao(x), giá trị của x vẫn là 5. Nhưng sau tangTrucTiep(x), x sẽ thành 6. Ví dụ này giúp bạn thấy rõ sức mạnh của truyền tham chiếu trong C++.
Reference cũng hay dùng khi truyền biến lớn vào hàm để tránh sao chép không cần thiết. Ở giai đoạn này, bạn chưa cần tối ưu hiệu năng sâu, nhưng nên nhớ rằng reference vừa giúp code gọn vừa có thể hiệu quả hơn.
Reference và pointer trong C++ khác nhau thế nào?
- Reference dễ đọc hơn trong nhiều trường hợp cơ bản.
- Pointer có thể trỏ chỗ khác hoặc để
nullptr, reference thì không. - Reference thường hay dùng cho tham số hàm.
Bạn có thể nhớ theo cách sau:
- Pointer giống như một biến chứa địa chỉ
- Reference giống như một tên phụ của cùng biến
Vì là tên phụ, reference không cần thao tác dereference bằng
* như pointer. Bạn dùng nó gần như biến bình thường. Đây là lý do code dùng reference thường nhìn sạch hơn.
Tuy nhiên, điều đó không có nghĩa reference thay thế hoàn toàn pointer. Pointer vẫn cần trong nhiều phần quan trọng của C++, nhất là khi làm việc với bộ nhớ động hoặc cấu trúc dữ liệu nâng cao.
Những lỗi thường gặp với reference trong C++
- Nghĩ rằng reference là bản sao của biến.
- Khai báo reference mà không gắn ngay với biến.
- Nhầm
&trong reference với&lấy địa chỉ. - Dùng reference khi không muốn thay đổi dữ liệu gốc.
- Nhầm giữa truyền tham trị và truyền tham chiếu.
int x = 5;
int& y = x;Một lỗi khác rất phổ biến là viết hàm dùng reference rồi quên mất rằng dữ liệu gốc sẽ bị sửa:
void datVeKhong(int& so) {
so = 0;
}Nếu gọi hàm này, biến truyền vào sẽ đổi thật. Vì vậy trước khi dùng reference, hãy tự hỏi: mình có muốn sửa dữ liệu gốc hay không?
Ngoài ra, đừng nhầm đoạn này:
int x = 10;
int& y = x;
cout << &x << endl;
cout << &y << endl;Hai dòng in trên sẽ cho cùng một địa chỉ, vì y chỉ là bí danh của x.
Bài tập thực hành
Viết hàm hoanDoi(int& a, int& b) để đổi chỗ giá trị của hai biến. Sau đó gọi hàm này trong main().
Gợi ý:
#include <iostream>
using namespace std;
void hoanDoi(int& a, int& b) {
int tam = a;
a = b;
b = tam;
}
int main() {
int x = 3;
int y = 9;
hoanDoi(x, y);
cout << x << " " << y << endl;
return 0;
}
Sau khi chạy, hãy giải thích vì sao x và y bị đổi trực tiếp dù trong hàm bạn chỉ làm việc với a và b.
Câu hỏi thường gặp về reference trong C++
Reference có thể đổi sang trỏ biến khác không?
Không. Sau khi reference đã gắn với một biến, nó sẽ luôn tham chiếu đến biến đó.
Khi nào nên dùng reference thay vì pointer?
Hãy dùng reference khi bạn chỉ cần làm việc trực tiếp với biến gốc theo cách gọn hơn, đặc biệt là khi truyền tham số vào hàm.
Reference có bắt buộc phải dùng với hàm không?
Không. Bạn có thể tạo reference ngay trong main() hoặc trong bất kỳ khối lệnh nào. Tuy nhiên, nơi reference xuất hiện nhiều nhất trong code thực tế là phần tham số hàm và giá trị trả về trong các chủ đề nâng cao hơn.
Dấu & trong int& y = x có phải là lấy địa chỉ không?
Không. Trong khai báo reference, dấu & là một phần của cú pháp tạo tham chiếu. Còn trong biểu thức như &x, dấu & mới có nghĩa là lấy địa chỉ của biến x.
Tóm tắt
Bạn đã hiểu reference trong C++ là gì, biết rằng reference là bí danh chứ không phải bản sao, và đã thấy cách dùng nó để thay đổi trực tiếp biến gốc khi truyền vào hàm. Bạn cũng đã phân biệt được reference với pointer và nhận ra lúc nào nên dùng tham chiếu để code dễ đọc hơn.
Ở bài tiếp theo, chúng ta sẽ học vector trong C++ để quản lý danh sách dữ liệu linh hoạt hơn mảng thường và bắt đầu viết các chương trình thực tế hơn.
Bài viết liên quan

Next.js là gì? Tại sao nên dùng Next.js để làm web?
Giới thiệu Next.js — framework React phổ biến nhất. Tìm hiểu ưu điểm, tính năng nổi bật và khi nào nên dùng.

Con bug đầu tiên trong cuộc đời lập trình viên
Câu chuyện hài hước về lần đầu gặp bug và mất 3 tiếng để tìm ra nguyên nhân chỉ là... thiếu dấu chấm phẩy.

Hướng dẫn cài đặt Python chi tiết trên Windows, macOS, Linux
Hướng dẫn từng bước cài đặt Python trên mọi hệ điều hành. Kèm cách kiểm tra và chạy chương trình đầu tiên.