[Basic] Tham số, đối số và cách truyền đối số cho hàm trong C++

Tham số (Parameters) và Đối số (Arguments)

Khi làm việc với hàm trong C++ có 2 khái niệm mà chúng ta hay nhầm lẫn đó là tham số và đối số. Việc nhầm lẫn đó không có gì nghiêm trọng, tuy nhiên ta cũng nên hiểu đôi chút về 2 khái niệm đó để có thể phân biệt 1 cách chính xác hơn.

Tham số (Parameters) là các biến được khai báo khi định nghĩa hàm.

Ví dụ:

//x, y là tham số 
int Add (int x, int y)
{
   
   return x + y;

}

Đối số (Arguments) là giá trị được truyền vào cho các tham số lúc gọi hàm;

Ví dụ:

int x = 10;

int y = 20;

int val = Add (x, y); //x,y là đối số

int val1 = Add (10,20); // 10, 20 là đối số

Truyền đối số cho hàm

Trong C++ hỗ trợ 3 cách truyền đối số cho hàm.

Truyền tham trị (Pass by value)

Mặc định truyền đối số cho hàm trong C++ là truyền tham trị. Khi truyền tham trị đối số sẽ được tạo ra 1 bản sao, hàm được gọi sẽ chỉ thao tác trên bản sao của đối số tạo ra mà không ảnh hưởng đến đối số gốc truyền vào.

=> Nếu trong hàm ta thay đổi giá trị của đối số truyền vào thì khi kết thúc hàm giá trị của đối số vẫn không thay đổi.

Ví dụ

#include <iostream>

using namespace std;

void Func(int val)
{
 
   //Thay đổi giá trị đối số truyền vào
   val++;
 
   cout << "Gia tri bien val trong ham : " << val << endl;

}

int main()
{
 
   int val = 10;
 
   cout << "Gia tri bien val truoc khi goi ham : " << val << endl;
 
   Func(val);
 
   cout << "Gia tro bien val sau khi goi ham : " << val << endl;
 
   cout << "Gia trị bien val truoc khi gọi ham : " << val << endl; 
 
   return 0;

}

Kết quả:

Gia tri bien val truoc khi goi ham : 10
Gia tri bien val trong ham : 11
Gia tro bien val sau khi goi ham : 10

Truyền tham chiếu (Pass by reference)

Khi truyền tham chiếu, đối số sẽ KHÔNG được tạo ra bản sao, mà hàm sẽ thao tác trên địa chỉ thực của đối số.

=> Nếu trong hàm thay đổi giá trị của đối số thì kết thúc hàm giá trị của đối số sẽ thay đổi theo.

Ví dụ:

#include <iostream>

using namespace std;

//Hàm có tham số là tham chiếu
void Func(int& val)
{
 
   //Thay đổi giá trị đối số truyền vào
   val++;
 
   cout << "Gia tri bien val trong ham : " << val << endl;

}

int main()
{
 
   int val = 10;
 
   cout << "Gia tri bien val truoc khi goi ham : " << val << endl;
 
   Func(val);
 
   cout << "Gia tro bien val sau khi goi ham : " << val << endl;
 
   return 0;
}

Kết quả:

Gia tri bien val truoc khi goi ham : 10
Gia tri bien val trong ham : 11
Gia tro bien val sau khi goi ham : 11

Truyền địa chỉ (Pass by address)

Tham số của hàm là con trỏ.

Khi truyền đối số là con trỏ, 1 bản sao của con trỏ sẽ được tạo ra. Hàm sẽ thao tác trên bản sao của con trỏ. Tuy nhiên địa chỉ mà con trỏ trỏ vào không được sao chép mà con trỏ vẫn trỏ trực tiếp vào địa chỉ thực mà nó đã trỏ vào trước đó.

=> Nếu trong hàm ta sử dụng con trỏ thay đổi giá trị của vùng nhớ nó trỏ vào thì kết thúc hàm giá trị tại vùng nhớ đó cũng thay đổi theo.

Ví dụ:

#include <iostream>

using namespace std;

void Func(int* ptr)
{
 
   //Thay đổi giá trị tai dia chỉ con tro tro toi
   *ptr = 20;
 
   cout << "Gia tri bien val trong ham : " << *ptr << endl;

}

int main()
{
 
   int val = 10;
 
   int* ptr = &val; //ptr tro toi dia chi bien val
 
   cout << "Gia tri bien val truoc khi goi ham : " << val << endl;
 
   Func(ptr);
 
   cout << "Gia tro bien val sau khi goi ham : " << val << endl;
 
   return 0;

}

Kết quả:

Gia tri bien val truoc khi goi ham : 10
Gia tri bien val trong ham : 20
Gia tro bien val sau khi goi ham : 20

Chú ý:

Vì con trỏ khi truyền vào hàm sẽ tạo ra 1 bản sao, nếu ta trong hàm ta thay đổi địa chỉ trỏ vào của con trỏ (thay đổi giá trị con trỏ) hoặc cấp phát bộ nhớ cho con trỏ thì kết thúc hàm giá trị của con trỏ vào vẫn không thay đổi.

Ví dụ:

#include <iostream>

using namespace std;

void Func(int* ptr)
{
 
   ptr = new int[5];
 
   if (ptr != nullptr)
   {
 
      cout << "Da cap phat bo nho trong ham" << endl;
 
   }

}

int main()
{
 
   int* ptr = nullptr;
 
   Func(ptr);
 
   if (ptr == nullptr)
   {
 
      cout << "Con tro ptr null" << endl;
 
   }
 
   return 0;

}

Kết quả:

Da cap phat bo nho trong ham
Con tro ptr null

Ví dụ trên con trỏ ptr đã được cấp phát bộ nhớ trong hàm, tuy nhiên sau khi thực hiện hàm con trỏ vẫn null. Lúc này ta có thề truyền tham chiếu hoặc địa chỉ của con trỏ ptr.

Ví dụ:

#include <iostream>

using namespace std;

void Func(int* &ptr)
{
 
   ptr = new int[5];
 
   if (ptr != nullptr)
   {
 
      cout << "Da cap phat bo nho trong ham" << endl;
 
   }

}

int main()
{
 
   int* ptr = nullptr;
 
   Func(ptr);
 
   if (ptr == nullptr)
   {
 
      cout << "Con tro ptr null" << endl;
 
   }
   else
   {
 
      cout << "Con tro ptr da duoc cap phat bo nho" << endl;
 
   }
 
   return 0;

}

Kết quả:

Da cap phat bo nho trong ham
Con tro ptr da duoc cap phat bo nho

Was this article helpful?

Leave A Comment?