TRUYỀN THAM SỐ CẤU TRÚC CHO HÀM

Một phần của tài liệu giáo trình lập trình C (Trang 286 - 300)

SỬ DỤNG HÀM TRONG C

CHƯƠNG 7 KIỂU DỮ LIỆU CẤU TRÚC

7.4 TRUYỀN THAM SỐ CẤU TRÚC CHO HÀM

Kiểu tham số của một hàm có thể là cấu trúc. Đây là một phương tiện hữu dụng khi ta muốn truyền một nhóm các thành phần dữ liệu có quan hệ logic với nhau thông qua một biến thay vì phải truyền từng thành phần một.

7.4.1 Truyền biến cấu trúc vào hàm

Tương tự như các kiểu dữ liệu khác, một biến cấu trúc có thể được truyền vào hàm theo hình thức tham chiếu hoặc tham trị.

 Truyền theo tham trị

Như đã đề cập trong chương 4, bản chất của việc truyền theo tham trị là khi hàm được gọi, giá trị của các đối số sẽ được truyền vào hàm thông qua các biến tạm (giá trị của các đối số được sao chép sang các biến tạm và truyền vào hàm).Như vậy, khi một biến cấu trúc được truyền vào hàm theo hình thức tham trị, hàm chỉ có thể sử dụng chứ không có khả năng thay đổi giá trị của biến cấu trúc đó trong hàm gọi.

Giả sử fact là biến có kiểu cấu trúc Fractionở trên, bây giờ nếu muốn truyền biến này vào một hàm func()bất kỳ trong chương trình theo hình thức tham trị thì nguyên mẫu của hàm phải được định nghĩa như sau:

<Kiểu trả về> func(struct

Fraction fact) {

/*Các câu lệnh*/

}

Hình thức gọi hàm và truyền tham số như sau:

void main(){

struct Fractionfact;

func(fact);

}

Chú ý, nếu kiểu cấu trúc được định nghĩa với từ khóa typedef thì không cần nhắc lại từ khóa struct trước khai báo biến cấu trúc.

145

Ví dụ 7.8:

#include

<stdio.h

>typedef struct{

int numerator,

denominator; }

Fraction;

void Sum(Fraction f1,

Fraction f2){

Fraction fs;

fs.numerator=f1.numerator*f2.de nominator+

f1.denominator*f2.numerator;

fs.denominator =

f1.denominator*f2.denominator;

printf("\n--- ----\n");

printf("\n%d/%d+%d/%d=%d/

%d\n",f1.numerator,f1.denominator,f2.nume rator,f2.denominator,

fs.numerator,fs.denominator);

} int main(){

Fraction fact1, fact2;

printf ("Input the fraction

1th:\n ");

printf("\nnumerator = ");

scanf("%d", &fact1.numerator);

printf("\ndenominator = ");

scanf("%d", &fact1.denominator);

printf ("\nInput the fraction 2th:\n"); printf("\nnumerator

= ");

scanf("%d",

&fact2.numerator);

printf("\ndenominator

= "); scanf("%d",

&fact2.denominator);

Sum(fact1, fact2);

}

Đoạn mã trên khai báo fact1fact2 là haibiến có kiểu cấu trúc phân số Fraction. Chương trình yêu cầu người dùng nhập giá trị cho các biến, sau đó chúng được truyền vào hàm Sum().Hàm này nhận vào haiphân số (haiđối số kiểu Fraction), tính tổng của chúng và hiển thị giá trị tính được ra màn hình.

Kết quả thực hiện của đoạn mã trên như sau:

Input the fraction 1th:

numerator = 1

denominator = 2

Input the

fraction 2th:

numerator =

1

denominator = 3

--- ---

1/2+1/3 = 5/6

 Truyền theo tham chiếu

Khi một biến cấu trúc được truyền vào hàm dưới dạng tham chiếu thì địa chỉ của nó sẽ được truyền vào hàm một cách trực tiếp (sử dụng phép toán &) hoặc gián tiếp thông qua con trỏ. Với hình thức truyền theo tham chiếu, hàm được phép truy xuất đến vùng bộ nhớ thực của các đối số và vì vậy có thể thay đổi giá trị của các đối số của hàm gọi.

Truyền trực tiếp địa chỉ của biến cấu trúc vào hàm 146

Giả sử fact là biến có kiểu cấu trúc phân sốFraction, để truyền trực tiếp địa chỉ của biến cấu trúc factvàohàmfunc()thìnguyên mẫu hàm phải được định nghĩa như sau:

<Kiểu trả về>func(struct Fraction&fact) {

/*Các câu lệnh*/

}

Hình thức gọi hàm và truyền tham số hoàn toàn giống như cách thức truyền tham trị:

void main() {

struct Fractionfact;

func(fact);

}

Chương trình sau khai báo một mảng các cấu trúc kiểu phân số Fraction, sau đó sử dụng hàm Sum_All() để tính tổng của tất cả các phân số đã nhập. Sau khi thực hiện xong, hàm gọi main() sẽ nhận lại kết quả tính toán và hiển thị ra màn hình.

Ví dụ 7.9:

#include

<stdio.h

>typedef struct{

int numerator,

denominator; }

Fraction;

void Sum_All(Fraction f, Fraction &fs){

Fraction sum;

sum.numerator=f.numerator*fs.de nominator+

f.denominator*fs.numerator;

sum.denominator =

f.denominator*fs.denominator;

fs.numerator = sum.numerator;

fs.denominator = sum.denominator;

}int main(){

Fraction fact_ary[100], fact_sum; int i, n;

printf("Enter n = ");

scanf("%d", &n); for (i=0;

i<n; i++){

printf("\nInput the fraction

%dth:\n ",i+1);

printf("\nnumerator=");

scanf("%d",

&fact_ary[i].numerator);

printf("\ndenominator =

");

scanf("%d",&fact_ary[i].denominator);

fact_sum.numerator = fact_ary[0].numerator; }

fact_sum.denominator =

fact_ary[0].denominator; for (i=1;

i<n; i++)

Sum_All(fact_ary[i],fact_sum);

printf("\n--- ---\n"); printf("Sum=%d/

%d\n",fact_sum.numerator, fact_sum.denominator);

}

147

Trong chương trình trên, hàm sum_all() nhận hai đối số kiểu cấu trúc Fraction. Trong đó, đối số thứ nhất được truyền vào hàm theo tham trị, đối số thứ hai được truyền theo tham chiếu. Khi hàm được gọi, giá trị các phần tử mảng sẽ được truyền vào cho đối số thứ nhất, đối số thứ hai là giá trị tổng hiện thời. Trong bước tính toán, giá trị của phần tử mảng sẽ được cộng vào tổng hiện thời, có nghĩa là giá trị của đối số thứ haisẽ được cập nhật sau mỗi bước tính toán và tiếp tục được sử dụng trong những lần gọi hàm tiếp theo.

Kết quả thực hiện của chương trình trên như sau:

Enter n = 4

Input the

fraction 1th:

numerator = 1

denominator = 2

Input the

fraction 2th:

numerator = 1

denominator = 3

Input the

fraction 3th:

numerator = 1

denominator = 4

Input the

fraction 4th:

numerator = 1

denominator = 5

--- ---

Sum = 154/120

Truyền địa chỉ của biến cấu trúc vào hàm thông qua con trỏ

Tương tự như trên, giả sử fact là biến có kiểu cấu trúc phân sốFraction, để

truyền biến

tham chiếu factvào hàmfunc()thông qua con trỏ thì nguyên mẫu hàm phải được

định nghĩa

như sau:

<Kiểu trả về>func(struct Fraction*fact)

{

/*Các câu lệnh*/

}

Hình thức gọi hàm và truyền tham số hoàn toàn giống như cách thức truyền tham trị:

void main()

{ struct Fractionfact;

func(&fact);

}

Chú ý, do biến fact được truyền vào hàm func() ở dạng con trỏ nên muốn truy xuất đến giá trị của nó cần phải sử dụng toán tử * trước tên biến.

Chương trình sau đây sẽ khai báo một mảng các cấu trúc kiểu phân số Fraction, nhập giá trị cho các phần tử mảng từ bàn phím, sắp xếp mảng theo chiều tăng dần và hiển thị mảng được sắp ra màn hình. Hàm Swap() nhận vào hai biến cấu trúc Fraction theo hình thức tham chiếu, hoán đổi vị trí của chúng và trả về kết quả cho hàm gọi - hàm main().

148

Ví dụ 7.10:

#include

<stdio.h>

typedef struct{

int numerator, denominator; }Fraction;

void Swap(Fraction *f1, Fraction *f2){

Fraction tmp;

tmp = *f1;

*f1 = *f2;

2 *f= tmp;}

int main(){

Fraction fact_ary[100], fact_sum; int i, j, n;

printf("Enter n = ");

scanf("%d", &n); for (i=0;

i<n; i++){

printf("\nInput the fraction %dth:\n

",i+1); printf("\nnumerator = ");

scanf("%d",

&fact_ary[i].numerator);

printf("\ndenominator = ");

scanf("%d",&fact_ary[i].denominator);

}

printf("\nBefore sort:\n"); for (i=0; i<n; i++)

printf("%d/

%d",fact_ary[i].numerator, fact_ary[i].denominator);

for (i=0; i<n-1; i++) for (j=i+1; j<n; j++)

if(fact_ary[i].numerator*fact_ary[j].deno minator> fact_ary[j].numerator*

fact_ary[i].denominator)

swap(fact_ary[i], fact_ary[j]);

printf("\nAfter sort:\n"); for (i=0; i<n; i++)

printf("%d/

%d",fact_ary[i].numerator, fact_ary[i].denominator);

}

Kết quả thực hiện của chương trình như sau:

Enter n = 4

Input the

fraction 1th:

numerator = 3

denominator = 5

Input the

fraction 2th:

numerator = 4

denominator = 9

Input the

fraction 3th:

numerator = 6

denominator = 7

Input the

fraction 4th:

numerator = 2

denominator = 3

149

Before sort:

3/5 4/9 6/7 2/3 After sort:

4/9 3/5 2/3 6/7

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

Việc truyền một mảng cấu trúc hàm cũng tương tự như truyền các mảng có kiểu dữ liệu khác vào hàm.

Giả sử fact_ary là một mảng kiểu cấu trúc Fraction, func() là một hàm nhận đối số là một mảng cấu trúc Fraction. Khi đó nguyên mẫu hàm sẽ được khai báo như sau:

<Kiểu trả về>func(struct Fraction fact[]) {

/*Các câu lệnh*/

} Hoặc:

<Kiểu trả về>func(struct Fraction fact[100])

{

/*Các câu lệnh*/

}

Khi hàm được gọi, tên của mảng được truyền vào hàm:

void main(){

struct Fractionfact[100];

func(fact);

}

Chương trình sau đây sẽ khai báo một mảng kiểu cấu trúc Fraction.

Mảng này được truyền vào hàm Input() để nhập giá trị cho các phần tử, sau đó được tiếp tục được truyền vào hàm Display()để hiển thị giá trị của các phần tử ra màn hình.

Ví dụ 7.11:

#include

<stdio.h

>

typedef struct{

int numerator,

denominator; }

Fraction;

void Input(Fraction ary[], int n){

printf("Call Input() function:\n"); for (int i=0; i<n; i++){

printf("\nInput the fraction %dth:\n ",i);

printf("\nnumerator = "); scanf("%d",

&ary[i].numerator); printf("\ndenominator = ");

scanf("%d",&ary[i].denominator);

} }

void Display(Fraction ary[100], int n){

printf("Call Display() function:\n"); for (int i=0; i<n; i++)

printf("%d/%d",ary[i].numerator, ary[i].denominator);

}

int main(){

Fraction fact_ary[100], fact_sum;

150

int n;

printf("Enter n = ");

scanf("%d", &n);

Input(fact_ary, n);

Display(fact_ary, n);

}

Kết quả thực hiện của chương trình như sau:

Enter n = 4

Call Input() function: Input the fraction 1th: numerator = 1

denominator = 2

Input the

fraction 2th:

numerator = 1

denominator = 3

Input the

fraction 3th:

numerator = 1

denominator = 4

Input the

fraction 4th:

numerator = 1

denominator = 5

Call Display() function: 1/2 1/3 1/4 1/5

151

Một phần của tài liệu giáo trình lập trình C (Trang 286 - 300)

Tải bản đầy đủ (DOCX)

(339 trang)
w