Kỹ thuật lập trình đơn thể

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().

doc16 trang | Chia sẻ: tlsuongmuoi | Lượt xem: 2533 | Lượt tải: 2download
Bạn đang xem nội dung tài liệu Kỹ thuật lập trình đơn thể, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
Ch­¬ng III. Kü thuËt lËp tr×nh ®¬n thÓ §Þnh nghÜa vµ sö dông ®¬n thÓ 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. C¸c ®Æc tr­ng cña hµm Mét hµm trong C++ cã c¸c ®Æc tr­ng sau: [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ú ý nh­ng 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. 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 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: 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. §Þnh nghÜa vµ sö dông hµm 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): ])> { //C¸c lÖnh trong th©n hµm; } - Hµm cã gi¸ trÞ tr¶ vÒ: void ])> { //C¸c lÖnh trong th©n hµm; } Trong ®ã: : 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… : do ng­êi dïng tù ®Þnh nghÜa. [ ]: 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). C¸ch 2: Hµm kh«ng cã gi¸ trÞ tr¶ vÒ C¸ch 1: Hµm cã gi¸ trÞ tr¶ vÒ void GT(int n) { long kq=1; for (int i=1; i<=n; i++) kq *=i; cout<<kq; } long GT(int n) { long kq=1; for (int i=1; i<=n; i++) kq *=i; return kq; } VD1: hµm tÝnh n! ®­îc viÕt theo 2 d¹ng: cã vµ kh«ng cã gi¸ trÞ tr¶ vÒ: NhËn xÐt: 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 ; 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. cã thÓ lµ h»ng, biÕn hoÆc hµm. VD2: ViÕt hµm tÝnh gi¸ trÞ biÓu thøc float F(int n) { float kq; if (n%2==1) kq=sqrt(n*n+1); else { kq=1; int Mau = 1; for(int i=1; i<=n; i++) { Mau *=2; kq+=1/Mau; } return kq; } void F(int n) { float kq; if (n%2==1) kq=sqrt(n*n+1); else { kq=1; int Mau = 1; for(int i=1; i<=n; i++) { Mau *=2; kq+=1/Mau; } cout<<kq; } F = 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Ò. C¸ch tæ chøc c¸c hµm 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: #include… …. //C¸c hµm ®Æt ë ®©y … void main() { Th©n hµm main; } #include… …. //Nguyªn mÉu cña hµm ®Æt ë ®©y … void main() { Th©n hµm main; } //C¸c hµm ®Æt ë ®©y D¹ng 1: Hµm ®Æt tr­íc hµm main() D¹ng 2: Hµm ®Æt sau hµm main() 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 ®ã l­u 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µ l­u 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 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; } } 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 #include #include #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. 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; cout<<gets(b); b = a; 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. 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: . 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 } } 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. Sö dông c¸c tham sè trong lËp tr×nh ®¬n thÓ 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. Thùc thi hµm Vïng nhí cña biÕn BiÕn Gäi hµm Thùc thi hµm Vïng nhí cña biÕn BiÕn Gäi hµm Vïng nhí míi a) truyÒn tham chiÕu b) TruyÒn tham trÞ 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 nh­ng 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() { 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(); } Kü thuËt ®Ö quy 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; } 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! 2! 1! 3 * 2! 1! * 2 = = 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: L­u ®Þ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 Gäi ®Ö quy Gäi ®Ö quy Gäi ®Ö quy KÕt thóc B¶n sao 1 B¶n sao n Bá qua lÖnh gäi ®Ö quy … 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! Gäi ®Ö quy Gäi ®Ö quy Gäi ®Ö quy KÕt thóc Return 1*2*3 Hµm GT(2) Hµm GT(1) Bá qua lÖnh gäi ®Ö quy Return 1 Return 1*2 ­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. 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. 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. VD2. D·y sè Catalan ®­îc ph¸t biÓu ®Ö quy nh­ sau: C1 = 1; Cn = 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; Kh«ng suy biÕn: n kh¸c 1; c«ng thøc tæng qu¸t: Cn = 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; } } §Ö 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. 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 . 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); 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); }

Các file đính kèm theo tài liệu này:

  • docKỹ thuật lập trình đơn thể.doc
Tài liệu liên quan