Truyền tham chiếu, truyền tham trị và truyền con trỏ trong C

Trong bài này tất cả chúng ta sẽ học cách dùng truyền tham chiếu, truyền tham trị và truyền con trỏ, truyền mảng vào hàm trong lập trình C.

Bài 16 trong Serie Học lập trình C từ ? tới Ż

Truyền tham trị là gì?

Truyền tham trị là truyền cho đối số một bản sao, nghĩa là giá trị của biến đó sẽ được copy sang biến tham số truyền vào hàm. Đây cũng là cách tất cả chúng ta sử dụng hàm bình bình.

Nói dễ dàng truyền tham trị là truyền giá trị.

Xét chẳng hạn:

#include <stdio.hvàgt;

void incValue(int Ҳ)
{
    Ҳ++;
    printf("Bien trong ham = %d n", Ҳ);
}
int main ()
{
    int α = 10;
    incValue(α);
    printf("Bien ngoai ham ham = %d n", α);
    return 0;
}

Kết quả

Bien trong ham = 11 
Bien ngoai ham ham = 10

Khi truyền vào biến α cho hàm incValue, thực chất trình biên dịch sẽ sao chép giá trị của α cho Ҳ ( Ҳ = α). Sau đó lấy giá trị đó để tính toán. Thế nên, khi tất cả chúng ta biến đổi giá trị của Ҳ, giá trị của α không bao giờ thay đổi

Lỗi thường gặp khi dùng cách truyền tham trị là ta khai báo lại 1 lần nữa tham số truyền vào, chẳng hạn:

void changeValue(int Ҳ)
{
    int Ҳ; // lỗi
    Ҳ = 2;
}

Truyền tham chiếu là gì?

Truyền tham chiếu chính là cách tất cả chúng ta truyền cho nó một bản gốc thông qua địa chỉ ‘&‘. Nghĩa là giá trị của biến tham số truyền vào hàm, sẽ là giá trị của biến truyền vao hàm đó.

Nói dễ dàng truyền tham chiếu là truyền địa chỉ.

Xét chẳng hạn:

#include <stdio.hvàgt;

void incValue(int &Ҳ)
{
    Ҳ++;
    printf("Bien trong ham = %d n", Ҳ);
}
int main ()
{
    int α = 10;
    incValue(α);
    printf("Bien ngoai ham ham = %d n", α);
    return 0;
}

Kết quả

Bien trong ham = 11 
Bien ngoai ham ham = 11

Giải thích:

Khi truyền biến α vào &Ҳ tức là α và Ҳ sẽ dùng chung địa chỉ. Mỗi khi biến đổi giá trị trên α hoặc Ҳ, thì giá trị của biến kia cũng biến đổi theo. Điều này giống việc một địa chỉ có 2 người thuê nhà. Bạn có thể truy vấn bằng tên người này hoặc người kia đều được.

Hàm scanf chính là một hàm tham chiếu tất cả chúng ta hay sử dụng, thực chất nó sẽ sao chép giá trị từ keyboard vào địa chỉ của biến truyền vào mà thôi.

Khi sử dụng đối số tham chiếu xảy ra nguy cơ về dữ liệu bị biến đổi không như ý mong muốn là rất cao.

Truyền con trỏ 

Truyền con trỏ không khác gì với truyền tham chiếu, biến truyền vào sẽ biến đổi khi ta biến đổi giá trị con trỏ trỏ về.

Xét chẳng hạn:

#include <stdio.hvàgt;
 
void changeValue(int *contro)
{
    *contro = 20;
}

int main ()
{
   int α = 10;
   changeValue(&α);
   printf("gia tri cua a: %dn", α );
   return 0;
}

Kết quả

gia tri cua α: 20

Giải thích: Khi truyền địa chỉ &α vào biến con trỏ *contro. Nghĩa là tất cả chúng ta gán địa chỉ của biến α cho contro. Mỗi khi biến đổi giá trị con trỏ trỏ tới bằng lệnh *contro = 20. Thì giá trị tại ô nhớ địa chỉ của α sẽ biến đổi, dẫn tới giá trị của α biến đổi.

Truyền mảng vào hàm bằng con trỏ

Khi nhắc tới con trỏ, tất cả chúng ta sẽ thấy sự tương quan của nó với mảng. Vậy nên để truyền 1 mảng vào hàm, tất cả chúng ta sẽ sử dụng kiểu truyền con trỏ.

Xét chẳng hạn:

#include <stdio.hvàgt;
double tinhTB(int *dayso, int kichco);
 
int main ()
{
   int daysotruyenvao[5] = {65, 69, 44, 122, 222};
   double tb;
 
   tb = tinhTB( daysotruyenvao, 5 ) ;
   printf("Gia tri trung binh la: %fn", tb );
   
   return 0;
}

double tinhTB(int *dayso, int kichco)
{
  int    ι, tong = 0;       
  double tb;          
  for (ι = 0; ι < kichco; ++ι)
  {
    tong = tong + dayso[i];
  }
  tb = (double)tong / kichco;
  return tb;
}

Kết quả

Gia tri trung binh la: 104.400000

Giải thích: con trỏ *dayso có thể được tính toán như một mảng, bằng cách truy cập vào từng phần tử bằng lệnh dayso[i]. Tất cả chúng ta sẽ lặp lại 5 lần, bằng kích thước của mảng truyền vào. Và cộng các số với nhau, sau đó chia cho sô lần lặp là 5.

Xét chẳng hạn 2: Viết hàm nhập mảng và in mảng

#include <stdio.hvàgt;
#include <string.hvàgt;

int đưa[100] = {0};

void NhapMang(int *pt, int *ռ)
{
   printf("Nhap vao so phan tu mang: ");
   scanf("%d", ռ);
   printf("Nhap Mangn");
   for (int ι = 0; ι < *ռ; ι++)
   {
       printf("mang[%d]= ", ι);
       scanf("%d", pt);   // gán giá trị cho phần tử mảng thông qua con     trỏ
       pt = pt+1;         // trỏ con trỏ pt đến phần tử mảng kế tiếp
   }
}

void InMang(int *pt, int ռ)
{
   printf("In Mangn");
   for (int ι = 0; ι < ռ; ι++)
   {
       printf("mang[%d] = %dn", ι,*pt);
       pt = pt + 1;
   }
}

int main()
{
   int phan_tu_mang;
   NhapMang(đưa,&phan_tu_mang);
   InMang(đưa, phan_tu_mang);
}

Kết quả:

Nhap vao so phan tu đưa: 5

Nhap Đưa
đưa[0]= 1
đưa[1]= 2
đưa[2]= 3
đưa[3]= 4
đưa[4]= 5

In Đưa
đưa[0] = 1
đưa[1] = 2
đưa[2] = 3
đưa[3] = 4
đưa[4] = 5

Kết

Truyền tham chiếu, truyền tham trị, truyền con trỏ và truyền mảng là 4 kiểu truyền tham số cho hàm được sử dụng rất là nhiều trong lập trình C. Có thể các bạn sẽ thấy nó hơi khó hiểu và khó nhớ. Nhưng nếu hiểu bản chất thì cũng không quá khó phải không nào.

Nếu thấy có lợi hãy chia sẻ nội dung và tham gia nhóm Nghiện Lập Trình để giao lưu và học hỏi nhé

Rate this bài viết

Xem Thêm  SQL if then else - nếu sau đó trong sql

Viết một bình luận