Gọi bằng tham chiếu trong C++: Sử dụng con trỏ (kèm theo ví dụ)
Trong bài này, bạn sẽ được học cách truyền con trỏ như một đối số cho hàm, và sử dụng nó một cách hiệu quả trong chương trình của bạn.
Trong bài về các hàm trong C++, bạn đã được học về cách truyền đối số cho một hàm. Phương pháp này thực hiện lời gọi bằng cách truyền tham trị, bởi vì giá trị thực sự được truyền vào.
Tuy nhiên, có một cách khác để truyền vào đối số cho một hàm mà giá trị thực sự của đối số không được truyền. Thay vào đó, chỉ có tham chiếu tới giá trị đó được truyền vào.
Ví dụ 1: Truyền tham chiếu sử dụng con trỏ
#include <iostream>
using namespace std;
// nguyên mẫu hàm
void swap(int&, int&);
int main()
{
int a = 1, b = 2;
cout << "Before swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap(a, b);
cout << "nAfter swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
void swap(int& n1, int& n2) {
int temp;
temp = n1;
n1 = n2;
n2 = temp;
}
Đầu ra
Before swapping
a = 1 b = 2 After swapping a = 2 b = 1 |
Trong hàm main(), hai biến số nguyên a và b được định nghĩa. Và các số nguyên đó được truyền vào hàm swap() thông qua tham chiếu.
Trình biên dịch có thể xác định đây là truyền theo theo chiếu vì định nghĩa hàm đưa ra ở trên là void swap(int& n1, int& n2) (lưu ý dấu & sau kiểu dữ liệu).
Chỉ có tham chiếu (địa chỉ) của biến a và b được nhận vào trong hàm swap(), và việc đổi chỗ được thực hiện với địa chỉ gốc của các biến.
Trong hàm swap(), n1 và n2 là hai đối số hình thức, hai đối số này lần lượt tương ứng với hai biến a và b.
Có một cách khác để thực hiện công việc tương tự đó là sử dụng con trỏ.
Ví dụ 2: Truyền bằng tham chiếu sử dụng con trỏ
#include <iostream>
using namespace std;
// nguyên mẫn hàm
void swap(int*, int*);
int main()
{
int a = 1, b = 2;
cout << "Before swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap(&a, &b);
cout << "nAfter swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
void swap(int* n1, int* n2) {
int temp;
temp = *n1;
*n1 = *n2;
*n2 = temp;
}
Đầu ra của ví dụ này giống với ví dụ trước đó.
Trong trường hợp này, địa chỉ của biến được truyền vào trong khi gọi hàm thay vì bản thân biến đó.
swap(&a, &b); // &a là địa chỉ của a và &b là địa chỉ của b
Vì địa chỉ được truyền vào thay cho giá trị, toán tử phân giải địa chỉ cần được sử dụng để truy xuất vào giá trị được lưu ở địa chỉ đó.
void swap(int* n1, int* n2) {
... .. ...
}
*n1 và *n2 trả về giá trị lưu tại địa chỉ n1 và n2.
Vì n1 chứa địa chỉ của a, bất cứ hành động nào thực hiện trên *n1 cũng sẽ thay đổi giá trị của a trong hàm main(). Tương tự, b sẽ có cùng giá trị với *n2.