Trong Ví dụ 4.6, hàm maximum có hai tham số và mỗi khi hàm này được gọi từ hàm main (hàm gọi), nó yêu cầu được cung cấp hai giá trị (đối số - argument) phù hợp với kiểu dữ liệu của hai tham số nói trên. Các giá trị này được sao chép vào các tham số
66
và được sử dụng trong phần thân của hàm maximum. Nói cách khác, tham số là tên của dữ liệu được sử dụng trong cài đặt hàm và đối số là dữ liệu thực tế được truyền cho hàm mỗi khi hàm được gọi.
Ví dụ 4.7. Minh họa thực thi chƣơng trình ở Ví dụ 4.6
Biên dịch và chạy chương trình (nhấn F9) Thực thi hàm main
> Nhap hai so tu ban phim: 5 10 [Enter]
> Gia tri lon nhat cua 5 va 10 la 10 > [Enter]
>
Khai báo biến cục bộ x, y, max Xuất chuỗi ký tự ra màn hình Đọc hai số từ bàn phím (5, 10) Gọi hàm maximum(5,10)
Chuyển điều khiển cho hàm maximum
- Hai tham số a=5, b=10.
- Khai báo, khởi tạo max = 5
- Thực hiện cấu trúc rẽ nhánh, điều kiện 5 < 10 đúng, gán max = 10
- Trả về kết quả 10 cho hàm gọi (hàm main)
- Trả điều khiển cho hàm main Gán max = 10
Xuất chuỗi ký tự ra màn hình Chờ nhập một ký tự
Chương trình kết thúc
Có hai phương pháp truyền đối số cho tham số bao gồm truyền tham trị và truyền tham chiếu.
4.6.1 Truyền tham trị
Phương pháp truyền tham trị thực hiện sao chép giá trị của đối số cho tham số của hàm. Trong trường hợp này, những thay đổi (nếu có) của tham số không ảnh hưởng đến đối số. Nói cách khác, giá trị của đối số trong hàm gọi không thay đổi trước và sau khi gọi thực thi hàm khác.
Ví dụ 4.8. Truyền tham trị cho hàm
#include <stdio.h> void swap(int a, int b){
int temp = a; a = b; b = temp; }
67 int x = 5, y = 10;
printf("Truoc khi doi cho: x=%d, y=%d\n", x, y); swap(x,y);
printf("Sau khi doi cho: x=%d, y=%d", x, y); getchar();
return 0; }
Hàm swap(int a, int b) với nhiệm vụ hoán vị giá trị của a và b như vậy là không đạt yêu cầu. Mặc dù hàm swap hoàn toàn chính xác cả về cú pháp lẫn ý nghĩa nhưng kết quả hiển thị trên màn hình của chương trình không có gì thay đổi trước và sau khi gọi hàm này. Điều này là do chương trình lựa chọn phương pháp truyền tham trị cho hàm
swap.
Trong trường hợp này, hàm swap nhận hai đối số là giá trị của x và y (tức 5 và 10) rồi gán chúng cho hai tham số a và b của hàm. Nói cách khác, khi hàm swap nhận trình điều khiển từ hàm main, hai tham số của hàm có giá trị lần lượt là 5 và 10. Kết thúc hàm
swap, a và b có giá trị lần lượt là 10 và 5 như là kết quả của việc hoán vị hai số. Tuy nhiên, sự thay đổi này chỉ có hiệu lực bên trong hàm swap mà thôi. Khi hàm main nhận trình điều khiển do hàm swap trả về, giá trị của x và y vẫn là 5 và 10 như trước khi gọi hàm swap.
4.6.2 Truyền tham chiếu
Phương pháp truyền tham chiếu thực hiện sao chép địa chỉ của đối số cho tham số của hàm. Trong trường hợp này, do đối số và tham số có cùng địa chỉ trong bộ nhớ nên mọi thay đổi trên tham số (được lưu trữ tại địa chỉ tương ứng trong bộ nhớ) cũng chính là thay đổi trên đối số (được lưu trữ tại cùng địa chỉ). Nói cách khác, giá trị của đối số trong hàm gọi thay đổi tương ứng với thay đổi của tham số trong hàm được gọi.
Ví dụ 4.9. Truyền tham chiếu cho hàm
#include <stdio.h>
void swap2(int &a, int &b){ int temp = a;
a = b; b = temp; }
68
int main(){
int x = 5, y = 10;
printf("Truoc khi doi cho: x=%d, y=%d\n", x, y); swap2(x,y);
printf("Sau khi doi cho: x=%d, y=%d", x, y); getchar();
return 0; }
Hàm swap2 trong Ví dụ 4.9 cũng có hai tham số như hàm swap trong Ví dụ 4.8. Tuy nhiên, swap2 nhận địa chỉ của hai đối số thay vì nhận giá trị như swap. Kết quả của việc truyền địa chỉ thông qua tham chiếu của các đối số làm cho hai tham số a và b của hàm được gọi (swap2) có cùng địa chỉ lưu trữ trong bộ nhớ với hai đối số x và y của hàm gọi (main). Do đó, sự thay đổi giá trị của a (từ 5 thành 10) và b (từ 10 thành 5) trong hàm
swap2 cũng được ghi nhận đối với giá trị của x và y trong hàm main. Nói cách khác, khi hàm main nhận trình điều khiển từ hàm swap2, x và y có giá trị lần lượt là 10 và 5 đúng như yêu cầu đặt ra ban đầu của chương trình.