Giống như tất cả các kiểu khác, chúng ta có thể truyền cấu trúc dưới dạng đối số cho một hàm. Trên thực tế, chúng ta có thể truyền các phần tử của cấu trúc hay một biến cấu trúc hoặc một con trỏ đến cấu trúc…. vào hàm.

Các hàm cũng có thể trả về một biến cấu trúc hoặc con trỏ đến cấu trúc.

1.Truyền các phần tử struct vào hàm

Ta hoàn toàn có thể truyền các giá trị của một struct vào hàm, thông qua toán tử (.) chấm.

Chương trình dưới đây, tôi có cấu trúc sinh viên bao gồm: Mã Sinh Viên, Tên Sinh Viên, Điểm Sinh Viên. Tôi sẽ truyền 3 thành phần đó của SV NguyenVanA vào hàm có tên “thông tin sinh viên” do tôi tự định nghĩa:

#include<stdio.h>
struct sinhvien{
    int MaSinhVien;
    char TenSinhVien[25];
    float DiemSinhVien;
};
typedef sinhvien SV;

//tao ham thong tin sinh vien co tham so: MaSinhVien,TenSinhVien,DiemSinhVien
void ThongTinSinhVien(int MaSinhVien, char TenSinhVien[], float DiemSinhVien)
{
    //hien thi thong tin
    printf("Ma sinh vien: %d\n", MaSinhVien);
    printf("Ten sinh vien: %s\n", TenSinhVien);
    printf("Diem sinh vien: %f\n", DiemSinhVien);
    printf("\n");
}

int main()
{
    //khai bao sinh vien NguyenVanA co kieu SV
    SV NguyenVanA = {1,"NguyenVanA", 10};
    //truyen cac thong tin cua NguyenVanA vao ham
    ThongTinSinhVien(NguyenVanA.MaSinhVien, NguyenVanA.TenSinhVien, NguyenVanA.DiemSinhVien);
}
Ma sinh vien: 1

Ten sinh vien: NguyenVanA

Diem sinh vien: 10.000000

2.Truyền một biến struct vào hàm

Khi khởi tạo một biến mang kiểu dữ liệu là SV (như ở ví dụ trên). Ta có thể truyền trực tiếp biến cấu trúc đó vào hàm.

Ví dụ dưới đây, tôi sẽ khai báo một sinh viên NguyenVanA mang kiểu SV và truyền trực tiếp NguyenVanA vào hàm “thông tin sinh viên” do tôi định nghĩa:

#include<stdio.h>
struct sinhvien{
    int MaSinhVien;
    char TenSinhVien[25];
    float DiemSinhVien;
};
typedef sinhvien SV;

//tao ham thong tin sinh vien co tham so la bien co kieu SV
void ThongTinSinhVien(SV NguyenVanA)
{
    //hien thi thong tin bang toan tu (.)
    printf("Ma sinh vien: %d\n", NguyenVanA.MaSinhVien);
    printf("Ten sinh vien: %s\n", NguyenVanA.TenSinhVien);
    printf("Diem sinh vien: %f\n", NguyenVanA.DiemSinhVien);
    printf("\n");
}

int main()
{
    //khai bao sinh vien NguyenVanA co kieu SV
    SV NguyenVanA = {1,"NguyenVanA", 10};
    //truyen bien cau truc NguyenVanA vao ham
    ThongTinSinhVien(NguyenVanA);
}

Kết quả thu được tương tự như ví dụ đầu tiên, tuy nhiên ta thấy rằng cách truyền kiểu này rất dễ viết, dễ đọc.

Chú ý: Sau khi truyền một biến struct vào hàm ta sẽ sử dụng toán tử “.” (chấm) để truy cập vào các phần tử của struct

3.Truyền con trỏ struct vào hàm

Mặc dù việc truyền biến cấu trúc làm đối số vào một hàm ở phần trên đã có thể cho phép chúng ta chuyển tất cả các thành phần của cấu trúc đó đến một hàm tuy nhiên thao tác này lại gây ra một nhược điểm sau:

  1. Tạo ra một bản sao của cấu trúc đó khi truyền vào hàm. Trường hợp ta cần truyền đi truyền lại nhiều lần thì sẽ rất tốn thời gian thực thi chương trình.
  2. Cần có thêm bộ nhớ bổ sung để lưu mọi bản sao của cấu trúc.

Vì vậy, ta cần suy nghĩ đến việc sử dụng con trỏ để khắc phục những nhược điểm trên!

Ví dụ dưới đây được dựa theo ví dụ trên, tuy nhiên tôi sẽ truyền theo phương pháp truyền biến con trỏ cấu trúc vào trong hàm “thông tin sinh viên”:

#include<stdio.h>
struct sinhvien{
    int MaSinhVien;
    char TenSinhVien[25];
    float DiemSinhVien;
};
typedef sinhvien SV;
//tao ham thong tin sinh vien co tham so la con tro SV *p
void ThongTinSinhVien(SV *p)
{
    //hien thi thong tin
    printf("Ma sinh vien: %d\n", p->MaSinhVien);
    printf("Ten sinh vien: %s\n", p->TenSinhVien);
    printf("Diem sinh vien: %f\n", p->DiemSinhVien);
    printf("\n");
}

int main()
{
    //khai bao sinh vien NguyenVanA co kieu SV
    SV NguyenVanA = {1,"NguyenVanA", 10};
    //khai bao con tro p co kieu SV
    SV *p;
    //gan p bang dia chi cua NguyenVanA
    p = &NguyenVanA;
    //truyen con tro p vao ham
    ThongTinSinhVien(p);
}

Kết quả thu được tương tự ví dụ trên, tuy nhiên khi truyền kiểu con trỏ thì sẽ giải quyết được nhược điểm của việc truyền theo biến cấu trúc vào hàm (tôi đã đề cập ở trên).

Chú ý: Sau khi truyền con trỏ struct vào hàm ta sẽ sử dụng toán tử -> (mũi tên) để truy cập vào các thành phần của struct.

4.Truyền mảng cấu trúc vào hàm

Chúng ta đã biết cách truyền một mảng các số nguyên, số thực, ký tự…. cho một hàm. Tương tự, chúng ta có thể truyền một mảng cấu trúc cho một hàm.

Ví dụ dưới đây, tôi có một mảng gồm 5 sinh viên. Tôi sẽ thực hiện việc truyền mảng cấu trúc này vào hàm “thông tin sinh viên” do tôi tự định nghĩa:

#include<stdio.h>
struct sinhvien{
    int MaSinhVien;
    char TenSinhVien[25];
    float DiemSinhVien;
};
typedef sinhvien SV;

//tao ham thong tin sinh vien co tham so la mang co kieu SV
void ThongTinSinhVien(SV arr_sv[])
{
    //su dung vong lap de duyet 5 sinh vien
    for(int i = 0; i< 5; i ++){
        printf("Ma sinh vien: %d", arr_sv[i].MaSinhVien);
        printf("\nTen sinh vien: %s",arr_sv[i].TenSinhVien);
        printf("\nDiem sinh vien: %f",arr_sv[i].DiemSinhVien);
        printf("\n \n");
    }
}

int main()
{
    //khai bao mang sinh vien gom 5 sinh vien co kieu SV
    SV arr_sv[5] = {
        {1,"NguyenVanA", 10},
        {2,"NguyenVanB", 9},
        {3,"NguyenVanC", 7.2},
        {4,"NguyenVanD", 5.6},
        {5,"NguyenVanE", 4}
    };
    //truyen mang arr_sv vao ham
    ThongTinSinhVien(arr_sv);
}
Ma sinh vien: 1

Ten sinh vien: NguyenVanA

Diem sinh vien: 10.000000

Ma sinh vien: 2

Ten sinh vien: NguyenVanB

Diem sinh vien: 9.000000

Ma sinh vien: 3

Ten sinh vien: NguyenVanC

Diem sinh vien: 7.200000

Ma sinh vien: 4

Ten sinh vien: NguyenVanD

Diem sinh vien: 5.600000

Ma sinh vien: 5

Ten sinh vien: NguyenVanE

Diem sinh vien: 4.000000

Chú ý: Sau khi truyền mảng vào hàm, để sử dụng được mảng đó ta sẽ dùng vòng lặp for duyệt qua các phần tử thứ i có trong mảng (là các struct) và để truy cập vào các thành phần của struct thứ i đó ta sử dụng toán tử -> (mũi tên).