0% found this document useful (0 votes)
50 views106 pages

HTMT Va NNC Chapter 9

The document discusses functions in C programming. It defines functions as program blocks that perform specific tasks. Functions allow programs to be organized modularly. Functions are declared with a return type and list of parameter types. Parameters passed to functions act as local variables that the function can perform computations on. Well-defined functions help make programs more maintainable and easy to debug.

Uploaded by

Tuấn Dũng
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
50 views106 pages

HTMT Va NNC Chapter 9

The document discusses functions in C programming. It defines functions as program blocks that perform specific tasks. Functions allow programs to be organized modularly. Functions are declared with a return type and list of parameter types. Parameters passed to functions act as local variables that the function can perform computations on. Well-defined functions help make programs more maintainable and easy to debug.

Uploaded by

Tuấn Dũng
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 106

CHÖÔNG 9

HAØM

CHÖÔNG 9
HAØM

9.1 Khaùi nieäm haøm


9.2 Khai baùo haøm
9.3 Ñoái soá cuûa haøm - ñoái soá laø tham trò
9.4 Keát quaû traû veà cuûa haøm - leänh RETURN
9.5 PROTOTYPE cuûa moät haøm
9.6 Haøm ñeä quy
Baøi taäp cuoái chöông
CHÖÔNG 9
HAØM

9.1 KHAÙI NIEÄM HAØM

Chöông trình con laø ñoaïn chöông trình ñaûm nhaän thöïc
hieän moät thao taùc nhaát ñònh.
Ñoái vôùi C, chöông trình con chæ ôû moät daïng laø haøm
(function), khoâng coù khaùi nieäm thuû tuïc (procedure).
CHÖÔNG 9
HAØM

9.1 KHAÙI NIEÄM HAØM

Haøm main () laø haøm ñaëc bieät cuûa C, noù laø moät haøm maø
trong ñoù caùc thao taùc leänh (bao goàm caùc bieåu thöùc tính
toaùn, goïi haøm, ...) ñöôïc C thöïc hieän theo moät trình töï hôïp
logic ñeå giaûi quyeát baøi toaùn ñöôïc ñaët ra.
Vieäc söû duïng haøm trong C seõ laøm cho chöông trình trôû
neân raát deã quaûn lyù, deã söûa sai.
CHÖÔNG 9
HAØM

9.1 KHAÙI NIEÄM HAØM

Taát caû caùc haøm trong C ñeàu ngang caáp nhau. Caùc haøm ñeàu
coù theå goïi laãn nhau, dó nhieân haøm ñöôïc goïi phaûi ñöôïc khai
baùo tröôùc haøm goïi.
CHÖÔNG 9
HAØM

9.1 KHAÙI NIEÄM HAØM

Caùc haøm trong moät chöông trình coù theå naèm treân caùc taäp
tin khaùc nhau vaø khaùc vôùi taäp tin chính (chöùa haøm main
()), moãi taäp tin ñöôïc goïi laø moät module chöông trình,
Caùc module chöông trình seõ ñöôïc dòch rieâng reõ vaø sau ñoù
ñöôïc lieân keát (link) laïi vôùi nhau ñeå taïo ra ñöôïc moät taäp tin
thöïc thi duy nhaát.
Caùch taïo chöông trình theo kieåu nhieàu module nhö vaäy
trong C laø project
CHÖÔNG 9
HAØM

9.1 KHAÙI NIEÄM HAØM

Ví duï: Chöông trình 1


#include <stdio.h>
#include <conio.h>
#include <math.h>
main ()
{
double a, b, c, delta, n1, n2;
clrscr();
printf ("Nhap 3 he so phuong trinh bac hai; ");
scanf ("%lf %lf %lf", &a, &b, &c);
CHÖÔNG 9
HAØM

9.1 KHAÙI NIEÄM HAØM


if (a ==0)/* phuong trinh suy bien ve bac nhat */
{
printf ("Phuong trinh suy bien ve bac nhat va
");
if (b == 0)
if (c == 0)
printf ("vo so nghiem\n");
else /* c != 0 */
printf ("vo nghiem\n");
else / * b != 0 */
CHÖÔNG 9
HAØM

9.1 KHAÙI NIEÄM HAØM


{
n1 = -c/b;
printf ("co 1 nghiem: = %5.2f \n",
n1);
}

}
else /* a != 0 */
{
printf ("Phuong trinh bac hai va ");
delta = b*b - 4*a*c;
CHÖÔNG 9
HAØM

9.1 KHAÙI NIEÄM HAØM


if (delta < 0)
printf ("vo nghiem thuc\n");
else if (delta == 0)
{
n1 = n2 = -b/2/a;
printf ("co nghiem kep x1 = x2 = %5.2f \n"
,n1);
}
CHÖÔNG 9
HAØM

9.1 KHAÙI NIEÄM HAØM

else /* delta > 0 */


{
n1 = (-b + sqrt(delta))/2/a;
n2 = (-b - sqrt(delta))/2/a;
printf ("co hai nghiem phan biet; \n");
printf ("x1 = %5.2f \n", n1);
printf ( x2 = %5.2f \n", n2);
}
}
getch();
}
CHÖÔNG 9
HAØM

9.1 KHAÙI NIEÄM HAØM

Ví duï: Chöông trình 2


#include <stdio.h>
#include <conio.h>
#include <math.h>
void gptb1 (double a, double b);
void gptb2 (double a, double b, double c);
CHÖÔNG 9
HAØM

9.1 KHAÙI NIEÄM HAØM


void gptb1 (double a, double b)
{
printf ("Phuong trinh suy bien ve bac nhat va ");
if (a == 0)
if (b == 0)
printf ("vo so nghiem\n");
else /* b != 0 */
printf ("vo nghiem\n");
else
printf ("co 1 nghiem: x = %5.2f \n", b/a);
}
CHÖÔNG 9
HAØM

9.1 KHAÙI NIEÄM HAØM


void gptb2 (double a,double b,double c)
{ double delta, x1, x2;
printf ("Phuong trinh bac hai va ");
delta = b*b - 4*a*c;
if (delta < 0)
printf ("vo nghiem thuc\n");
else if (delta == 0)
printf ("co nghiem kep x1 = x2 = %5.2f \n", -
b/2/a);
CHÖÔNG 9
HAØM

9.1 KHAÙI NIEÄM HAØM


else /* delta > 0 */
{ x1 = (-b + sqrt(delta))/2/a;
x2 = (-b - sqrt(delta))/2/a;
printf ("co hai nghiem phan biet: \n");
printf ("x1 = %5.2f \n ", x1);
printf ("x2 = %5.2f \n" , x2);
}
}
CHÖÔNG 9
HAØM

9.1 KHAÙI NIEÄM HAØM


main()
{
double a, b, c;
clrscr();
printf ("Nhap 3 he so phuong trinh bac hai: ");
scanf ("%lf %lf %lf", &a, &b, &c);
if (a == 0) /* phuong trinh suy bien ve bac nhat */
gptb1 (b, c);
else /* a != 0 */
gptb2 (a, b, c);
getch();
}
CHÖÔNG 9
HAØM

9.2 KHAI BAÙO HAØM

Khai baùo moät haøm laø chæ ra roõ raèng traû veà vò trí kieåu gì,
ñoái soá ñöa vaøo cho haøm coù bao nhieâu ñoái soá, moãi ñoái soá coù
kieåu nhö theá naøo vaø caùc leänh beân trong thaân haøm xaùc
ñònh thao taùc cuûa haøm.
Coù hai loaïi haøm: haøm trong thö vieän cuûa C vaø haøm do laäp
trình vieân töï ñònh nghóa.
CHÖÔNG 9
HAØM

9.2 KHAI BAÙO HAØM

- Neáu haøm söû duïng laø haøm chuaån trong thö vieän thì vieäc
khai baùo haøm chæ ñôn giaûn laø khai baùo prototype cuûa haøm,
caùc prototype naøy ñaõ ñöôïc phaân loaïi vaø ôû trong caùc file .h,
laäp trình vieân caàn ra leänh #include bao haøm caùc file naøy
vaøo chöông trình hoaëc module chöông trình söû duïng noù.
CHÖÔNG 9
HAØM

9.2 KHAI BAÙO HAØM

- Neáu caùc haøm söû duïng laø do laäp trình vieân töï ñònh nghóa
thì vieäc khai baùo haøm bao goàm hai vieäc: khai baùo
prototype cuûa haøm ñaàu chöông trình vaø ñònh nghóa caùc
leänh beân trong thaân haøm (hay thöôøng ñöôïc goïi taét laø ñònh
nghóa haøm).
CHÖÔNG 9
HAØM

9.2 KHAI BAÙO HAØM


Daïng 1: Daïng 2: (Laïc haäu)

kieåu teân_haøm kieåu teân_haøm (danh_saùch_ñoái_soá)


(danh_saùch_khai_baùo_ñoái_soá) khai_baùo_ñoái_soá
{ {
khai_baùo_bieán_cuïc_boä khai_baùo_bieán_cuïc_boä
leänh
leänh }
}
CHÖÔNG 9
HAØM

9.2 KHAI BAÙO HAØM


Daïng 1: Daïng 2:
int so_sanh (int a, int b) int so_sanh (a, b)
{ int a, b;
int ket_qua; {
if (a >b) int ket_qua:
ket_qua = 1: if (a >b)
else if (a == b) ket_qua = 1;
else if (a == b)
ket_qua = 0; ket_qua = 0;
else if (a < b) else if (a < b)
ket_qua = -1; ket_qua = -1;
return ket_qua; return ket_qua;
} }
CHÖÔNG 9
HAØM

9.2 KHAI BAÙO HAØM


Ví duï:
#include <stdio.h>
#include <conio.h>
int so_sanh (int a, int b);  prototype cuûa haøm so_sanh
main()
{
int a, b, ket_qua;
clrscr();
printf ("Moi nhap hai so ");
scanf ("%d %d" , &a, &b);
ket_qua = so_sanh (a, b); goïi
haøm
CHÖÔNG 9
HAØM

9.2 KHAI BAÙO HAØM


switch (ket_qua)
{ case -1:
printf ("So %d nho hon so %d \n" ,
a, b);
break;
case 0:
printf ("So %d bang so %d \n", a, b);
break;
case 1:
printf ("So %d lon hon so %d \n" , a,
b);
break; }
getch();
}
CHÖÔNG 9
HAØM

9.2 KHAI BAÙO HAØM


int so_sanh (int a, int b)
{
int ket_qua:
if (a >b)
ket_qua = 1;
else if (a == b)
ket_qua = 0;
else if (a < b)
ket_qua = -1;
return ket_qua;
}
CHÖÔNG 9
HAØM

9.3 ÑOÁI SOÁ CUÛA HAØM - ÑOÁI SOÁ LAØ THAM TRÒ

Khi goïi haøm thì ñoái soá thaät caàn gôûi cho haøm chæ ñöôïc gôûi
döôùi daïng tham soá trò, coù nghóa laø caùc bieán, trò hoaëc bieåu
thöùc ñöôïc gôûi ñeán cho moät haøm, qua ñoái soá cuûa noù, seõ ñöôïc
laáy trò ñeå tính toaùn trong thaân haøm.
Coù theå noùi trò cuûa bieán thaät beân ngoaøi khi goïi haøm ñaõ
ñöôïc cheùp sang ñoái soá giaû, ta coù theå xem nhö laø bieán cuïc
boä cuûa haøm, vaø moïi vieäc tính toaùn chæ ñöôïc thöïc hieän treân
bieán cuïc boä naøy maø thoâi.
CHÖÔNG 9
HAØM

9.3 ÑOÁI SOÁ CUÛA HAØM - ÑOÁI SOÁ LAØ THAM TRÒ

Ví duï:Vieát chöông trình tính luõy thöøa n cuûa x(xn), vôùi n


nguyeân va øx thöïc.
#include <stdio.h>
#include <conio.h>
double luy_thua(double x, int n);
main()
{ int n;
double x, xn;
clrscr();
printf ("Moi nhap so tinh luy thua: ");
scanf ("%lf", &x);
CHÖÔNG 9
HAØM

9.3 ÑOÁI SOÁ CUÛA HAØM - ÑOÁI SOÁ LAØ THAM TRÒ
printf ("Moi nhap so luy thua: ");
scanf ("%d", &n);
xn =luy_thua (x, n);
printf("Ket qua: %5.2f luy thua %d bang: %7.2f\n",
x,n,xn);
printf ("Tri cua so mu la %d", n);
getch();}
double luy_thua(double x, int n)
{ double t = 1;
for ( ; n > 0; n--)
t *= x;
return t; }
CHÖÔNG 9
HAØM

9.3 ÑOÁI SOÁ CUÛA HAØM - ÑOÁI SOÁ LAØ THAM TRÒ

Khi goïi haøm luõy thöøa, trò cuûa bieán x vaø n seõ ñöôïc cheùp vaøo
cho hai ñoái soá giaû x vaø n, do ñoù ta coù ñoàng thôøi caùc hoäp
bieán nhö sau khi vaøo trong haøm luy_thua():

Bieán cuûa haøm main() Bieán cuûa haøm luy_thua()


x 3.45 3.45 x

n 3 3 n
CHÖÔNG 9
HAØM

9.3 ÑOÁI SOÁ CUÛA HAØM - ÑOÁI SOÁ LAØ THAM TRÒ

Ví duï:
Ta coù theå goïi haøm luy_thua() vaø truyeàn cho haøm naøy moät
bieåu thöùc:
xn = luy_thua( 3*a + x , 5);

Tuy nhieân, caùch truyeàn tham soá nhö treân khoâng theå thay
ñoåi trò cuûa bieán, maø ñieàu naøy ñoâi khi laïi caàn thieát.
CHÖÔNG 9
HAØM

9.3 ÑOÁI SOÁ CUÛA HAØM - ÑOÁI SOÁ LAØ THAM TRÒ
Ví duï: Vieát chöông trình duøng haøm nhaäp soá lieäu
#include <stdio.h>
#include <conio.h>
void nhap_tri (int a, int b);
main()
{ int a = 0, b = 0;
clrscr();
printf ("Truoc khi goi ham nhap_tri: a = %d, b = %d\n",
a, b);
nhap_tri (a, b);
printf("Sau khi goi ham nhap_tri a = %d, b = %d\n", a,
b);
getch();
}
CHÖÔNG 9
HAØM

9.3 ÑOÁI SOÁ CUÛA HAØM - ÑOÁI SOÁ LAØ THAM TRÒ

void nhap_tri (int a, int b)


{
printf ("Moi nhap hai so: ");
scanf ("%d %d", &a, &b);
}
CHÖÔNG 9
HAØM

9.3 ÑOÁI SOÁ CUÛA HAØM - ÑOÁI SOÁ LAØ THAM TRÒ

Ví duï:
Thieát keá chöông trình duøng haøm nhaäp maûng, tính toång caùc
phaàn töû vaø in ra maøn hình keát quaû.
#include <stdio.h>
#include <conio.h>
void nhap_tri (int a[], int n);
int tong (int a[], int n);
CHÖÔNG 9
HAØM

9.3 ÑOÁI SOÁ CUÛA HAØM - ÑOÁI SOÁ LAØ THAM TRÒ

main() Giaù trò cuûa maûng


{ int a[100], n; coù theå bò thay ñoåi
int sum; trong haøm
clrscr();
printf ("Moi nhap so phan tu cua mang: ");
scanf (%d , &n);
nhap_tri (a, n);
sum = tong (a, n);
printf ("Tong cac phan tu cua mang la: %d \n", sum);
getch();
}
CHÖÔNG 9
HAØM

9.3 ÑOÁI SOÁ CUÛA HAØM - ÑOÁI SOÁ LAØ THAM TRÒ

void nhap_tri (int a[], int n)


{ int i;
printf ("Moi nhap cac phan tu cua mang: ");
for (i = 0; i <n; i++)
scanf ("%d", &a[i]);
}
int tong (int a[], int n) Giaù trò cuûa maûng
{ int i, s = 0; coù theå bò thay ñoåi
for (i = 0; i < n; s += a[i++]) trong haøm
;
return s;}
CHÖÔNG 9
HAØM

9.4 KEÁT QUAÛ TRAÛ VEÀ CUÛA HAØM - LEÄNH RETURN

Ñoái vôùi C khoâng coù söï phaân bieät giöõa thuû tuïc (procedure)
vaø haøm (function), maø thuû tuïc cuõng ñöôïc xem laø moät haøm
maø khoâng traû veà giaù trò naøo caû. Ñeå khai baùo kieåu traû veà töø
haøm nhö vaäy C ñöa ra kieåu void, taïm goïi laø kieåu khoâng
hieåu.
Ví duï: so saùnh 2 tröôøng hôïp söû duïng haøm
c = getch(); vaø getch();
hoaëc
c = getche(); vaø getche();
CHÖÔNG 9
HAØM

9.4 KEÁT QUAÛ TRAÛ VEÀ CUÛA HAØM - LEÄNH RETURN

Trong chöông trình, ta cuõng bieát leänh return duøng ñeå


thöïc hieän vieäc traû trò cuûa haøm veà cho nôi goïi noù, duø trò naøy
coù ñöôïc söû duïng hay khoâng tuøy nôi goïi.
Ví duï:
Thieát keá haøm so saùnh hai soá.
CHÖÔNG 9
HAØM

9.4 KEÁT QUAÛ TRAÛ VEÀ CUÛA HAØM - LEÄNH RETURN


int so_sanh (int a, int b)
{ if (a >b)
{ printf ("So %d lon hon so %d", a, b);
return 1; }
else if (a == b)
{ printf ("So %d bang so %d", a, b);
return 0; }
else /* a <b */
{ printf ("So %d nho hon so %d", a, b);
return -1; }
}
CHÖÔNG 9
HAØM

9.4 KEÁT QUAÛ TRAÛ VEÀ CUÛA HAØM - LEÄNH RETURN

main()
{
int so1, so2;
clrscr();
printf("Moi nhap hai so: ");
scanf ("%d %d", &so1, &so2);
so_sanh (so1, so2);
getch();
}
CHÖÔNG 9
HAØM

9.4 KEÁT QUAÛ TRAÛ VEÀ CUÛA HAØM - LEÄNH RETURN

main()
{
int so1, so2;
int kq;
clrscr();
printf ("Moi nhap hai so: ");
scanf ("%d %d", &so1, &so2);
kq = so_sanh (so1, so2);
CHÖÔNG 9
HAØM

9.4 KEÁT QUAÛ TRAÛ VEÀ CUÛA HAØM - LEÄNH RETURN


switch (kq)
{
case -1:
printf (", nen tri tuyet doi hieu hai so la: %d\n,so2-
so1");
break;
case 0:
case 1:
printf (", tri tuyet doi hieu hai so la %d\n , so1-so2");
break;
}
getch();
}
CHÖÔNG 9
HAØM

9.4 KEÁT QUAÛ TRAÛ VEÀ CUÛA HAØM - LEÄNH RETURN

Ví duï: Xeùt haøm sau (khoâng traû veà giaù trò)


void so_sanh (int a, int b)
{ if (a > b)
printf ("So %d lon hon so %d", a, b);
else if (a == b)
printf ("So %d bang so %d", a, b);
else /* a < b */
printf ("So %d nho hon s %d", a, b);
}
CHÖÔNG 9
HAØM

9.4 KEÁT QUAÛ TRAÛ VEÀ CUÛA HAØM - LEÄNH RETURN

Khi khai baùo haøm maø ta khoâng neâu cuï theå kieåu traû veà cuûa
haøm, C maëc nhieân xem nhö haøm traû veà keát quaû laø int. Ví
duï:
so_sanh (int a, int b)
{ if (a > b)
return 1;
else if (a == b)
return 0;
else /* a < b */
return -1; }
CHÖÔNG 9
HAØM

9.4 KEÁT QUAÛ TRAÛ VEÀ CUÛA HAØM - LEÄNH RETURN

Ñoái vôùi caùc haøm coù kieåu traû veà trò khaùc int, khi khai baùo
caàn phaûi trình baøy ñaày ñuû caùc thaønh phaàn cuûa haøm.
Khi goïi söû duïng haøm thì trong haøm goïi caàn phaûi coù neâu
keát quaû traû veà cuûa caùc haøm ñöôïc goïi trong ñoù.
Kieåu khai baùo keát quaû naøy coù theå ñöôïc ñaët beân ngoaøi taát
caû caùc haøm ñeå thoâng baùo cho taát caû caùc haøm veà trò traû veà
cuûa noù, hoaëc coù theå ñöôïc ñaët trong haøm maø haøm söû duïng
ñöôïc goïi: kieåu teân_haøm();
CHÖÔNG 9
HAØM

9.4 KEÁT QUAÛ TRAÛ VEÀ CUÛA HAØM - LEÄNH RETURN

Ví duï:
main()
{ int so_sanh ();
int so1, so2;
clrscr();
printf ("Moi nhap hai so: ");
scanf ("%d %d", &so1, &so2);
so_sanh (so1, so2);
getch(); }
CHÖÔNG 9
HAØM

9.5 PROTOTYPE CUÛA MOÄT HAØM

Nhö vaäy ñeå moät haøm coù theå söû duïng trong moät haøm khaùc
thì trong haøm söû duïng phaûi coù khai baùo haøm caàn söû duïng.
Tuy nhieân khai baùo naøy raát haïn cheá ôû choã khoâng cho pheùp
kieåm tra soá ñoái soá thaät ñöa vaøo haøm cuõng nhö kieåu cuûa ñoái
soá coù phuø hôïp khoâng
CHÖÔNG 9
HAØM

9.5 PROTOTYPE CUÛA MOÄT HAØM

Ñeå khaéc phuïc nhöõng loãi treân, trong nhöõng phaùt trieån sau
naøy cuûa C theo ANSI, ngöôøi ta ñöa ra khaùi nieäm prototype
cuûa moät haøm, ñaây thaät söï laø moät daïng khai baùo haøm môû
roäng hôn, coù daïng toång quaùt nhö sau
kieåu teân_haøm (danh_saùch_khai_baùo_ñoái_soá);
Ví duï : int so_sanh (int a, int b);
void gptb1 (double a, double b, doubbe c);
char kiem_tra (double n);
CHÖÔNG 9
HAØM

9.5 PROTOTYPE CUÛA MOÄT HAØM

C cho pheùp khai baùo prototype cuûa haøm trong phaàn khai
baùo ñoái soá chæ caàn coù kieåu maø khoâng caàn coù teân cuûa ñoái soá
giaû.
Ví duï :
int so_sanh (int, int);
CHÖÔNG 9
HAØM

9.5 PROTOTYPE CUÛA MOÄT HAØM

Coâng duïng cuûa prototype cuûa haøm: prototype cuûa moät haøm
ngoaøi vieäc duøng ñeå khai baùo kieåu cuûa keát quaû traû veà töø
moät haøm, noù coøn ñöôïc duøng ñeå kieåm tra soá ñoái soá.
Ví duï :Neáu ñaõ khai baùo prototype
int so_sanh (int a, int b);
maø khi goïi haøm ta chæ göûi moät ñoái soá nhö sau:
so_sanh (so2);
thì seõ bò C phaùt hieän vaø baùo loãi
CHÖÔNG 9
HAØM

9.5 PROTOTYPE CUÛA MOÄT HAØM


Ví duï: Chöông trình sau luoân cho keát quaû so saùnh 2 soá
nhaäp vaøo laø baèng
main()
{ int so1, so2;
int n;
clrscr();
printf(Moi nhap hai so: );
scanf (“%d %d”, &so1, &so2);
so_sanh (so2);
getch(); }
CHÖÔNG 9
HAØM

9.5 PROTOTYPE CUÛA MOÄT HAØM

Chuyeån kieåu cuûa ñoái soá: khi moät haøm ñöôïc goïi, maø
haøm ñoù coù prototype, caùc ñoái soá ñöôïc gôûi cho haøm seõ ñöôïc
chuyeån kieåu baét buoäc theo kieåu cuûa caùc ñoái soá ñöôïc khai
baùo trong prototype, söï chuyeån kieåu naøy laøm cho caùc ñoái soá
ñöôïc söû duïng phuø hôïp vôùi caùc pheùp toaùn trong thaân haøm.
CHÖÔNG 9
HAØM

9.5 PROTOTYPE CUÛA MOÄT HAØM

Chuyeån kieåu cuûa ñoái soá: khi moät haøm ñöôïc goïi, maø
haøm ñoù coù prototype, caùc ñoái soá ñöôïc gôûi cho haøm seõ ñöôïc
chuyeån kieåu baét buoäc theo kieåu cuûa caùc ñoái soá ñöôïc khai
baùo trong prototype, söï chuyeån kieåu naøy laøm cho caùc ñoái soá
ñöôïc söû duïng phuø hôïp vôùi caùc pheùp toaùn trong thaân haøm.
Tröôøng hôïp maø söï chuyeån kieåu khoâng cho pheùp
thöïc hieän thì C seõ ñöa ra caùc thoâng baùo loãi, hoaëc moät lôøi
caûnh baùo (warning.
CHÖÔNG 9
HAØM

9.5 PROTOTYPE CUÛA MOÄT HAØM

Ñoái vôùi caùc haøm chuaån trong thö vieän C, prototype cuûa
chuùng ñaõ ñöôïc C vieát saün vaø ñeå trong caùc file coù phaàn môû
roäng laø .h, muoán laáy caùc prototype naøy vaøo chöông trình ta
caàn ra chæ thò bao haøm file .h chöùa prototype cuûa caùc haøm
caàn söû duïng vaøo ñaàu chöông trình baèng leänh tieàn xöû lyù
#include theo cuù phaùp sau:
# include <file. h>
Ví duï 3: #include <stdio.h>
CHÖÔNG 9
HAØM

9.6 HAØM ÑEÄ QUY


C ñöôïc goïi laø moät ngoân ngöõ ñeä quy vì C cho pheùp moät haøm
coù theå goïi ñeán chính noù moät caùch tröïc tieáp, hoaëc giaùn tieáp
(töùc laø goïi qua trung gian moät haøm khaùc), khi ñoù ta noùi
haøm ñoù coù tính ñeä quy (recursive).
Moät giaûi thuaät ñeä quy seõ daãn ñeán moät söï laëp ñi laëp laïi
khoâng keát thuùc caùc thao taùc, nhöng trong thöïc teá, chuùng
caàn phaûi ñöôïc keát thuùc, söû duïng caùc ñieàu kieän keát thuùc ñeä
quy.
CHÖÔNG 9
HAØM

9.6 HAØM ÑEÄ QUY


Ví duï 3: Haøm ñeä quy tính giai thöøa n!
#include <stdio.h>
#include <conio.h>
long factorial (long so);
int main()
{ long so, kq = 0; clrscr();
printf ("Moi nhap mot so 0: ");
scanf ("%ld", &so);
kq = factorial (so);
printf ("Ket qua %ld! la %ld \n", so, kq);
getch();
return 0;}
CHÖÔNG 9
HAØM

9.6 HAØM ÑEÄ QUY

long factorial (long so)


{
if (so > 1)
return (factorial(so - 1) * so);
else
return 1;
}
CHÖÔNG 9
HAØM

9.6 HAØM ÑEÄ QUY


CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


Trong C, để gọi hàm ta cần ba bước cơ bản:
(1) các tham số từ nơi gọi được chuyển cho hàm
được gọi và điều khiển được chuyển cho hàm
được gọi,
(2) hàm được gọi thực hiện tác vụ,
(3) một giá trị trả về được gởi ngược lại cho nơi gọi
hàm, và điều khiển được trả về cho nơi gọi.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C

Một quy ước quan trọng mà chúng ta quy định cho cơ chế
gọi là hàm được gọi nên độc lập với nơi gọi.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C

9.7.1 Ngăn xếp thực thi (Run-time stack)


Trước khi tiến hành, đầu tiên chúng ta cần
thảo luận về cách thức kích hoạt một hàm khi nó
được gọi. Nghĩa là, khi một hàm bắt đầu thực thi,
các biến cục bộ của nó phải được cấp các vị trí
trong bộ nhớ.
Mẫu tin kích hoạt được định vị ở đâu trong bộ
nhớ? Có hai chọn lựa như sau:
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.1 Ngăn xếp thực thi (Run-time stack)
Chọn lựa 1: Bộ dịch có thể quy định một cách hệ
thống một số vùng trống trong bộ nhớ cho mỗi hàm
để chứa mẫu tin kích hoạt.
VD: Hàm A có thể được gán cho vùng bộ nhớ X để
đặt mẫu tin kích hoạt của nó, hàm B lại có thể được
gán cho vùng nhớ Y.
cái gì xảy ra khi hàm A gọi chính nó?
Bản được gọi của hàm A sẽ ghi đè các biến cục bộ
của hàm A, và chương trình sẽ không chạy như ta
mong đợi.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C

9.7.1 Ngăn xếp thực thi (Run-time stack)


Chọn lựa 2: Mỗi lần một hàm được gọi, một mẫu tin
kích hoạt được định vị cho riêng nó trong bộ nhớ.
Khi hàm đó trở về nơi gọi, vùng nhớ của mẫu tin
kích hoạt đó sẽ được đòi lại để gán cho các hàm
khác sau này.
 Mỗi lần gọi một hàm đều lấy một vùng nhớ riêng
cho các biến cục bộ của nó.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C

9.7.1 Ngăn xếp thực thi (Run-time stack)


Chọn lựa 2: Ví dụ, nếu hàm A gọi hàm A, mẫu tin kích hoạt
của bản được gọi sẽ được định vị ở một vị trí khác với vị trí
của bản gọi ban đầu trong bộ nhớ, và dĩ nhiên là hai mẫu
tin kích hoạt này độc lập nhau.
Có một tác nhân làm giảm bớt tính phức tạp của việc thực
hiện chọn lựa 2: quá trình gọi của hàm (tức hàm A gọi hàm
B, hàm B lại gọi hàm C, …) có thể được theo dõi bằng một
cấu trúc dữ liệu ngăn xếp.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.1 Ngăn xếp thực thi (Run-time stack)
Ví dụ:
1 int main()
2 {
3 int a;
4 int b;
5
6 …
7 b = Watt (a);
8 b = Volta (a, b);
9 }
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.1 Ngăn xếp thực thi (Run-time stack)
Ví dụ:
11 int Watt (int a)
12 {
13 int w;
14
15 …
16 w = Volta (w, 20);
17
18 return w;
19 }
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.1 Ngăn xếp thực thi (Run-time stack)
Ví dụ:
21 int Volta (int q, int r)
22 {
23 int k;
24 int m;
25
26 …
27 return w;
28 }
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.1 Ngăn xếp thực thi (Run-time stack)
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.1 Ngăn xếp thực thi (Run-time stack)
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
Để hoàn thành tất cả các việc này, các bước sau cần
phải được thực hiện:
•Đầu tiên, code của hàm gọi (caller) sẽ chép các đối số của
nó vào vùng bộ nhớ để hàm được gọi (callee) có thể truy
xuất được.
•Thứ hai, code ở nơi bắt đầu trong hàm được gọi đẩy mẫu
tin kích hoạt của nó vào stack và lưu các thông tin trạng
thái của biến cục bộ, thanh ghi, … để khi điều khiển trả về
cho nơi gọi, thì đối với nơi gọi mọi thứ như không có gì thay
đổi, từ các biến cục bộ tới các thanh ghi.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C

9.7.2 Quá trình hiện thực


•Thứ ba, hàm được gọi thực thi tác vụ của nó.
•Thứ tư, khi hàm được gọi hoàn thành việc của nó, mẫu
tin kích hoạt của nó được lấy ra khỏi ngăn xếp thực thi
(run-time stack) và điều khiển được trả về cho nơi gọi.
•Sau cùng, một khi điều khiển được trả về cho code nơi
gọi, code thực thi sẽ truy tìm trị mà hàm được gọi trả về.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C

9.7.2 Quá trình hiện thực


Gọi hàm
Trong mệnh đề w = Volta(w, 20); hàm Volta() được gọi với
hai đối số. Sau đó giá trị trả về từ hàm Volta() sẽ được gán
cho biến nguyên cục bộ w. Trong khi dịch việc gọi hàm này,
bộ dịch tạo ra code LC-3 làm các việc sau:
1) Truyền giá trị của hai đối số của hàm Volta() bằng việc
đẩy chúng trực tiếp vào đỉnh của ngăn xếp thực thi (run-
time stack) mà địa chỉ đang được chứa trong thanh ghi R6.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
Gọi hàm
2) Chuyển điều khiển sang hàm Volta() nhờ lệnh
JSR.
Mã LC-3 thực hiện gọi hàm này như sau:
; đẩy đối số thứ hai vào stack
AND R0, R0, #0 ; R0  0
ADD R0, R0, #20 ; R0  20
ADD R6, R6, #-1
STR R0, R6, #0 ; Push 20
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
Gọi hàm
; đẩy đối số thứ nhất vào stack
LDR R0, R5, #0 ; Lấy trị của biến cục bộ w
ADD R6, R6, #-1
STR R0, R6, #0 ; Push trị này vào stack
; gọi chương trình con
JSR Volta
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
•Thực hiện hàm được gọi
Lệnh được thực hiện ngay sau lệnh JSR trong hàm
Watt() là lệnh đầu tiên trong hàm được gọi Volta().
Code ở chỗ bắt đầu của hàm được gọi xử lý một số
thao tác liên quan tới việc gọi hàm. Việc đầu tiên là định vị
bộ nhớ cho trị trả về bằng cách hàm được gọi sẽ đẩy một
ô nhớ vào stack để chiếm chổ qua việc giảm con trỏ stack .
Và vị trí này sẽ được ghi vào giá trị cần trả về trước khi
điều khiển trả về cho hàm gọi.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
•Thực hiện hàm được gọi
Kế tiếp, hàm được gọi lưu các thông tin về hàm gọi để khi
việc gọi kết thúc, hàm gọi sẽ lấy lại điều khiển chương
trình một cách đúng đắn. Đặc biệt, chúng ta cần lưu địa chỉ
trở về của hàm gọi đang được chứa trong thanh ghi R7 và
con trỏ khung của hàm gọi đang được chứa trong thanh
ghi R5. Một điều quan trọng là cần chép sao con trỏ khung
của hàm gọi mà ta gọi là liên kết động, để khi điều khiển
trả về cho nơi gọi thì nơi gọi sẽ có thể truy xuất trở lại các
biến cục bộ của nó.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
•Thực hiện hàm được gọi:
Nếu một trong địa chỉ trở về hoặc liên kết động bị sai, thì
chúng ta sẽ gặp sai sót khi tiếp tục thực thi hàm gọi khi
hàm được gọi hoàn thành. Nên chúng ta cần phải sao lưu
cả hai thứ này vô bộ nhớ.
Sau cùng, khi tất cả điều này được thực thi xong, hàm
được gọi sẽ định vị đủ không gian trong stack cho các biến
cục bộ của nó bằng việc chỉnh trị cho R6, và nó sẽ đặt R5
chỉ tới nền của các biến cục bộ này.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
• Thực hiện hàm được gọi
Danh sách các tác vụ phải diễn ra lúc bắt đầu một hàm:
- Hàm được gọi lưu không gian trong stack cho trị trả về.
Trị trả về được định vị ngay trên đỉnh các tham số của
hàm được gọi.
- Hàm được gọi đẩy một bản sao của địa chỉ trở về trong
thanh ghi R7 vô stack.
- Hàm được gọi đẩy một bản sao của liên kết động (con trỏ
khung của hàm gọi) trong R5 vô stack.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
• Thực hiện hàm được gọi
- Hàm được gọi định vị đủ không gian trong stack cho các
biến cục bộ của nó và chỉnh thanh ghi R5 chỉ tới nền của
danh sách biến cục bộ và thanh ghi R6 chỉ tới đỉnh stack.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
• Thực hiện hàm được gọi
Đoạn code hoàn thành việc này cho hàm Volta() như sau:
ADD R6, R6, #-1 ; dành không gian cho trị trả về
ADD R6, R6, #-1
STR R7, R6, #0 ; đẩy R7 (địa chỉ trở về) vô stack
ADD R6, R6, #-1 ; đẩy liên kết động vô stack (con trỏ
khung của hàm gọi)
STR R5, R6, #0 ; đẩy R5 vô stack
ADD R5, R6, #-1 ; đặt con trỏ khung mới
ADD R6, R6, #-2 ; định vị không gian cho các biến cục
bộ
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
• Thực hiện hàm được gọi
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
• Kết thúc hàm được gọi
Một khi hàm được gọi hoàn thành công việc của nó, nó
phải làm thêm một số tác vụ nữa trước khi trả điều khiển
về cho hàm gọi. Đầu tiên, ta cần có cơ chế để một hàm
trả về trị một cách thích hợp cho nơi gọi. Thứ hai, hàm
được gọi phải lấy ra khỏi stack mẫu tin kích hoạt của nó.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
• Kết thúc hàm được gọi
Như vậy, ta có các việc như sau:
1) Nếu có một trị trả về, nó cần phải được ghi vô đầu vào
trị trả về của mẫu tin kích hoạt.
2) Các biến cục bộ phải được lấy ra khỏi stack.
3) Liên kết động cần được phục hồi.
4) Địa chỉ trả về phải được phục hồi.
5) Lệnh RET trả điều khiển về cho hàm gọi.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
• Kết thúc hàm được gọi
Hàm Volta() khi lệnh return k; được thi hành như sau:
LDR R0,R5,#0 ; nạp biến cục bộ k
STR R0,R5,#3 ; lưu nó vô đầu vào trị trả về
ADD R6,R5,#1 ; pop các biến cục bộ
LDR R5,R6,#0 ; pop liên kết động, con trỏ khung -> R5
ADD R6,R6,#1 ; R6 chỉ tới ô địa chỉ trả về
LDR R7,R6,#0 ; lưu địa chỉ trả về cho R7
ADD R6,R6,#1 ; R6 chỉ tới ô trị trả về
RET ; trả điều khiển về cho nơi gọi
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
• Trở về hàm gọi
Sau khi hàm được gọi thực thi lệnh RET, điều khiển
được trả ngược về cho hàm gọi. Trong một số trường
hợp, không có trị trả về (tức hàm được gọi được khai báo
với kiểu void) và, trong một số trường hợp khác, hàm gọi
bỏ qua các trị trả về (như khi ta gọi getch();).
Đặc biệt, có hai thao tác phải được thi hành:
1) Trị trả về (nếu có) được lấy ra khỏi stack.
2) Các đối số cần được lấy ra khỏi stack.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C

9.7.2 Quá trình hiện thực


• Trở về hàm gọi
Đoạn code LC-3 sau lệnh JSR sẽ như sau:
JSR Volta

LDR R0, R6, #0 ; nạp trị trả về ở đỉnh stack


STR R0, R5, #0 ; w = Volta(w, 20);
ADD R6, R6, #1 ; pop trị trả về
ADD R6, R6, #2 ; pop các đối số
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
• Sao lưu ở nơi gọi và sao lưu ở nơi được gọi
Trong khi thực thi một hàm, R0 tới R3 có thể chứa các
giá trị tạm thời, là một phần của các thao tác tính toán
đang chạy. Thanh ghi từ R4 tới R7 được dành cho các
mục đích khác: thanh ghi R4 là con trỏ chỉ tới vùng dữ
liệu toàn cục, R5 là con trỏ khung, R6 là con trỏ stack, và
R7 được dùng để giữ địa chỉ trở về. Nếu chúng ta gọi
một hàm, dựa theo quy ước gọi hàm chúng ta đã mô tả
thanh ghi R4 tới R7 không thay đổi hay thay đổi theo các
cách đã được xác định trước.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
• Sao lưu ở nơi gọi và sao lưu ở nơi được gọi
Nhưng cái gì xảy ra cho các thanh ghi R0, R1, R2, và R3?
Tổng quát mà nói, chúng ta muốn chắc chắn rằng hàm
được gọi sẽ không chép đè chúng. Để làm được điều
này, các quy ước gọi hàm cụ thể theo một trong hai
phương cách: (1) Nơi gọi sẽ sao lưu các thanh ghi bằng
cách đẩy chúng vô mẫu tin kích hoạt của nó. Đây được
gọi là sao lưu nơi gọi (caller save). Khi điều khiển được
trả về cho nơi gọi, nơi gọi sẽ khôi phục lại các thanh ghi
này bằng việc lấy chúng ra khỏi stack.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.2 Quá trình hiện thực
• Sao lưu ở nơi gọi và sao lưu ở nơi được gọi
(2) Hàm được gọi có thể sao lưu các thanh ghi này bằng
cách thêm vô bốn vùng tin trong vùng thông tin trạng thái
của mẫu tin của nó. Đây chính là sao lưu nơi được gọi
(callee save). Khi nơi được gọi được khởi tạo, nó sẽ sao
lưu R0 tới R3 và R5 và R7 vô vùng thong tin trạng thái và
khôi phục các thanh ghi này lại trước khi trở về nơi gọi.
CHÖÔNG 9
HAØM

9.7 HIỆN THỰC HÀM TRONG C


9.7.3 Tóm lại (GT)
CHÖÔNG 9
HAØM

9.8 KIỂM TRA VÀ SỬA LỖI


9.8.1 Giới thiệu
9.8.2 Các dạng lỗi
9.8.2.1 Lỗi cú pháp
Ví dụ 10.20:
#include <stdio.h>
main()
{ int i, i2
for (i = 0; i < 10; i++)
{ i2 = i * i;
printf (“%d x %d = %d\n”, i, i, i2);
} }
CHÖÔNG 9
HAØM

9.8 KIỂM TRA VÀ SỬA LỖI


9.8.2 Các dạng lỗi
9.8.2.2 Lỗi ngữ cảnh
Ví dụ 10.21:
#include <stdio.h>
main()
{
int i, i2;
for (i = 0; i < 10; i++)
i2 = i * i;
printf (“%d x %d = %d\n”, i, i, i2);
}
CHÖÔNG 9
HAØM

9.8 KIỂM TRA VÀ SỬA LỖI


9.8.2 Các dạng lỗi
9.8.2.2 Lỗi ngữ cảnh
Ví dụ 10.22: Chương trình tính tổng 1+2+ …+ n, với n là trị
nguyên dương được nhập từ bàn phím. Chương trình
được thiết kế với hàm tính tổng.
#include <stdio.h>
int tinh_tong (int n); // prototype của hàm
main()
{ int so;
int tong;
printf (“Moi nhap mot so nguyen duong: ”);
CHÖÔNG 9
HAØM

9.8 KIỂM TRA VÀ SỬA LỖI


9.8.2 Các dạng lỗi
9.8.2.2 Lỗi ngữ cảnh
scanf (“%d”, &so);
tong = tinh_tong (n);
printf (“Tong tu 1 + … + %d = %d\n”, n, tong); }
int tinh_tong (int n)
{ int tong;
int i;
for (i = 1; i <= n; i++)
tong += i;
return tong; }
CHÖÔNG 9
HAØM

9.8 KIỂM TRA VÀ SỬA LỖI


9.8.2 Các dạng lỗi
9.8.2.3 Lỗi giải thuật
Ví dụ 10.23:
#include <stdio.h>
#include <conio.h>
void gptb1 (double a, double b);
main()
{ double a, b; clrscr();
printf ("Nhap 2 he so phuong trinh bac nhat: ");
scanf ("%lf %lf", &a, &b); gptb1 (a, b);
getch(); }
CHÖÔNG 9
HAØM

9.8 KIỂM TRA VÀ SỬA LỖI


9.8.2 Các dạng lỗi
9.8.2.3 Lỗi giải thuật
Ví dụ 10.23:
void gptb1 (double a, double b)
{ printf ("Phuong trinh bac nhat ");
printf ("co 1 nghiem: x = %5.2f \n", -b/a);
}
CHÖÔNG 9
HAØM

9.8 KIỂM TRA VÀ SỬA LỖI

9.8.3 Kiểm tra chương trình


9.8.3.1 Kiểm tra hộp đen
Với kỹ thuật hộp đen này, chúng ta có thể kiểm tra xem dữ
liệu nhập và xuất của chương trình có phù hợp không,
mà không cần phải biết cấu trúc lệnh trong chương trình.
CHÖÔNG 9
HAØM

9.8 KIỂM TRA VÀ SỬA LỖI


9.8.3 Kiểm tra chương trình
9.8.3.1 Kiểm tra hộp trắng
Kỹ thuật kiểm tra hộp trắng tổng quát sử dụng các code
tìm lỗi được đặt trong chương trình một cách có tính
toán. Các code này có thể kiểm tra các điều kiện để chỉ
ra lỗi sai làm chương trình không thực thi đúng. Khi có
một lỗi sai được tìm ra, code sẽ in ra một thông điệp
cảnh báo, hiển thị một vài thông tin có giá trị về lỗi, hoặc
là làm cho chương trình kết thúc sớm. Vì các code tìm lỗi
này xác nhận các điều kiện cụ thể cần giữ trong suốt quá
trình chương trình thực thi, nên chúng ta gọi các code
này là sự xác nhận.
CHÖÔNG 9
HAØM

9.8 KIỂM TRA VÀ SỬA LỖI


9.8.4 Gỡ rối chương trình (debuging)
9.8.4.1 Kỹ thuật phi thể thức
9.8.4.2 Gỡ rối cấp nguồn
- Điểm ngắt (Breakpoints)
- Thực thi từng bước (Single-Stepping)
- Hiển thị giá trị
CHÖÔNG 9
HAØM

9.8 KIỂM TRA VÀ SỬA LỖI


9.8.5 Tính đúng đắn khi lập trình
9.8.5.1 Xác định thật rõ các chi tiết
Ví dụ 10.25:
int Giaithua (int n)
{ int i;
int ketqua = 1; // Kiểm tra trị nhập
if (n < 1 || n > 31)
{ printf (“Trị sai, cần trị trong khoảng 1-31.\n”);
ketqua = -1; }
else
for (i = 1; i <= n; i++) ketqua *= i;
return ketqua; }
CHÖÔNG 9
HAØM

9.8 KIỂM TRA VÀ SỬA LỖI


9.8.5 Tính đúng đắn khi lập trình
9.8.5.2 Thiết kế theo từng khối
9.8.5.3 Lập trình dự phòng
CHÖÔNG 9
HAØM

BAØI TAÄP CUOÁI CHÖÔNG

1. Thieát keá haøm giaûi phöông trình


ax2 + bx + c = 0.
Vieát chöông trình chính söû duïng haøm naøy.
2. Thieát keá haøm in ra maøn hình chuoãi soá Fibonaci, vôùi
thoâng soá nhaäp laø moät soá ngaãu nhieân trong soá töø 1 ñeán
100.
Höôùng daãn: Söû duïng haøm random() vaø randomize() ñeå
taïo soá ngaãu nhieân. Daõy Fibonacci : 0, 1, 1, 2, 3...
CHÖÔNG 9
HAØM

BAØI TAÄP CUOÁI CHÖÔNG

3. Thieát keá haøm tính caùc bieåu thöùc sau ñaây:


1 1 2 1  2  ...  n
T   ... 
1! 2! n!
S =(1)! + (1+2)! +...+ (1+...+n)!
4. Thieát keá haøm veõ ra maøn hình hình sau:
*
***
***** n nhaäp
*******
CHÖÔNG 9
HAØM

BAØI TAÄP CUOÁI CHÖÔNG

5. Thieát keá haøm vaø veõ ra maøn hình hình sau:


********
**** *
**** *
**** * n nhaäp laø soá chaün
* ****
* ****
* ****
********
CHÖÔNG 9
HAØM

BAØI TAÄP CUOÁI CHÖÔNG

6. Vieát chöông trình thieát keá hai haøm max() vaø min() cho
pheùp tìm soá lôùn nhaát vaø nhoû nhaát trong loaït soá ñaõ nhaäp.
Loaït soá nhaäp naøy seõ keát thuùc vieäc nhaäp baèng vieäc nhaán
phím <F6>
7. Vieát moät chöông trình cho pheùp nhaäp moät chuoãi. Haõy
thieát keá moät haøm cho pheùp caét chuoãi ñoù ra laøm nhieàu töø
vaø in ra maøn hình moãi töø treân moät haøng.
CHÖÔNG 9
HAØM

BAØI TAÄP CUOÁI CHÖÔNG

8. Vieát moät haøm nhaän moät chuoãi vaø cho pheùp ñaûo chuoãi
ñoù, in ra keát quaû.
9. Vieát moät haøm cho pheùp nhaän moät soá nguyeân döông. In
ra maøn hình kyù soá thöù n tính töø beân phaûi qua cuûa soá ñoù.
Ví duï:
Nhaäp: 12345 4
Xuaát: 2
CHÖÔNG 9
HAØM

BAØI TAÄP CUOÁI CHÖÔNG

10. Thieát keá moät haøm ñeä quy cho pheùp nhaän moät soá
nguyeân döông, in ra maøn hình soá ñoù ôû daïng nhò phaân.
11. Vieát haøm ñeä quy tính xn.
12. Vieát moät haøm nhaän moät soá döông coù phaàn leû vaø in ra
maøn hình phaàn nguyeân vaø phaàn leû rieâng bieät.
13. Vieát chöông trình vôùi haøm tính toång sau:
S=1 - x2/2! + x4/4! - … ± xn/n!
14. Töông töï nhö baøi 10.13, nhöng tính toång sau:
S=1 - x3/3! + x5/5! - … ± xn/n!
CHÖÔNG 9
HAØM

KEÁT THUÙC CHÖÔNG 9

You might also like