Bài 8: Chương trình con – Hàm

0
3330

Một chương trình viết trong ngôn ngữ C là một dãy các hàm, trong đó có một hàm chính (hàm main()). Hàm chia các bài toán lớn thành các công việc nhỏ hơn, giúp thực hiện những công việc lặp lại nào đó một cách nhanh chóng mà không phải viết lại đoạn chương trình. Thứ tự các hàm trong chương trình là bất kỳ, song chương trình bao giờ cũng đi thực hiện từ hàm main(). Trong C chương trình con chỉ tồn tại dới dạng hàm chứ không có thủ tục.

Hàm có thể xem là một đơn vị độc lập của chương trình. Các hàm có vai trò ngang nhau, vì vậy không có phép xây dựng một hàm bên trong các hàm khác.

 

8.1 Khai báo và định nghĩa hàm

Xây dựng một hàm bao gồm: khai báo kiểu hàm, đặt tên hàm, khai báo các đối và đưa ra câu lệnh cần thiết để thực hiện yêu cầu đề ra cho hàm. Một hàm được viết theo mẫu sau:

 

                 <Kiểu_trả_về>  <tên_hàm> ( [khai báo các tham số hình thức])

 

{

[Khai báo các biến cục bộ]

[Các câu lệnh]

[return[biểu thức];]

}

 

Giải thích:

–     <Kiểu_trả_về>: giá trị kiểu dữ liệu của dữ liệu sẽ trả về cho hàm

–      <tên_hàm>: tên của hàm mà bạn muốn định nghĩa, được đặt theo qui tắc đặt tên của C

–      [khai báo các tham số hình thức]: các tham số hình thức và kiểu của chúng

–      [Khai báo các biến cục bộ]: khai báo các biến cục bộ, các biến này chỉ có tác dụng trong nội bộ hàm

–      [return]: là lệnh thực hiện gán giá trị trả về cho hàm

–      [biểu thức]: là giá trị trả về cho hàm, có thể là biến, hằng, biểu thức nhưng phải có giá trị xác định và có kiểu dữ liệu là kiểu đã khai báo cho hàm.

 

Ví dụ 1: Hàm tìm giá trị lớn nhất giữa hai giá trị

 

int tim_max(int a, int b)

{

if(a>=b)

return a;

else

return b;

}

 

@ Lưu ý:

– Hàm có thể có giá trị trả về hoặc không, giá trị trả về phải cùng kiểu với kiểu trả về đã khai báo hàm. Nếu hàm không có giá trị trả về thì đặt từ khóa void trước tên hàm để báo hiệu là hàm không cần giá trị trả về cho hàm.

– Khi hàm khai báo không có kiểu ở trước nó thì nó được mặc định là kiểu int.

– Không nhất thiết phải khai báo nguyên mẫu hàm. Nhưng nói chung nên có vì nó cho phép chương trình biên dịch phát hiện lỗi khi gọi.

– Nguyên mẫu của hàm thực chất là dòng đầu tiên của hàm thêm vào dấu;. Tuy nhiên, trong nguyên mẫu có thể bỏ tên các tham số hình thức.

 

Ví dụ 2: Hàm in ra dãy số từ 1 đến n

 

void In_dayso(int n)

{

for(int i=1;i<=n;i++)

Printf(“%d”,i);

}

Hàm này không cần có giá trị trả về nên ta khai báo từ khóa void trước tên hàm.

 

8.2 Lời gọi hàm

Cú pháp:

                     tên hàm ([Danh sách các tham số thực])

 

Danh sách các tham số thực phải bằng số tham số hình thức và lần lượt chúng có kiểu tương ứng với nhau.

 

Ví dụ 3

#include <stdio.h>

#include <conio.h>

// khai bao prototype

int tim_max(int a, int b);

void main(void)

{

int a=5, b=7;

printf(“Max là %d ”,tim_max(a,b));

getch();

}

// ham so sanh a và b

int tim_max(int a, int b)

{

if(a>=b)

return a;

else

return b;

}

 

8.3 Tham số hình thức, tham số thực và biến cục bộ

Các tham số dùng khi khai báo hàm được gọi là tham số hình thức. Các tham số được cung cấp cho hàm khi gọi hàm là tham số thực. Tham số thực có thể là một biểu thức, trong khi tham số hình thức thì không thể là 1 biểu thức. Dãy các tham số thực phải tương ứng về kiểu với tham số hình thức.

Có những hàm không cần có tham số. Vì vậy, khi khai báo ta có thể dùng từ khóa void để báo rằng hàm không cần tham số.

 

Ví dụ 4: Hàm in ra bảng cửu chương 2

 

void in_cuuchuong2(void)

{

for(int i=1;i<=10;i++)

printf(“2 x %d = %d\n”, i, i*2);

}

 

Biến cục bộ là biến chỉ có phạm vi hoạt động trọng nội bộ hàm, được khia báo bên trong hàm. Do tham số thực và biến cục bộ đều có phạm vi hoạt động trong cùng một hàm nên tham số thực và biến cục bộ cần có tên khác nhau.

Tham số hình thức và biến cục bộ có thể trùng tên với các đại lượng ngoài hàm mà không gây ra nhầm lẫn nào.

Khi một hàm được gọi tới, việc đầu tiên là giá trị của các tham số thực được gán cho các tham số hình thức. Như vậy các tham số hình thức chính là các bản sao của các tham số thực.  Hàm chỉ làm việc trên các tham số hình thức.

Các tham số hình thức có thể bị biến đổi trong thân hàm, còn các tham số thực thì không bị thay đổi.

 

Ví dụ 5:

 

#include <stdio.h>

#include <conio.h>

// khai bao prototype

int power(int, int);

void main(void)

{

printf(“2 mu 2 = %d.\n”, power(2, 2));

printf(“2 mu 3 = %d.\n”, power(2, 3));

getch();

}

// ham tinh so mu

int power(int ix, int in)

{

int i, ip = 1;

for(i = 1; i <= in; i++)

ip *= ix; //tương đương với ip=ip*ix

return ip; //giá trị trả về cho hàm

}

 

Giải thích chương trình:

Hàm power có hai tham số truyền vào là ix, in có kiểu int và kiểu trả về cũng có kiểu int.

Dòng lệnh: return ip, trả về giá trị sau khi tính toán

Hai tham số ix, in của hàm power là dạng truyền tham trị.

 

Ví dụ 6:

 

#include <stdio.h>

#include <conio.h>

// khai bao prototype

void time(int & , int &);//co the k can ghi tham so hinh thuc

// ham doi phut thanh gio:phut

void time(int &ig, int &ip)

{

ig = ip/60;

ip %= 60;

}

void main(void)

{

int igio, iphut;

printf(“Nhap vao so phut: “);

scanf(“%d”, &iphut);

time(igio, iphut);

printf(“%02d:%02d\n”, igio, iphut);

getch();

}

 

Giải thích chương trình:

Hàm time có hai tham số hình thức là ig, ip có kiểu int. 2 tham số này có toán tử địa chỉ & đi trước cho biết 2 tham số này là dạng truyền tham biến.

 

8.4 Quy tắc hoạt động của hàm

Khi gặp một lời gọi hàm thì nó sẽ bắt đầu được thực hiện. Nói cách khác, khi máy gặp lời gọi hàm ở một vị trí nào đó trong chương trình, máy sẽ tạm dời chỗ đó và chuyển đến hàm tương ứng. Quá trình đó diễn ra theo trình tự sau:

–   Cấp phát bộ nhớ cho các biến cục bộ.

–   Gán giá trị của các tham số thực cho các tham số hình thức tương ứng.

–   Thực hiện các câu lệnh trong thân hàm.

–   Khi gặp câu lệnh return hoặc dấu } cuối cùng của thân hàm thì máy sẽ xoá các tham số hình thức, biến cục bộ và ra khỏi hàm.

Nếu trở về từ một câu lệnh return có chứa biểu thức thì giá trị của biểu thức được gán cho hàm. Giá trị của hàm sẽ được sử dụng trong các biểu thức chứa nó.

 

8.5 Bài tập thực hành:

Viết lại các bài tập ở bài số 6 & 7 dưới dạng hàm.

Leave a Reply