Gọi hàm theo tham chiếu trong C
Xin chào các bạn future programmers! Hôm nay, chúng ta sẽ bắt đầu một hành trình đầy thú vị vào thế giới lập trình C, cụ thể là khám phá khái niệm "Gọi hàm theo tham chiếu." Đừng lo lắng nếu bạn mới bắt đầu học lập trình; tôi sẽ hướng dẫn bạn từng bước, như tôi đã làm cho hàng trăm sinh viên trong những năm dạy học của mình. Vậy, hãy lấy饮料 yêu thích của bạn, thoải mái ngồi xuống, và cùng nhau bắt đầu nhé!
Ký hiệu địa chỉ (&) trong C
Trước khi chúng ta có thể hiểu được các cuộc gọi hàm theo tham chiếu, chúng ta cần làm quen với một ký hiệu rất quan trọng trong C: dấu phẩy dưới (&). Ký tự nhỏ bé này được gọi là "ký hiệu địa chỉ," và nó giống như một枝 phép thuật có thể tiết lộ vị trí bí mật của các biến trong bộ nhớ máy tính.
Hãy xem một ví dụ đơn giản:
#include <stdio.h>
int main() {
int age = 25;
printf("Giá trị của age là: %d\n", age);
printf("Địa chỉ của age là: %p\n", &age);
return 0;
}
Trong đoạn mã này, chúng ta không chỉ in giá trị của age
(đó là 25), mà còn địa chỉ của nó trong bộ nhớ. Cụm từ định dạng %p
được sử dụng để in địa chỉ bộ nhớ.
Khi bạn chạy chương trình này, bạn có thể thấy điều gì đó như sau:
Giá trị của age là: 25
Địa chỉ của age là: 0x7ffd5e8e9944
Con số kỳ lạ sau "Địa chỉ của age là:" thực sự là một địa chỉ bộ nhớ! Đó là nơi máy tính của bạn đã quyết định lưu trữ biến age
. Hãy tưởng tượng nó như địa chỉ nhà của biến trong khu phố rộng lớn của bộ nhớ máy tính.
Pointer trong C là gì?
Bây giờ chúng ta đã biết cách tìm địa chỉ của một biến, hãy nói về pointer. Nếu địa chỉ giống như địa chỉ nhà, thì pointer giống như một thiết bị định vị GPS có thể hướng dẫn bạn đến địa chỉ đó.
Trong C, một pointer là một biến lưu trữ địa chỉ bộ nhớ của biến khác. Chúng ta khai báo một pointer bằng cách sử dụng ký hiệu dấu sao (*).
Dưới đây là một ví dụ:
#include <stdio.h>
int main() {
int age = 25;
int *ptr_age = &age;
printf("Giá trị của age là: %d\n", age);
printf("Địa chỉ của age là: %p\n", &age);
printf("Giá trị của ptr_age là: %p\n", ptr_age);
printf("Giá trị mà ptr_age chỉ đến là: %d\n", *ptr_age);
return 0;
}
Trong đoạn mã này, ptr_age
là một pointer lưu trữ địa chỉ của age
. Khi chúng ta sử dụng *ptr_age
, chúng ta đang yêu cầu giá trị lưu trữ tại địa chỉ mà ptr_age
đang chỉ đến.
Kết quả đầu ra có thể trông như sau:
Giá trị của age là: 25
Địa chỉ của age là: 0x7ffd5e8e9944
Giá trị của ptr_age là: 0x7ffd5e8e9944
Giá trị mà ptr_age chỉ đến là: 25
Thấy rằng địa chỉ lưu trữ trong ptr_age
khớp với địa chỉ của age
? Đó là vì ptr_age
đang chỉ đến age
!
Gọi hàm theo tham chiếu hoạt động như thế nào trong C?
Bây giờ chúng ta đã hiểu về pointer, chúng ta có thể khám phá cách gọi hàm theo tham chiếu. Khi chúng ta gọi hàm theo tham chiếu, chúng ta đang truyền địa chỉ của một biến đến hàm, thay vì giá trị của nó. Điều này cho phép hàm trực tiếp thay đổi biến gốc.
Hãy xem một ví dụ:
#include <stdio.h>
void increment(int *num) {
(*num)++;
}
int main() {
int x = 5;
printf("Trước khi increment: x = %d\n", x);
increment(&x);
printf("Sau khi increment: x = %d\n", x);
return 0;
}
Trong đoạn mã này, chúng ta đang truyền địa chỉ của x
đến hàm increment
. Hàm sau đó sử dụng địa chỉ này để trực tiếp thay đổi giá trị của x
.
Kết quả đầu ra sẽ là:
Trước khi increment: x = 5
Sau khi increment: x = 6
Hàm increment
đã có thể thay đổi giá trị của x
trong hàm main
vì nó nhận được địa chỉ của x
, không chỉ là một bản sao giá trị của nó.
Kết hợp gọi hàm theo giá trị và theo tham chiếu
Trong C, chúng ta có thể kết hợp gọi hàm theo giá trị và theo tham chiếu trong cùng một hàm. Điều này có thể rất hữu ích khi chúng ta muốn thay đổi một số tham số nhưng không phải tất cả.
Dưới đây là một ví dụ:
#include <stdio.h>
void modify(int *a, int b, int *c) {
(*a)++;
b++;
(*c)++;
}
int main() {
int x = 1, y = 2, z = 3;
printf("Trước khi modify: x = %d, y = %d, z = %d\n", x, y, z);
modify(&x, y, &z);
printf("Sau khi modify: x = %d, y = %d, z = %d\n", x, y, z);
return 0;
}
Trong ví dụ này, x
và z
được truyền theo tham chiếu, trong khi y
được truyền theo giá trị.
Kết quả đầu ra sẽ là:
Trước khi modify: x = 1, y = 2, z = 3
Sau khi modify: x = 2, y = 2, z = 4
Chú ý rằng x
và z
đã thay đổi, nhưng y
vẫn giữ nguyên? Đó là vì hàm chỉ nhận được một bản sao giá trị của y
, không phải địa chỉ của nó.
Dưới đây là bảng tóm tắt sự khác biệt giữa gọi hàm theo giá trị và theo tham chiếu:
Phương diện | Gọi hàm theo giá trị | Gọi hàm theo tham chiếu |
---|---|---|
Gì được truyền | Bản sao giá trị | Địa chỉ của biến |
Có thể thay đổi biến gốc | Không | Có |
Cú pháp | function(variable) |
function(&variable) |
Tham số hàm | Biến bình thường | Pointer |
Và thế là xong! Chúng ta đã bao quát các khái niệm cơ bản về gọi hàm theo tham chiếu trong C. Nhớ rằng, như với bất kỳ kỹ năng mới nào, thực hành là chìa khóa. Hãy thử viết các hàm riêng của bạn sử dụng gọi hàm theo tham chiếu và thử nghiệm với các kịch bản khác nhau. Trước khi bạn nhận ra, bạn sẽ manipulates địa chỉ bộ nhớ như một chuyên gia!
Chúc các bạn lập trình vui vẻ, và mong rằng các pointer của bạn luôn chỉ đúng hướng!
Credits: Image by storyset