Tham số là tham biến trong hàm là gì

Trong bài này mình sẽ giúp bạn hiểu hơn về tham trị và tham chiếu trong C++, đây là hai cách truyền tham số cho hàm C++ mà bạn nhất định phải biết.

Tham số là tham biến trong hàm là gì

Tham số là tham biến trong hàm là gì

Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Trong C++ hỗ trợ cho chúng ta 2 cách gọi hàm đó là tham trị (call by value) và tham chiếu (call by reference). Cả hai đều có chung mục đích là truyền dữ liệu vào hàm, nhưng về tính chất thì có sự khác biệt rất rõ ràng.

Tham số là tham biến trong hàm là gì

Thuật ngữ modified trong hình trên có ý nghĩa là có thể thay đổi giá trị cho tham số Original value truyền vào. Vậy, khi tham số được gọi theo tham trị thì những thay đổi của tham số đó trong hàm sẽ không ảnh hưởng đến giá trị gốc của biến khi kết thúc hàm. Còn khi gọi theo kiểu tham trị thì có thay đổi.

Bài viết này được đăng tại [free tuts .net]

Để biết thêm chi tiết chúng ta sẽ cùng tìm hiểu trong nội dung sau nhé.

1. Gọi hàm kiểu tham trị trong C++

Tham trị trong C++ không làm thay đổi giá trị của tham số thực tế được truyền vào hàm. Tức là khi truyền giá trị của tham số thực tế vào hàm, thì giá trị của tham số thực tế sẽ được copy cho tham số hình thức của hàm, giá trị của tham số hình thức và tham số thực tế ở hai bộ nhớ khác nhau, vì vậy thay đổi giá trị bên trong hàm không làm thay đổi giá trị của tham số thực tế truyền vào.

Ví dụ: Chúng ta cùng xem một ví dụ đơn giản về tham trị trong C++ như sau:

Ví dụ

#include <iostream> using namespace std; void Show(int i) { i = 15; cout << "Bien i ben trong ham, i = " << i << endl; } int main() { int i = 1; cout << "Truoc khi truyen bien i vao ham, i = " << i << endl; Show(i); cout << "Sau khi truyen bien i vao ham, i = " << i << endl; return 0; }

Và kết quả sau khi thực thi đoạn code trên:

Tham số là tham biến trong hàm là gì

Ban đầu giá trị của i = 1, mình truyền i vào trong hàm và hàm đó thay đổi giá trị của i thành 15. Tuy nhiên, sau khi kết thúc hàm thì biến i vẫn giữ nguyên giá trị ban đầu là bằng 1.

2. Gọi hàm kiểu tham chiếu trong C++

Tham chiếu trong C++ sẽ làm thay đổi giá trị của biến truyền vào hàm bởi vì chúng ta truyền vào địa chỉ của nó chứ không phải truyền giá trị vào.

Ở đây, địa chỉ của tham số thực tế được truyền vào hàm, vì vậy địa chỉ của tham số hình thức và tham số thực tế sẽ cùng địa chỉ trong bộ nhớ, cho nên khi thay đổi giá trị của tham số hình thức bên trong hàm, sẽ làm thay đổi giá trị gốc của tham số thực tế được truyền vào hàm.

Để hiểu rõ hơn về tham chiếu trong C++ thì bạn phải có kiến thức về con trỏ trong C++. Tuy nhiên, vì các bạn chưa học nên tạm thời cứ hiểu rằng khi truyền kiểu tham chiếu thì tên biến bạn phải thêm dấu sao * nhé.

Ví dụ: Chúng ta cùng xem một ví dụ đơn giản về tham chiếu trong C++, đó là hoán đổi 2 giá trị của 2 biến cho nhau.

Ví dụ

#include<iostream> using namespace std; void swap(int *x, int *y) { int swap; swap=*x; *x=*y; *y=swap; } int main() { int x; int y; x=2; y=3; cout << "Gia tri x truoc khi goi ham, x = " << x << endl; cout << "Gia tri y truoc khi goi ham, y = " << y << endl; swap(&x, &y); cout << "Gia tri x sau khi goi ham, x = " << x << endl; cout << "Gia tri y sau khi goi ham, y = " << y << endl; return 0; }

Và kết quả sau khi thực thi đoạn code trên:

Tham số là tham biến trong hàm là gì

Như bạn thấy, giá trị của biến x và y đã bị thay đổi sau khi truyền nó vào hàm swap.

3. Sự khác nhau giữa tham trị và tham chiếu trong C++ là gì?

Chúng ta cùng tổng hợp điểm khác nhau giữa tham trị và tham chiếu trong C++ như trong bảng sau:

Tham tri Tham chiếu
Một bản sao giá trị của biến được truyền vào hàm Địa chỉ của biến được truyền vào hàm
Thay đổi biến bên trong hàm không làm thay đổi biến truyền vào hàm Thay đổi biến bên trong hàm sẽ làm thay đổi biến truyền vào hàm
Tham số hình thức và tham số thực tế khác địa chỉ trong bộ nhớ Tham số hình thức và tham số thực tế cùng địa chỉ trong bộ nhớ

4. Kết luận

Vậy là trong bài học hôm nay chúng ta đã tìm hiểu xong 2 cách gọi hàm thường sử dụng trong C++, đó là gọi hàm theo tham trị và gọi hàm theo tham chiếu. Tùy vào từng trường hợp mà bạn chọn cách gọi cho phù hợp nhé.

Nếu bạn nào muốn thay đổi giá trị của biến sau khi gọi hàm thì dùng cách gọi tham chiếu, nếu bạn nào chỉ lấy giá trị của biến để tính toán mà không cần thay đổi giá trị của biến thì dùng cách gọi tham trị.

Như vậy mình sẽ kết thúc bài học này tại đây nhé. Bài học tiếp theo mình sẽ học về đệ quy trong C++. Các bạn nhớ theo dõi nhé.

Trong C++ hỗ trợ những cách truyền đối số cho hàm là:

    • Truyền bằng tham trị (pass by value)
    • Truyền bằng địa chỉ (pass by address hoặc pass by pointer)
    • Truyền bằng tham chiếu (pass by reference)

Bài này sẽ giới thiệu cách truyền tham trịtham chiếu. Truyền bằng địa chỉ sẽ học sau ở những bài về con trỏ (pointer). Cuối bài này, chúng ta sẽ xem xét một vấn đề nữa là đối số mặc định của hàm.

Ví dụ, ta có một hàm được định nghĩa như sau:

void foo(int param1, int param2) //param1 and param2 are parameters { //do something }

với param1 và param2 là 2 tham số (parameters) của hàm foo.

Tham số của hàm là những biến được khai báo trong khai báo hàm. Tham số đóng vai trò là giá trị đầu vào cho hàm.

Giả sử, trong hàm main() thực hiện gọi hàm foo:

int main() { foo(1, 2); //1 and 2 are arguments return 0; }

Lúc này, 1 và 2 là 2 đối số (arguments) của hàm foo. Khi đó, giá trị 1 và 2 sẽ được tiếp nhận và lưu trữ tạm thời trong 2 tham số param1 và param2.

Đối số là giá trị được truyền vào hàm mỗi khi thực hiện lời gọi hàm. Đối số phải có kiểu dữ liệu phù hợp với tham số của hàm.

Truyền đối số cho hàm ở dạng giá trị. Có thể truyền hằng, biến, biểu thức nhưng tham số của hàm chỉ sẽ nhận giá trị. Truyền tham trị được sử dụng khi không có nhu cầu thay đổi giá trị của tham số sau khi thực hiện hàm.

Chương trình C++ minh họa truyền tham trị

#include <iostream> using namespace std; void passByValue(int x){ x++; } int main() { int a = 10; passByValue(a); //pass 'a' variable to function cout<<"Value of 'a' variable is not changed, a = "<<a; system("pause"); }
Kết quả
Value of 'a' variable is not change, a = 10

Khi sử dụng tham trị:

– Những biến thuộc về hàm sẽ được khởi tạo và lưu trữ giá trị trong quá trình thực thi hàm nên gây tốn thêm vùng nhớ. Những biến thuộc về hàm sẽ được hủy khi hàm thực thi xong.

– Cách duy nhất để lấy được đầu ra (output) từ hàm là thông qua từ khóa return với hàm có kiểu trả về.

Truyền đối số cho hàm ở dạng địa chỉ (con trỏ). Được bắt đầu bằng toán tử & trong khai báo. Khi gọi hàm, phải truyền vào tên biến, không được truyền giá trị cho tham số này. Truyền tham chiếu được sử dụng khi có nhu cầu thay đổi giá trị của tham số sau khi thực hiện hàm.

Chương trình C++ minh họa truyền tham chiếu

#include <iostream> using namespace std; void passByValue(int &x){ x++; } int main() { int a = 10; passByValue(a);//pass 'a' variable to function cout<<"Value of 'a' variable is changed, a = "<<a; system("pause"); }
Kết quả
Value of 'a' variable is changed, a = 11

Khi sử dụng tham chiếu:

– Khi gọi hàm, những biến truyền tham chiếu sẽ không cần khởi tạo và lưu trữ một lần nữa nên tiết kiệm bộ nhớ và hoạt động nhanh hơn.

– Có thể trả về nhiều giá trị trong một lần gọi hàm.

– Trong một hàm, các tham số có thể truyền theo nhiều cách.

void HonHop(int x, int &y) { x++; y++; }

– Sử dụng tham chiếu là một cách để trả về giá trị cho chương trình.

int TinhTong(int x, int y)//không truyền tham chiếu, phải return giá trị { return x + y; } //biến tong truyền tham trị, sẽ lưu giá trị khi ra void TinhTong(int x, int y, int &tong)khỏi hàm { tong = x + y; } void TinhTongHieu(int x, int y, int &tong, int &hieu)//biến tong và hieu truyền tham trị { tong = x + y; hieu = x – y; }

Tham số mặc định là tham số có một giá trị khởi tạo tại thời điểm khai báo.

Khi người dùng không cung cấp đối số cho tham số mặc định, giá trị mặc định sẽ được sử dụng.

Khi người dùng cung cấp đối số cho tham số mặc định, tham số sẽ được gán lại bằng giá trị của đối số được truyền vào.

Cách khai báo tham số mặc định

Để khai báo tham số mặc định cho hàm, sử dụng toán tử gán “=”.

void printValue(int x, int y = 10) { cout << "x: " << x << endl; cout << "y: " << y << endl; }

Tham số thứ 2 của hàm printValue có giá trị mặc định nên khi gọi hàm, có thể chỉ truyền vào 1 đối số cho tham số x. Hoặc truyền đối số cho cả tham số x và y.

printValue(5);//truyền đối số cho x printValue(5, 5);//truyền đối số cho cả x và y

Trường hợp khai báo tham số mặc định không hợp lệ

void printValue(int x = 10, int y) //Invalid { cout << "x: " << x << endl; cout << "y: " << y << endl; } // Invalid void add(int a, int b = 3, int c, int d); // Invalid void add(int a, int b = 3, int c, int d = 4); // Valid void add(int a, int c, int b = 3, int d = 4);

Lưu ý: Mọi tham số mặc định khi khai báo phải đặt phía sau tham số không có giá trị mặc định.

Bài trước và bài sau trong môn học