You are on page 1of 16

Ch¬ng III.

Kü thuËt lËp tr×nh ®¬n thÓ


I. §Þnh nghÜa vµ sö dông ®¬n thÓ

1. Kh¸i niÖm – ph©n lo¹i


Kh¸i niÖm: §¬n thÓ (hay Module) lµ mét ®o¹n ch¬ng tr×nh ®îc viÕt
theo mét cÊu tróc nµo ®ã, gi¶i quyÕt mét vÊn ®Ò t¬ng ®èi ®éc lËp cña bµi
to¸n.
Khi viÕt mét ch¬ng tr×nh, chóng ta cã thÓ triÓn khai theo hai c¸ch:
C¸ch 1: Toµn bé c¸c lÖnh cña ch¬ng tr×nh ®îc viÕt trong hµm main().
C¸c lÖnh ®îc viÕt theo tr×nh tù ®Ó gi¶i quyÕt bµi to¸n ®Æt ra.
C¸ch 2: Ch¬ng tr×nh ®îc t¹o thµnh tõ nhiÒu ®¬n thÓ kh¸c nhau. C¸c
®¬n thÓ thùc hiÖn nh÷ng nhiÖm vô t¬ng ®èi ®éc lËp vµ ®îc “l¾p ghÐp” l¹i
thµnh ch¬ng tr×nh th«ng qua nh÷ng lêi gäi ®¬n thÓ trong hµm main().
u nhîc ®iÓm:
- Víi c¸ch 1: sÏ thÝch hîp khi viÕt nh÷ng ch¬ng tr×nh cã kÝch thíc nhá.
Toµn bé thuËt to¸n ®îc thÓ hiÖn trong mét ®o¹n m· tõ trªn xuèng díi. Tuy
nhiªn, c¸ch nµy kh«ng phï hîp víi c¸c ch¬ng tr×nh lín do:
+ KÝch thíc ch¬ng tr×nh cång kÒnh, khã kiÓm so¸t, chØnh söa.
+ C¸c ®o¹n m· cã thÓ lÆp ®i lÆp l¹i, ch¬ng tr×nh dµi kh«ng cÇn
thiÕt.
- Víi c¸ch 2: Ch¬ng tr×nh ®îc chia nhá thµnh c¸c ®¬n thÓ kh¾c phôc ®îc
hai nhîc ®iÓm c¬ b¶n trªn. §Æc biÖt phï hîp víi c¸c ch¬ng tr×nh cã kÝch thíc
lín.
Trong C++, ta cã hai lo¹i ®¬n thÓ sau:
[1]. C¸c líp ®èi tîng: Ch¬ng tr×nh bao gåm mét sè ®o¹n m· m« t¶ c¸c líp
c¸c ®èi tîng nµo ®ã sÏ sö dông trong ch¬ng tr×nh chÝnh. Lo¹i ®¬n thÓ nµy ®-
îc nghiªn cøu trong néi dung m«n häc “LËp tr×nh híng ®èi tîng”.
[2]. C¸c hµm: Ch¬ng tr×nh ®îc cÊu t¹o tõ c¸c hµm. Mçi hµm thùc thi
mét nhiÖm vô t¬ng ®èi ®éc lËp, trong ®ã cã mét hµm main ®ãng vai trß nh
ch¬ng tr×nh chÝnh ®Ó sö dông c¸c hµm kh¸c.
Trong ph¹m vi m«n häc, ta chØ xem xÐt c¸c ®¬n thÓ díi d¹ng c¸c hµm.
2. C¸c ®Æc trng cña hµm
Mét hµm trong C++ cã c¸c ®Æc trng sau:
§Ò c¬ng chi tiÕt Kü thuËt lËp tr×nh

[1]. Tªn hµm: do ngêi lËp tr×nh tù ®Æt vµ cã nh÷ng ®Æc ®iÓm sau:
+ Tªn hµm thêng mang tÝnh ®¹i diÖn cho c«ng viÖc mµ hµm sÏ ®¶m
nhiÖm.
+ Tªn hµm ®îc ®Æt tuú ý nhng tu©n theo quy íc ®Æt tªn trong C++.
[2]. KiÓu gi¸ trÞ tr¶ vÒ cña hµm: NÕu hµm tr¶ vÒ mét gi¸ trÞ th× gi¸
trÞ ®ã ph¶i thuéc mét kiÓu d÷ liÖu nµo ®ã; ta gäi lµ kiÓu gi¸ trÞ tr¶ vÒ cña
hµm. KiÓu gi¸ trÞ tr¶ vÒ cña hµm cã thÓ lµ c¸c kiÓu d÷ liÖu chuÈn.
[3]. C¸c ®èi cña hµm: NÕu hµm sö dông c¸c ®èi th× c¸c ®èi ph¶i
thuéc mét kiÓu d÷ liÖu nµo ®ã. Khi thiÕt lËp mét hµm, ta cÇn chØ ra danh
s¸ch c¸c ®èi cña hµm vµ kiÓu d÷ liÖu cña mçi ®èi.
[4]. Th©n hµm: lµ néi dung chÝnh cña hµm, chøa toµn bé c¸c lÖnh cña
hµm.
3. Ph©n lo¹i hµm
Tïy theo nguån gèc cña hµm ta ph©n ra:
- C¸c hµm cã s½n: Lµ c¸c hµm chøa trong c¸c th viÖn cña C++, ®· ®îc
®Þnh nghÜa tõ tríc. C¸c hµm nµy ®îc ®Æt trong c¸c th viÖn .h. Ngêi lËp
tr×nh chØ viÖc sö dông chóng th«ng qua c¸c chØ thÞ:
#include <Tªn th viÖn chøa hµm>
mµ kh«ng cÇn ®Þnh nghÜa hµm.
VD: C¸c hµm sqrt(); sin(); cos(); gets(); puts() .v.v…
- C¸c hµm tù ®Þnh nghÜa: Lµ c¸c hµm mµ tríc khi dïng chóng ta ph¶i
®Þnh nghÜa chóng. C¸c hµm nµy còng cã thÓ ®îc tËp hîp l¹i trong mét file .h
®Ó dïng nh mét th viÖn cã s½n.
Tuú theo kiÓu cña gi¸ trÞ tr¶ vÒ cña hµm ta ph©n ra:
- Hµm kh«ng cã gi¸ trÞ tr¶ vÒ: Lµ hµm chØ cã chøc n¨ng thùc hiÖn mét
c«ng viÖc nµo ®ã mµ ta kh«ng quan t©m tíi gi¸ trÞ tr¶ vÒ cña hµm. C¸c gi¸
trÞ tÝnh to¸n ®îc trong th©n hµm thêng ®îc kÕt xuÊt lªn mµn h×nh.
- Hµm cã gi¸ trÞ tr¶ vÒ: Ngoµi viÖc thùc hiÖn mét c«ng viÖc nµo ®ã,
hµm nµy cßn tr¶ vÒ mét gi¸ trÞ th«ng qua tªn hµm. Gi¸ trÞ nµy cã thÓ ®îc dïng
trong nh÷ng ®o¹n tr×nh tiÕp theo sau lêi gäi hµm.
NhËn xÐt:

Biªn so¹n: NguyÔn M¹nh Cêng Trang 1


§Ò c¬ng chi tiÕt Kü thuËt lËp tr×nh

- Trong pascal, ta cã hai lo¹i ch¬ng tr×nh con: thñ tôc (procedure) vµ hµm
(function). Trong C++, chóng ta cã duy nhÊt mét lo¹i “ch¬ng tr×nh con” (mµ ta
gäi lµ ®¬n thÓ), ®ã lµ hµm.
- Mét ch¬ng tr×nh trong C++ ®îc cÊu t¹o tõ c¸c hµm, trong ®ã hµm main
lµ hµm b¾t buéc ph¶i cã, ®ãng vai trß nh ch¬ng tr×nh chÝnh.
4. §Þnh nghÜa vµ sö dông hµm
a. CÊu tróc mét hµm:
Mét hµm thêng cã cÊu tróc nh sau:
- Hµm kh«ng cã gi¸ trÞ tr¶ vÒ (hµm void):

<KiÓu hµm> <Tªn hµm> <([<kiÓu ®èi> <tªn ®èi>])>


{
//C¸c lÖnh trong th©n hµm;
}

- Hµm cã gi¸ trÞ tr¶ vÒ:

void <Tªn hµm> <([<kiÓu ®èi> <tªn ®èi>])>


{
//C¸c lÖnh trong th©n hµm;
}

Trong ®ã:
- <KiÓu hµm>: lµ kiÓu gi¸ trÞ tr¶ vÒ cña hµm. NÕu hµm kh«ng cã gi¸
trÞ tr¶ vÒ, ta dïng kiÓu void. Ngîc l¹i, ta thêng sö dông c¸c kiÓu chuÈn nh
int, float, double, char…
- <Tªn hµm>: do ngêi dïng tù ®Þnh nghÜa.
- [<kiÓu ®èi> <tªn ®èi>]: liÖt kª danh s¸ch c¸c ®èi cña hµm vµ kiÓu d÷
liÖu cña ®èi (nÕu hµm cã ®èi).
VD1: hµm tÝnh n! ®îc viÕt theo 2 d¹ng: cã vµ kh«ng cã gi¸ trÞ tr¶ vÒ:

C¸ch 1: Hµm cã gi¸ trÞ tr¶ vÒ C¸ch 2: Hµm kh«ng cã gi¸ trÞ tr¶ vÒ
long GT(int n) void GT(int n)
{ {
long kq=1; long kq=1;
for (int i=1; i<=n; i++) for (int i=1; i<=n; i++)
kq *=i; kq *=i;
return kq; cout<<kq;
} }

NhËn xÐt:

Biªn so¹n: NguyÔn M¹nh Cêng Trang 2


§Ò c¬ng chi tiÕt Kü thuËt lËp tr×nh

- Hai ®iÓm kh¸c nhau c¬ b¶n gi÷a hai lo¹i hµm nµy lµ: KiÓu tr¶ vÒ
(long vµ void) vµ c©u lÖnh cuèi hµm (return kq; vµ cout<<kq;)
- NÕu hµm cã gi¸ trÞ tr¶ vÒ th× trong th©n hµm thêng dïng lÖnh:
return <Gi¸ trÞ tr¶ vÒ>;
Khi ®ã, gi¸ trÞ tr¶ vÒ sÏ ®îc g¸n vµo tªn hµm. Bªn ngoµi hµm ta sö dông gi¸
trÞ tr¶ vÒ nµy th«ng qua tªn hµm.
- <Gi¸ trÞ tr¶ vÒ> cã thÓ lµ h»ng, biÕn hoÆc hµm.
VD2: ViÕt hµm tÝnh gi¸ trÞ biÓu thøc
 1 1 1 1
1   2  3  ...  n nÕun ch½n
F=  2 2 2 2
 n 1
2
nÕun lÎ

float F(int n) void F(int n)


{ {
float kq; float kq;
if (n%2==1) if (n%2==1)
kq=sqrt(n*n+1); kq=sqrt(n*n+1);
else else
{ {
kq=1; int Mau = 1; kq=1; int Mau = 1;
for(int i=1; i<=n; i++) for(int i=1; i<=n; i++)
{ {
Mau *=2; Mau *=2;
kq+=1/Mau; kq+=1/Mau;
} }
return kq; cout<<kq;
} }

Mét vÊn ®Ò ®Æt ra lµ: khi nµo th× viÕt hµm díi d¹ng cã gi¸ trÞ tr¶
vÒ, khi nµo th× viÕt hµm kh«ng cã gi¸ trÞ tr¶ vÒ?
Nãi chung, tuú thuéc vµo bµi to¸n cô thÓ ta cã thÓ quyÕt ®Þnh ®iÒu
nµy, tuy nhiªn:
- NÕu ta chØ dïng hµm ®Ó thùc thi mét c«ng viÖc nµo ®ã mµ kÕt qu¶
cña nã chØ cÇn ®îc kÕt xuÊt ra mµn h×nh lµ ®ñ th× hµm thêng ®îc viÕt díi
d¹ng kh«ng cã gi¸ trÞ tr¶ vÒ.
- NÕu kÕt qu¶ tr¶ vÒ cña hµm cã thÓ ®îc dïng trong nh÷ng c«ng viÖc
tiÕp theo (tøc ta cßn sö dông chóng sau nµy) th× hµm thêng ®îc viÕt díi d¹ng
cã gi¸ trÞ tr¶ vÒ.
b. C¸ch tæ chøc c¸c hµm

Biªn so¹n: NguyÔn M¹nh Cêng Trang 3


§Ò c¬ng chi tiÕt Kü thuËt lËp tr×nh

C¸ch 1: C¸c hµm ®Æt trong cïng mét tÖp víi hµm main().
Ch¬ng tr×nh ngoµi hµm main() cßn cã c¸c hµm kh¸c th× ®îc viÕt theo
cÊu tróc sau:

D¹ng 1: Hµm ®Æt tríc hµm main() D¹ng 2: Hµm ®Æt sau hµm main()

#include… #include…
…. ….
//C¸c hµm ®Æt ë ®©y //Nguyªn mÉu cña hµm ®Æt ë ®©y
… …
void main() void main()
{ {
Th©n hµm main; Th©n hµm main;
} }
//C¸c hµm ®Æt ë ®©y

C¸ch 2: C¸c hµm ®Æt trong th viªn:


B1: ViÕt c¸c hµm (trõ hµm main()) trong mét file sau ®ã lu díi ®Þnh
d¹ng .h. File nµy thêng ®îc gäi lµ file th viÖn. (®Ó thuËn tiÖn cho viÖc so¸t
lçi, tèt nhÊt tríc tiªn nªn tæ chøc c¸c hµm nh c¸ch 1, sau ®ã di chuyÓn toµn bé
c¸c hµm (trõ hµm main() sang mét file .h vµ lu l¹i)
B2: Më mét tÖp míi vµ viÕt hµm main() trong mét tÖp nµy. §Ó hµm
main() cã thÓ sö dông c¸c hµm viÕt trong file th viÖn ®· t¹o trong B1, cÇn
thªm chØ thÞ: #include <[ ®êng dÉn] <Tªn th viÖn.h>
Chó ý: nÕu ®Æt file th viÖn trªn trong th môc TC\ Include th× trong
chØ thÞ #include… kh«ng cÇn thªm ®êng dÉn. Ngîc l¹i, cÇn thªm ®Çy ®ñ ®-
êng dÉn tíi file th viÖn nãi trªn.
VD: T¹o file th viÖn TV.h víi néi dung sau:
int NT(int n)
{
if (n ==1 || n ==2)
return =1;
else
{Check =1;
for (int i=2; i<n; i++)
if (n%i==0) Check =0;
return Check;
}
}

Biªn so¹n: NguyÔn M¹nh Cêng Trang 4


§Ò c¬ng chi tiÕt Kü thuËt lËp tr×nh

long GT(int n)
{long kq=1;
if (n==0 || n==1)
kq=1;
else
for (int i=1; i<=n; i++)
kq *=i;
return kq;
}
Më mét file (.CPP) míi vµ viÕt hµm main():
#include <conio.h>
#include <stdio.h>
#include <iostream.h>
#include <C:\TC\BIN\ TV.h”
void main()
{
int a;
cout<<”NhËp a”;
cin>>a;
if (NT(a) == 0)
cout<<”Sè “<<a<<” Kh«ng ph¶i nguyªn tè”;
else
{
cout<<”Sè “<<a<<” lµ sè nguyªn tè”;
cout<<” Giai thõa cña “<<a<<” lµ “<<GT(a);
}
getch();
}
Chó ý:
- C¸c file th viÖn .h kh«ng nhÊt thiÕt ph¶i cã c¸c chØ thÞ tiÒn xö lý
#include …
- Kh«ng thÓ so¸t lçi b»ng c¸ch bÊm F9 trong file th viÖn .h.
c. Sö dông hµm
§Ó n¾m c¸ch sö dông hai lo¹i hµm trªn, ta xÐt c¸ch sö dông c¸c biÕn vµ
c¸c lÖnh trong ch¬ng tr×nh.
Gi¶ sö ta xÐt a, b lµ mét biÕn vµ gets() lµ mét lÖnh cã trong ch¬ng
tr×nh. khi ®ã:
C¸ch viÕt sai C¸ch viÕt ®óng
a; b = a;
cout<<gets(b); gets(a);
Tøc lµ:
- C¸c biÕn kh«ng ®îc dïng mét c¸ch ®éc lËp mµ lu«n ®îc viÕt trong mét
lÖnh nµo ®ã hoÆc trong biÓu thøc cña lÖnh g¸n.

Biªn so¹n: NguyÔn M¹nh Cêng Trang 5


§Ò c¬ng chi tiÕt Kü thuËt lËp tr×nh

- C¸c lÖnh cã thÓ ®îc dïng ®éc lËp mµ kh«ng thÓ dïng lÖnh nµy bªn
trong lÖnh kia.
Ghi nhí:
- C¸c hµm cã gi¸ trÞ tr¶ vÒ dïng nh mét biÕn.
- C¸c hµm kh«ng cã gi¸ trÞ tr¶ vª dïng nh mét lÖnh.
Mét sè nguyªn t¾c khi dïng hµm:
- NÕu hµm ®îc ®Þnh nghÜa cã ®èi sè th× khi gäi hµm ta ph¶i truyÒn
®Çy ®ñ c¸c tham sè (hay ®èi sè thùc sù) cho hµm.
- C¸c tham sè ph¶i cã kiÓu trïng víi kiÓu cña ®èi sè t¬ng øng.
- NÕu hµm kh«ng cã ®èi sè th× lêi gäi hµm vÉn ph¶i sö dông dÊu () kÌm
tªn hµm: <Tªn hµm> <( )>.
5. Ph¹m vi cña biÕn
Theo ph¹m vi ho¹t ®éng cña biÕn, ta chia ra:
- BiÕn toµn côc: lµ c¸c biÕn cã ph¹m vi ho¹t ®éng trong toµn bé ch¬ng
tr×nh, kÓ tõ vÞ trÝ khai b¸o biÕn.
VÞ trÝ khai b¸o biÕn toµn côc n»m ngoµi c¸c hµm (kÓ c¶ hµm main).
NÕu ch¬ng tr×nh ®îc viÕt trªn nhiÒu tÖp, ®Ó ph¹m vi ho¹t ®éng cña
biÕn bao gåm c¶ c¸c tÖp kh¸c, ta cÇn thªm chØ danh extern vµo tríc khai b¸o
biÕn.
- BiÕn côc bé: lµ c¸c biÕn cã ph¹m vi ho¹t ®éng bÞ h¹n chÕ: NÕu biÕn
®îc khai b¸o trong th©n mét khèi nµo ®ã sÏ cã ph¹m vi ho¹t ®éng chØ trong
khèi, kÓ c¶ c¸c khèi con n»m bªn trong khèi ®ã.
+ KÕt thóc khèi, biÕn côc bé sÏ ®îc gi¶i phãng.
+ Muèn biÕn nµy tån t¹i trong suèt thêi gian ch¬ng tr×nh lµm viÖc, ta
cÇn thªm tõ khãa static tríc khai b¸o biÕn ®Ó khai b¸o biÕn díi d¹ng biÕn
tÜnh.
VD1: XÐt vÝ dô sau:
int x;
void Ham(int a)
{
cout<<”BiÕn x trong hµm “<<x; //bien toan cuc
if (a%2==0)
{ int x=5; x+= a;
cout<<”BiÕn x trong hµm “<< x; // bien cuc bo
}

Biªn so¹n: NguyÔn M¹nh Cêng Trang 6


§Ò c¬ng chi tiÕt Kü thuËt lËp tr×nh

}
void main()
{
x=1; int a = 2;
Ham(a);
cout<< “BiÕn x trong hµm main “<<x; //bien toan cuc
int x = 3;
cout<<”BiÕn x trong hµm main “<<x; //bien cuc bo
getch();
}
NhËn xÐt:
- BiÕn x díi d¹ng toµn côc cã ph¹m vi ho¹t ®éng trong toµn bé ch¬ng
tr×nh, kÓ tõ khi khai b¸o.
- NÕu trong mét khèi cã khai b¸o biÕn côc bé trïng tªn víi viÕn toµn côc
th× kÓ tõ khi khai b¸o, khèi ®ã sÏ sö dông biÕn côc bé mµ kh«ng sö dông biÕn
toµn côc.
II. Sö dông c¸c tham sè trong lËp tr×nh ®¬n thÓ

1. Ph©n lo¹i c¸ch truyÒn tham sè


NÕu hµm cã ®èi sè (tham sè h×nh thøc), khi gäi hµm ta ph¶i truyÒn c¸c
tham sè t¬ng øng cho hµm. C¸c tham sè cã thÓ lµ c¸c biÕn hoÆc c¸c h»ng gi¸ trÞ.
Cã hai c¸ch truyÒn tham sè:
[1]. TruyÒn d¹ng tham chiÕu: Khi truyÒn tham sè díi d¹ng tham chiÕu,
tham sè lµ c¸c biÕn vµ tham sè sÏ ®îc truy cËp trùc tiÕp. Nh vËy, c¸c tham sè
®îc truyÒn vµo mét hµm th× sau khi ra khái hµm, gi¸ tÞ cña chóng cã thÓ bÞ
thay ®æi.
[2]. TruyÒn d¹ng tham trÞ: Khi truyÒn tham sè díi d¹ng tham trÞ, tham
sè sÏ kh«ng ®îc truy cËp trùc tiÕp. Hµm sÏ cÊp ph¸t mét vïng nhí míi vµ sao
chÐp gi¸ trÞ cña tham sè vµo ®ã. C¸c lÖnh trong th©n hµm sÏ thao t¸c trªn
vïng nhí míi nµy. Nh vËy, mét tham sè khi truyÒn vµo mét hµm díi d¹ng tham
trÞ sÏ kh«ng bÞ tham ®æi gi¸ trÞ cña nã khi ra khái hµm.

BiÕn Vïng nhí BiÕn Vïng nhí


cña biÕn cña biÕn
Vïng nhí
míi
Gäi hµm Thùc thi Gäi hµm Thùc thi
hµm hµm

Biªn so¹n: NguyÔn M¹nh Cêng Trang 7


§Ò c¬ng chi tiÕt Kü thuËt lËp tr×nh

a) truyÒn tham chiÕu b) TruyÒn tham trÞ


2. TruyÒn tham sè
NÕu ch¬ng tr×nh viÕt trong c¸c file cã phÇn më réng .h, ta cã duy nhÊt
mét c¸ch truyÒn tham sè: TruyÒn theo tham trÞ. Tõ C++3.0 trë lªn, cho phÐp
sö dông c¶ hai c¸ch truyÒn tham sè trong c¸c ch¬ng tr×nh viÕt díi d¹ng c¸c
file .CPP.
XÐt trêng hîp ta cã c¸c biÕn th«ng thêng (kh«ng ph¶i lµ biÕn con trá)
- NÕu biÕn ®îc truyÒn díi d¹ng th«ng thêng th× c¸ch truyÒn ®ã lµ
truyÒn theo tham trÞ.
- NÕu ta kh«ng truyÒn biÕn vµo hµm mµ thay vµo ®ã, ta truyÒn ®Þa
chØ cña biÕn vµo th× ®ã lµ c¸ch truyÒn tham chiÕu.
VD: int a=3, b=5;
Ham (&a, b);
Khi ®ã biÕn a ®îc truyÒn vµo hµm díi d¹ng tham chiÕu; biÕn b ®îc
truyÒn vµo hµm díi d¹ng tham trÞ.
XÐt trêng hîp ta cã c¸c biÕn con trá.
V× b¶n th©n con trá thêng chøa ®Þa chØ cña biÕn nµo ®ã (mµ nã trá
tíi) nªn khi truyÒn con trá vµo hµm th× mÆc nhiªn ®· lµ truyÒn theo d¹ng
tham chiÕu.
VD: int a, *p;
a = 5; p = & a;
Ham(p);
Khi ®ã biÕn p ®îc truyÒn vµo hµm nhng thùc chÊt lµ ta ®· chuyÒn
®Þa chØ cña a vµo hµm. VËy cã thÓ coi ®©y lµ trêng hîp truyÒn biÕn a vµo
hµm díi d¹ng tham chiÕu (tøc sau khi ra khái hµm, biÕn a cã thÓ bÞ thay ®æi
gi¸ trÞ).
VD1: XÐt hµm sau:
int tang(int a)
{
a++;
}
void main()
{

Biªn so¹n: NguyÔn M¹nh Cêng Trang 8


§Ò c¬ng chi tiÕt Kü thuËt lËp tr×nh

int n=1;
cout<<”Gi¸ trÞ tríc khi gäi hµm “<<n;
tang(n);
cout<<”Gi¸ trÞ sau khi gäi hµm “<<n;
getch();
}
VD2: xÐt hµm sau
int Ham(int a, int b)
{
if (a%2==0){
a+=1;
b+=a;
}
cout<<”Gi¸ trÞ a trong th©n hµm “<<a;
cout<<Gi¸ trÞ b trong th©n hµm “<<b;
}
void main()
{
int a, b;
a=1;
b=2;
cout<<”Gi¸ trÞ a tríc khi gäi hµm “<<a;
cout<<”Gi¸ trÞ b tríc khi gäi hµm “<<b;
Ham(a, b);
cout<<”Gi¸ trÞ a sau khi gäi hµm “<<a;
cout<<”Gi¸ trÞ b sau khi gäi hµm “<<b;
getch();
}
III. Kü thuËt ®Ö quy

1. Kh¸i niÖm vÒ ®Ö quy


Trong C++, mét hµm cã thÓ gäi ®Õn chÝnh nã. TÝnh chÊt nµy cña
hµm gäi lµ tÝnh ®Ö quy. Khi mét hµm gäi ®Õn chÝnh nã, hµm ®îc viÕt theo
kiÓu ®Ö quy.
VD: XÐt hµm tÝnh n!. Ta cã ®Þnh nghÜa sau: n! = n * (n-1)! .
Hµm lÆp:
long GT(int n)
{
long kq=1;
if (n==0 || n==1)
kq=1;
else
for (int i=1; i<=n; i++)
kq *=i;
return kq;

Biªn so¹n: NguyÔn M¹nh Cêng Trang 9


§Ò c¬ng chi tiÕt Kü thuËt lËp tr×nh

Hµm ®Ö quy:
long GT(int n)
{
if (n==1)
return 1;
else
return GT(n-1) * n;
}

Thùc hiÖn: Gi¶ sö n =3. Khi ®ã, quy tr×nh thùc hiÖn nh sau:

3! = 3 * 2!

2! = 1! * 2

1! = 1

§Ó tÝnh 3! ta cÇn tÝnh 2!; §Ó tÝnh 2 ! ta cÇn tÝnh 1!.

NÕu biÕt 1!=1 th× ta cã thÓ tõ ®ã tÝnh ®îc 2! vµ 3!. VËy thø tù thùc
hiÖn c«ng viÖc tÝnh to¸n sÏ lµ: 1!, 2!, 3! (tøc ph¶i gäi hµm tÝnh n! tíi 3 lÇn
víi 3 ®èi vµo 1, 2, 3).

Mçi lÇn gäi ®Ö quy, ch¬ng tr×nh thùc hiÖn nh sau:

- Lu ®Þa chØ cña dßng lÖnh gäi ®Ö quy.

- T¹o mét t¹o mét b¶n sao cña hµm, cÊp ph¸t c¸c vïng nhí míi cho c¸c biÕn
côc bé, thùc hiÖn b¶n sao nµy.

- LÊy ®Þa chØ cña dßng lÖnh gäi ®Ö quy vµ quay vÒ.

§Ó râ h¬n ta xem s¬ ®å sau:


B¾t ®Çu B¶n sao 1 B¶n sao n

Gäi ®Ö quy Gäi ®Ö quy … Gäi ®Ö quy Bá qua lÖnh


gäi ®Ö quy

Biªn so¹n: NguyÔn M¹nh Cêng Trang 1


KÕt thóc 0
§Ò c¬ng chi tiÕt Kü thuËt lËp tr×nh

Nh vËy cã bao nhiªu lêi gäi hµm th× cã bÊy nhiªu lÇn kÕt thóc hµm.
Trong trêng hîp kh«ng tån t¹i mét b¶n sao cña hµm mµ t¹i ®ã kh«ng thùc hiÖn
hiÖn lêi gäi ®Ö quy th× qu¸ tr×nh ®Ö quy sÏ kh«ng dõng ®îc (ta gäi lµ ®Ö
quy v« h¹n).

Trong vÝ dô vÒ tÝnh n!, víi n=3 vµ c«ng thøc ®Ò quy n! = n * (n-1)!,


s¬ ®å ®Ö quy cã thÓ nh sau:
B¾t ®Çu :
tÝnh 3! Hµm GT(2) Hµm GT(1)

Gäi ®Ö quy Gäi ®Ö quy Gäi ®Ö quy Bá qua lÖnh


gäi ®Ö quy

KÕt thóc
Return 1*2*3 Return 1*2 Return 1

u nhîc ®iÓm cña ph¬ng ph¸p ®Ö quy:


- Ch¬ng tr×nh ng¾n gäi, dÔ hiÓu.
- Qu¸ tr×nh dÞch phøc t¹p.
- Nãi chung, tèn nhiÒu kh«ng gian nhí h¬n lÆp.
Ph¬ng ph¸p ®Ö quy ®Æc biÖt thÝch hîp víi mét sè bµi to¸n nh duyÖt
c©y, ®å thÞ… Tuy nhiªn, nãi chung ta nªn Ýt sö dông ®Ö quy khi viÕt ch¬ng
tr×nh do c¸c nhîc ®iÓm trªn.

2. ThiÕt kÕ ch¬ng tr×nh theo kiÓu ®Ö quy.


C¸c bµi to¸n ¸p dông gi¶i thuËt ®Ö quy thêng cã ®Æc ®iÓm sau:
- Bµi to¸n dÔ dµng gi¶i quyÕt trong mét sè trêng hîp riªng øng víi c¸c gi¸
trÞ ®Æc biÖt cña tham sè. Trong trêng hîp nµy, ta cã thÓ gi¶i quyÕt bµi to¸n
mµ kh«ng cÇn gäi ®Ö quy. Ta gäi trêng hîp nµy lµ trêng hîp suy biÕn.
- Trong trêng hîp tæng qu¸t, bµi to¸n cã thÓ quy vÒ bµi to¸n cïng d¹ng nh-
ng gi¸ trÞ cña tham sè thay ®æi. Vµ sau mét sè h÷u h¹n bíc biÕn ®æi ®Ö quy,
sÏ dÉn tíi trêng hîp suy biÕn.

Biªn so¹n: NguyÔn M¹nh Cêng Trang 1


1
§Ò c¬ng chi tiÕt Kü thuËt lËp tr×nh

Gi¶ sö bµi to¸n tÝnh n!, dÔ dµng thÊy:


- Víi n=0 hoÆc n = 1 th× n! = 1. Khi ®ã ta kh«ng cÇn gäi ®Ö quy vÉn cã
thÓ tÝnh ®îc n!. ta gäi trêng hîp nµy lµ trêng hîp suy biÕn.
- Trêng hîp n > 1: n! = n* (n-1)!. Tøc lµ ®Ó tÝnh n!, ta cã thÓ quy vÒ
bµi to¸n tÝnh (n-1)!. Sau mét sè h÷u h¹n bíc biÕn ®æi, ta cã thÓ quy vÒ bµi
to¸n tÝnh 1!. VËy ®©y lµ trêng hîp tæng qu¸t
Nh vËy:
- Trêng hîp suy biÕn: n=0 hoÆc n=1. Khi ®ã: n! = 1;
- Trêng hîp tæng qu¸t: n > 1. Khi ®ã: n! = n* (n-1)!.
Ch¬ng tr×nh ®Ö quy ®îc thiÕt kÕ nh sau:
Bíc 1: X¸c ®Þnh c¸c trêng hîp suy biÕn – tæng qu¸t
- X¸c ®Þnh trêng hîp suy biÕn: gi¸ trÞ cña tham sè, c«ng thøc ®Ó tÝnh
to¸n trong trêng hîp nµy.
- X¸c ®Þnh trêng hîp tæng qu¸t: gi¸ trÞ cña tham sè, c«ng thøc ®Ó tÝnh
to¸n trong trêng hîp nµy.
Bíc 2: ViÕt khung ch¬ng tr×nh:

if (suy biÕn)
C«ng thøc trong trêng hîp suy biÕn.
else
C«ng thøc trong trêng hîp tæng qu¸t.

VD1: ThiÕt kÕ hµm ®Ö quy tÝnh n!.


Bíc 1:
- Suy biÕn : n=0 hoÆc n = 1; C«ng thøc n! = 1;
- Tæng qu¸t: n kh¸c 0 vµ n kh¸c 1; C«ng thøc n! = n* (n-1)!.
Bíc 2:
if (n= = 0 || n= = 1)
return 1;
else
return n * GT(n-1);
Sau khi thiÕt kÕ, viÖc lËp hµm ®Ö quy trë lªn rÊt ®¬n gi¶n.

Biªn so¹n: NguyÔn M¹nh Cêng Trang 1


2
§Ò c¬ng chi tiÕt Kü thuËt lËp tr×nh

VD2. D·y sè Catalan ®îc ph¸t biÓu ®Ö quy nh sau:


C1 = 1;
n 1

Cn = C C
i 1
i n i

H·y x©y dùng hµm ®Ö quy t×m sè CataLan thø n.


Hµm ®Ö quy ®îc thiÕt kÕ nh sau:
Bíc 1:
- Suy biÕn: n = 1; C«ng thøc suy biÕn: Cn = 1;
n 1

- Kh«ng suy biÕn: n kh¸c 1; c«ng thøc tæng qu¸t: Cn = C C


i 1
i n i

Bíc 2:
if (n = = 1)
return 1;
else
{ int C =0;
for (int i=1; i<n; i++)
C+= CataLan(i) * CataLan(n-i);
Return C;
}
Nh vËy, hµm ®Ö quy tÝnh sè CataLan thø n ®îc viÕt nh sau:
int CataLan(int n)
{
if (n==1)
return 1;
else
{
int C=0;
for (int i=1; i<n; i++)
C+=CataLan(i)*CataLan(n-i);
return C;
}
}

3. §Ö quy vµ c¸c d·y truy håi


Kh¸i niÖm: Mét d·y truy håi lµ d·y mµ c¸c sè h¹ng ®øng sau ®îc ®Þnh
nghÜa dùa trªn sè h¹ng ®øng tríc cña d·y.

Biªn so¹n: NguyÔn M¹nh Cêng Trang 1


3
§Ò c¬ng chi tiÕt Kü thuËt lËp tr×nh

VD: Cho d·y sau:


a[1] = 1;
a[n] = a[n-1] * n;
DÔ dµng thÊy ®©y chÝnh lµ d·y c¸c giai thõa cña c¸c sè tù nhiªn: 1!, 2!,
3!, 4!…
HoÆc d·y c¸c sè Fibonacci:
A[1] = 1;
A[2] = 1;
A[n] = A[n-1] + A[n-2] (víi n>2).
Víi c¸c d·y truy håi, ta hoµn toµn cã thÓ dïng c¸c thuËt to¸n lÆp ®Ó
tÝnh. Tuy nhiªn c¸c gi¶i thuËt ®Ö quy thêng ®îc ¸p dông rÊt hiÖu qu¶ trªn c¸c
d·y truy håi .
4. Mét sè vÝ dô vÒ ®Ö quy
VD1: USCLN cña hai sè nguyªn a, b ®îc ®Þnh nghÜa nh sau:
USCLN(a, b) = a nÕu b =0
= USCLN(b, a%b) nÕu b kh¸c 0.
ViÕt hµm lÆp vµ ®Ö quy ®Ó tÝnh USCLN cña hai sè nguyªn a, b.
Hµm lÆp:
int USCLN_Lap(int a, int b)
{
int Sodu;
while (y !=0)
{
Sodu = a%b;
a = b;
b = Sodu;
}
return a;
}

Hµm ®Ö quy:
Bíc 1:
- Suy biÕn : b=0; c«ng thøc suy biÕn: USCLN(a, b) = b;
- Kh«ng suy biÕn: b kh¸c 0; c«ng thøc tæng qu¸t: USCLN (a, b) =
USCLN(b, a%b);

Biªn so¹n: NguyÔn M¹nh Cêng Trang 1


4
§Ò c¬ng chi tiÕt Kü thuËt lËp tr×nh

Bíc 2:
if (b==0)
return a;
else
return USCLN(b, a%b)
LËp tr×nh:

Int USCLN_DQ(int a, int b)


{
if (b==0)
return a;
else
return USCLN_DQ(b, a%b);
}

VD2: C¸c sè Fibonacci ®îc ®Þnh nghÜa ®Ö quy nh sau:


F[0] = F[1] = 1;
F[i] = F[i-1] + F[i-2];
VD: 1, 1, 2, 3, 5, 8, 13…
ViÕt hµm ®Ö quy t×m sè Fibonacci thø n.
Bíc 1:
- Suy biÕn: n <=1; c«ng thøc suy biÕn: Fibo(n) = 1;
- Kh«ng suy biÕn: n >1; c«ng thøc tæng qu¸t: Fibo(n) = Fibo(n-1) +
Fibo(n-2).
Bíc 2:
if(n<=1)
return 1;
else
return Fibo(n-1) + Fibo(n-2);
LËp tr×nh:
int Fibo(int n)
{
if(n<=1)
return 1;
else
return Fibo(n-1) + Fibo(n-2);
}

Biªn so¹n: NguyÔn M¹nh Cêng Trang 1


5

You might also like