
Nguyen Dinh Phuong
Bài 15 Hàm
M c tiêu:ụ
K t thúc bài h c này, b n có th :ế ọ ạ ể
Tìm hi u v cách s d ng các hàmể ề ử ụ
Tìm hi u v c u trúc c a m t hàmề ề ấ ủ ộ
Khai báo hàm và các nguyên m u hàmẫ
Th o lu n các ki u khác nhau c a bi nả ậ ể ủ ế
Tìm hi u cách g i các hàm:ể ọ
•G i b ng giá trọ ằ ị
•G i b ng tham chi uọ ằ ế
Tìm hi u v các qui t c v ph m vi c a hàmể ề ắ ề ạ ủ
Tìm hi u các hàm trong các ch ng trình có nhi u t p tinể ươ ề ậ
Tìm hi u v các l p l u trể ề ớ ư ữ
Tìm hi u v con tr hàm.ể ề ỏ
Gi i thi uớ ệ
M t hàm là m t đo n ch ng trình th c hi n m t tác v đ c đ nh nghĩa c th . Chúng th c ch tộ ộ ạ ươ ự ệ ộ ụ ượ ị ụ ể ự ấ
là nh ng đo n ch ng trình nh giúp gi i quy t m t v n đ l n.ữ ạ ươ ỏ ả ế ộ ấ ề ớ
15.1 S d ng các hàmử ụ
Nói chung, các hàm đ c s d ng trong C đ th c thi m t chu i các l nh liên ti p. Tuy nhiên, cáchượ ử ụ ể ự ộ ỗ ệ ế
s d ng các hàm thì không gi ng v i các vòng l p. Các vòng l p có th l p l i m t chu i các chử ụ ố ớ ặ ặ ể ặ ạ ộ ỗ ỉ
th v i các l n l p liên ti p nhau. Nh ng vi c g i m t hàm s sinh ra m t chu i các ch th đ cị ớ ầ ặ ế ư ệ ọ ộ ẽ ộ ỗ ỉ ị ượ
th c thi t i v trí b t kỳ trong ch ng trình. Các hàm có th đ c g i nhi u l n khi có yêu c u. Giự ạ ị ấ ươ ể ượ ọ ề ầ ầ ả
s m t ph n c a mã l nh trong m t ch ng trình dùng đ tính t l ph n trăm cho m t vài con s .ử ộ ầ ủ ệ ộ ươ ể ỉ ệ ầ ộ ố
N u sau đó, trong cùng ch ng trình, vi c tính toán nh v y c n ph i th c hi n trên nh ng con sế ươ ệ ư ậ ầ ả ự ệ ữ ố
khác, thay vì ph i vi t l i các ch th gi ng nh trên, m t hàm có th đ c vi t ra đ tính t l ph nả ế ạ ỉ ị ố ư ộ ể ượ ế ể ỉ ệ ầ
trăm c a b t kỳ các con s . Sau đó ch ng trình có th nh y đ n hàm đó, đ th c hi n vi c tínhủ ấ ố ươ ể ả ế ể ự ệ ệ
toán (trong hàm) và tr v n i nó đã đ c g i. Đi u này s đ c gi i thích rõ ràng h n khi th oở ề ơ ượ ọ ề ẽ ượ ả ơ ả
lu n v cách ho t đ ng c a các hàm.ậ ề ạ ộ ủ
M t đi m quan tr ng khác là các hàm thì d vi t và d hi u. Các hàm đ n gi n có th đ c vi tộ ể ọ ễ ế ễ ể ơ ả ể ượ ế
đ th c hi n các tác v xác đ nh. Vi c g r i ch ng trình cũng d dàng h n khi c u trúc ch ngể ự ệ ụ ị ệ ỡ ố ươ ễ ơ ấ ươ
trình d đ c, nh vào s đ n gi n hóa hình th c c a nó. M i hàm có th đ c ki m tra m t cáchễ ọ ờ ự ơ ả ứ ủ ỗ ể ượ ể ộ
đ c l p v i các d li u đ u vào, v i d li u h p l cũng nh không h p l . Các ch ng trình ch aộ ậ ớ ữ ệ ầ ớ ữ ệ ợ ệ ư ợ ệ ươ ứ
các hàm cũng d b o trì h n, b i vì nh ng s a đ i, n u yêu c u, có th đ c gi i h n trong cácễ ả ơ ở ữ ử ổ ế ầ ể ượ ớ ạ
hàm c a ch ng trình. M t hàm không ch đ c g i t các v trí bên trong ch ng trình, mà cácủ ươ ộ ỉ ượ ọ ừ ị ươ
hàm còn có th đ t vào m t th vi n và đ c s d ng b i nhi u ch ng trình khác, vì v y ti tể ặ ộ ư ệ ượ ử ụ ở ề ươ ậ ế
ki m đ c th i gian vi t ch ng trình.ệ ượ ờ ế ươ
15.2 C u trúc hàmấ
Hàm 209

Cú pháp t ng quát c a m t hàm trong C là:ổ ủ ộ
type_specifier function_name (arguments)
{
body of the function
return statement
}
type_specifier xác đ nh ki u d li u c a giá tr s đ c tr v b i hàm. N u không có ki u đ cị ể ữ ệ ủ ị ẽ ượ ả ề ở ế ể ượ
đ a ra, hàm cho r ng tr v m t k t qu s nguyên. Các đ i s đ c phân cách b i d u ph y. M tư ằ ả ề ộ ế ả ố ố ố ượ ở ấ ẩ ộ
c p d u ngo c r ng () v n ph i xu t hi n sau tên hàm ngay c khi n u hàm không ch a b t kỳ đ iặ ấ ặ ỗ ẫ ả ấ ệ ả ế ứ ấ ố
s nào. Các tham s xu t hi n trong c p d u ngo c () đ c g i là ố ố ấ ệ ặ ấ ặ ượ ọ tham s hình ốth cứ ho c ặđ i số ố
hình th cứ. Ph n thân c a hàm có th ch a m t ho c nhi u câu l nh. M t hàm nên tr v m t giáầ ủ ể ứ ộ ặ ề ệ ộ ả ề ộ
tr và vì v y ít nh t m t l nh return ph i có trong hàm.ị ậ ấ ộ ệ ả
15.2.1 Các đ i s c a m t hàmố ố ủ ộ
Tr c khi th o lu n chi ti t v các đ i s , xem ví d sau,ướ ả ậ ế ề ố ố ụ
#include <stdio.h>
main()
{
int i;
for(i =1; i <=10; i++)
printf(“\nSquare of %d is %d “, i,squarer (i));
}
squarer(int x)
/* int x; */
{
int j;
j = x * x;
return(j);
}
Ch ng trình trên tính tính bình ph ng các s t 1 đ n 10. Đi u này đ c th c hi n b ng vi cươ ươ ố ừ ế ề ượ ự ệ ằ ệ
g i hàm ọsquarer. D li u đ c truy n t th t c g i (trong tr ng h p trên là hàm main()) đ nữ ệ ượ ề ừ ủ ụ ọ ườ ợ ế
hàm đ c g i ượ ọ squarer thông qua các đ i s . Trong th t c g i, các đ i s đ c bi t nh là ố ố ủ ụ ọ ố ố ượ ế ư các
đ i s th c ố ố ự và trong đ nh nghĩa c a hàm đ c g i (squarer()) các đ i s đ c g i là các ị ủ ượ ọ ố ố ượ ọ đ i số ố
hình th cứ. Ki u d li u c a các đ i s th c ph i cùng ki u v i các đ i s hình th c. H n n a, sể ữ ệ ủ ố ố ự ả ể ớ ố ố ứ ơ ữ ố
l ng và th t c a các tham s th c ph i gi ng nh c a các tham s hình th c.ượ ứ ự ủ ố ự ả ố ư ủ ố ứ
Khi m t hàm đ c g i, quy n đi u khi n s đ c chuy n đ n cho nó, đó các đ i s hình th cộ ượ ọ ề ề ể ẽ ượ ể ế ở ố ố ứ
đ c thay th b i các đ i s th c. Sau đó hàm đ c th c thi và khi b t g p câu l nh return, nó sượ ế ở ố ố ự ượ ự ắ ặ ệ ẽ
chuy n quy n đi u khi n cho ch ng trình g i nó.ể ề ề ể ươ ọ
Hàm squarer() đ c g i b ng cách truy n s c n đ c tính bình ph ng. Đ i s ượ ọ ằ ề ố ầ ượ ươ ố ố x có th đ cể ượ
khai báo theo m t trong các cách sau khi đ nh nghĩa hàm.ộ ị
Ph ng pháp 1ươ
squarer(int x)
/* x đ c đ nh nghĩa cùng v i ki u d li u trong c p d u ngo c ()*/ượ ị ớ ể ữ ệ ặ ấ ặ
Ph ng pháp 2ươ
210 L p trình c b n Cậ ơ ả

Nguyen Dinh Phuong
squarer(x)
int x;
/* x đ c đ t trong c p d u ngo c (), và ki u c a nó đ c khai báoượ ặ ặ ấ ặ ể ủ ượ
ngay sau tên hàm */
Chú ý, trong tr ng h p sau, ườ ợ x ph i đ c đ nh nghĩa ngay sau tên hàm, tr c kh i l nh. Đi u nàyả ượ ị ướ ố ệ ề
th t ti n l i khi có nhi u tham s có cùng ki u d li u đ c truy n. Trong tr ng h p nh v y,ậ ệ ợ ề ố ể ữ ệ ượ ề ườ ợ ư ậ
ch ph i ch rõ ki u đ m t l n duy nh t t i đi m b t đ u.ỉ ả ỉ ể ề ộ ầ ấ ạ ể ắ ầ
Khi các đ i s đ c khai báo trong c p d u ngo c (), m i đ i s ph i đ c đ nh nghĩa riêng l ,ố ố ượ ặ ấ ặ ỗ ố ố ả ượ ị ẻ
cho dù chúng có cùng ki u d li u. Ví d , n u x và y là hai đ i s c a m t hàm abc(), thìể ữ ệ ụ ế ố ố ủ ộ
abc(char x, char y) là m t khai báo đúng và ộabc(char x, y) là sai.
15.2.2 S tr v t hàmự ả ề ừ
L nh ệreturn có hai m c đích:ụ
Ngay l p t c tr đi u khi n t hàm v ch ng trình g iậ ứ ả ề ể ừ ề ươ ọ
B t kỳ cái gì bên trong c p d u ngo c () theo sau ấ ặ ấ ặ return đ c tr v nh là m t giá tr choượ ả ề ư ộ ị
ch ng trình g i.ươ ọ
Trong hàm squarer(), m t bi n ộ ế j ki u int đ c đ nh nghĩa đ l u giá tr bình ph ng c a đ i sể ượ ị ể ư ị ươ ủ ố ố
truy n vào. Giá tr c a bi n này đ c tr v cho hàm g i thông qua l nh ề ị ủ ế ượ ả ề ọ ệ return. M t hàm có thộ ể
th c hi n m t tác v xác đ nh và tr quy n đi u khi n v cho th t c g i nó mà không c n tr vự ệ ộ ụ ị ả ề ề ể ề ủ ụ ọ ầ ả ề
b t kỳ giá tr nào. Trong tr ng h p nh v y, l nh ấ ị ườ ợ ư ậ ệ return có th đ c vi t d ng ể ượ ế ạ return(0) ho cặ
return. Chú ý r ng, n u m t hàm cung c p m t giá tr tr v và nó không làm đi u đó thì nó s trằ ế ộ ấ ộ ị ả ề ề ẽ ả
v giá tr không thích h p.ề ị ợ
Trong ch ng trình tính bình ph ng c a các s , ch ng trình truy n d li u t i hàm ươ ươ ủ ố ươ ề ữ ệ ớ squarer
thông qua các đ i s . Có th có các hàm đ c g i mà không c n b t kỳ đ i s nào. đây, hàmố ố ể ượ ọ ầ ấ ố ố Ở
th c hi n m t chu i các l nh và tr v giá tr , n u đ c yêu c uự ệ ộ ỗ ệ ả ề ị ế ượ ầ
Chú ý r ng, hàm ằsquarer() cũng có th đ c vi t nh sauể ượ ế ư
squarer(int x)
{
return(x*x);
}
đây m t bi u th c h p l đ c xem nh m t đ i s trong câu l nh return. Trong th c t , l nhỞ ộ ể ứ ợ ệ ượ ư ộ ố ố ệ ự ế ệ
return có th đ c s d ng theo m t trong các cách sau đây:ể ượ ử ụ ộ
return;
return(h ng);ằ
return(bi n);ế
return(bi u th c);ể ứ
return(câu l nh đánh giá); ệví d : ụreturn(a>b?a:b);
Tuy nhiên, gi i h n c a l nh ớ ạ ủ ệ return là nó ch có th tr v m t giá tr duy nh t.ỉ ể ả ề ộ ị ấ
15.2.3 Ki u c a m t hàmể ủ ộ
type-specifier đ c s d ng đ xác đ nh ki u d li u tr v c a m t hàm. Trong ví d trên, ượ ử ụ ể ị ể ữ ệ ả ề ủ ộ ụ type-
specifier không đ c vi t bên c nh hàm ượ ế ạ squarer(), vì squarer() tr v m t giá tr ki u ả ề ộ ị ể int. type-
Hàm 211

specifier là không b t bu c n u m t giá tr ki u s nguyên đ c tr v ho c n u không có giá trắ ộ ế ộ ị ể ố ượ ả ề ặ ế ị
nào đ c tr v . . Tuy nhiên, t t h n nên ch ra ki u d li u tr v là int n u m t giá tr s nguyênượ ả ề ố ơ ỉ ể ữ ệ ả ề ế ộ ị ố
đ c tr v và t ng t dùng void n u hàm không tr v giá tr nào. ượ ả ề ươ ự ế ả ề ị
15.3 G i hàmọ
Có th g i m t hàm t ch ng trình chính b ng cách s d ng tên c a hàm, theo sau là c p d uể ọ ộ ừ ươ ằ ử ụ ủ ặ ấ
ngo c (). C p d u ngo c là c n thi t đ nói v i trình biên d ch là đây là m t l i g i hàm. Khi m tặ ặ ấ ặ ầ ế ể ớ ị ộ ờ ọ ộ
tên hàm đ c s d ng trong ch ng trình g i, tên hàm có th là m t ph n c a m t m t l nh ho cượ ử ụ ươ ọ ể ộ ầ ủ ộ ộ ệ ặ
chính nó là m t câu l nh. Mà ta đã bi t m t câu l nh luôn k t thúc v i m t d u ch m ph y (ộ ệ ế ộ ệ ế ớ ộ ấ ấ ẩ ;). Tuy
nhiên, khi đ nh nghĩa hàm, không đ c dùng d u ch m ph y cu i ph n đ nh nghĩa. S v ng m tị ượ ấ ấ ầ ở ố ầ ị ự ắ ặ
c a d u ch m ph y nói v i trình biên d ch đây là ph n đ nh nghĩa c a hàm và không đ c g i hàm.ủ ấ ấ ẩ ớ ị ầ ị ủ ượ ọ
M t s đi m c n nh :ộ ố ể ầ ớ
M t d u ch m ph y đ c dùng cu i câu l nh khi m t hàm đ c g i, nh ng nó không đ cộ ấ ấ ẩ ượ ở ố ệ ộ ượ ọ ư ượ
dùng sau m t s đ nh nghĩa hàm.ộ ự ị
C p d u ngo c () là b t bu c theo sau tên hàm, cho dù hàm có đ i s hay không.ặ ấ ặ ắ ộ ố ố
Hàm g i đ n m t hàm khác đ c g i là ọ ế ộ ượ ọ hàm g i ọhay th t c g iủ ụ ọ . Và hàm đ c g i đ n cònượ ọ ế
đ c g i là ượ ọ hàm đ c g i ượ ọ hay th t c đ c g iủ ụ ượ ọ .
Các hàm không tr v m t giá tr s nguyên c n ph i xác đ nh ki u c a giá tr đ c tr v .ả ề ộ ị ố ầ ả ị ể ủ ị ượ ả ề
Ch m t giá tr có th đ c tr v b i m t hàm.ỉ ộ ị ể ượ ả ề ở ộ
M t ch ng trình có th có m t ho c nhi u hàm.ộ ươ ể ộ ặ ề
15.4 Khai báo hàm
N u mếMt hàm ộnên đ c ượ g iọkhai báo trong hàm main() tr c khi nó đ c đ nh nghĩa ướ ượ ị ho c sặ ử
d ng. ụĐi u này ềph i ảđ c ượ th c hi n ự ệ trong tr ng h p hàm đ c g i tr c khi nó đ c ườ ợ ượ ọ ướ ượ đ nhị
nghĩa.thi hàm ph i đ c khai báo trong hàmả ượ main() tr c khi nó đ c s d ng.ướ ượ ử ụ
Xem ví d ,ụ
#include <stdio.h>
main()
{
.
.
address();
.
.
}
address()
{
.
.
.
}
Hàm main() g i hàm ọaddress() và hàm address() đ c g i tr c khi nó đ c đ nh nghĩa. M c dù,ượ ọ ướ ượ ị ặ
nó không đ c khai báo trong hàm ượ main() thì đi u này có th th c hi n đ c trong m t s trìnhề ể ự ệ ượ ộ ố
biên d ch C, hàm ịaddress() đ c g i mà không c n khai báo gì thêm c . Đây là s ượ ọ ầ ả ự khai báo không
t ng minh ườ c a m t hàm.ủ ộ
212 L p trình c b n Cậ ơ ả

Nguyen Dinh Phuong
15.5 Các nguyên m u hàmẫ
M t nguyên m u hàm là m t khai báo hàm trong đó xác đ nh rõ ki u d li u c a các đ i s và trộ ẫ ộ ị ể ữ ệ ủ ố ố ị
tr v . Thông th ng, các hàm đ c khai báo b ng cách xác đ nh ki u c a giá tr đ c tr v b iả ề ườ ượ ằ ị ể ủ ị ượ ả ề ở
hàm, và tên hàm. Tuy nhiên, chu n ANSI C cho phép s l ng và ki u d li u c a các đ i s hàmẩ ố ượ ể ữ ệ ủ ố ố
đ c khai báo. M t hàm abc() có hai đ i s ki u int là x và y, và tr v m t giá tr ki u char, cóượ ộ ố ố ể ả ề ộ ị ể
th đ c khai báo nh sau:ể ượ ư
char abc();
ho c ặ
char abc(int x, nt y);
Cách đ nh nghĩa sau đ c g i là ị ượ ọ nguyên m u hàmẫ. Khi các nguyên m u đ c s d ng, C có thẫ ượ ử ụ ể
tìm và thông báo b t kỳ ki u d li u không h p l khi chuy n đ i gi a các đ i s đ c dùng đấ ể ữ ệ ợ ệ ể ổ ữ ố ố ượ ể
g i m t hàm v i s đ nh nghĩa ki u c a các tham s . M t l i s đ c thông báo ngay khi có sọ ộ ớ ự ị ể ủ ố ộ ỗ ẽ ượ ự
khác nhau gi a s l ng các đ i s đ c s d ng đ g i hàm và s l ng các tham s khi đ nhữ ố ượ ố ố ượ ử ụ ể ọ ố ượ ố ị
nghĩa hàm.
Cú pháp t ng quát c a m t nguyên m u hàm:ổ ủ ộ ẫ
type function_name(type parm_namel,type parm_name2,..type
parm_nameN);
Khi hàm đ c khai báo không có các thông tin nguyên m u, trình biên d ch cho r ng không có thôngượ ẫ ị ằ
tin v các tham s đ c đ a ra. M t hàm không có đ i s có th gây ra l i khi khai báo không cóề ố ượ ư ộ ố ố ể ỗ
thông tin nguyên m u. Đ tránh đi u này, khi m t hàm không có tham s , nguyên m u c a nó sẫ ể ề ộ ố ẫ ủ ử
d ng ụvoid trong c p d u ngo c (). Nh đã nói trên, ặ ấ ặ ư ở void cũng đ c s d ng đ khai báo t ngượ ử ụ ể ườ
minh m t hàm không có giá tr tr v .ộ ị ả ề
Ví d , n u m t hàm noparam() tr v ki u d li u char và không có các tham s đ c g i, có thụ ế ộ ả ề ể ữ ệ ố ượ ọ ể
đ c khai báo nh sauượ ư
char noparam(void);
Khai báo trên ch ra r ng hàm không có tham s , và b t kỳ l i g i có truy n tham s đ n hàm đó làỉ ằ ố ấ ờ ọ ề ố ế
không đúng.
Khi m t hàm không nguyên m u đ c g i t t c các ki u ộ ẫ ượ ọ ấ ả ể char đ c đ i thành ki u ượ ổ ể int và t t cấ ả
ki u ểfloat đ c đ i thành ki u ượ ổ ể double. Tuy nhiên, n u m t ế ộ hànghàm là nguyên m u, thì các ki uẫ ể
đã đ a ra trong nguyên m u đ c gi nguyên và không có s tăng c p ki u x y ra.ư ẫ ượ ữ ự ấ ể ả
15.6 Các bi nế
Nh đã th o lu n, các bi n là nh ng v trí đ c đ t tên trong b nh , đ c s d ng đ ch a giá trư ả ậ ế ữ ị ượ ặ ộ ớ ượ ử ụ ể ứ ị
có th ho c không th đ c s a đ i b i m t ch ng trình ho c m t hàm. Có ba lo i bi n c b n:ể ặ ể ượ ử ổ ở ộ ươ ặ ộ ạ ế ơ ả
bi n c c b , tham s hình th c,ế ụ ộ ố ứ và bi n toàn c cế ụ .
1. Bi n c c b ế ụ ộ là nh ng bi n đ c khai báo bên trong m t hàm.ữ ế ượ ộ
2. Tham s hình th c ố ứ đ c khai báo trong m t đ nh nghĩa hàm nh là các tham s . ượ ộ ị ư ố
3. Bi n toàn c c ế ụ đ c khai báo bên ngoài các hàm. ượ
15.6.1 Bi n c c b ế ụ ộ
Hàm 213