–Bằng cách thay thếmột dãy các chỉthịbởi một lệnh duy nhấtlệnh gọi hàm/thủtục sẽgiúp mã nguồn dễ đọc và dễduyệt lỗihơn.Hàm có kết quảtrảvềcòn thủtục thì không.Đối sốvà Tham biến Argument
Trang 2Hàm/th ủ t ụ c có th ể đượ c g ọ i t ừ nhi ề u ch ỗ khác nhau trong ch ươ ng trình
– B ằ ng cách thay th ế m ộ t dãy các ch ỉ th ị b ở i m ộ t l ệ nh duy nh ấ t (l ệ nh g ọ i hàm/th ủ t ụ c) s ẽ giúp mã ngu ồ n d ễ đọ c và d ễ duy ệ t l ỗ i
h ơ n.
Hàm có k ế t qu ả tr ả v ề còn th ủ t ụ c thì không.
Đố i s ố và Tham bi ế n (Arguments and Parameters)
Ví d ụ
{ C ộ ng num1 và num2 r ồ i ghi k ế t qu ả vào bi ế n sum}
Procedure Adder(num1 : real; num2 : real; var sum : real);
Trang 3Vài đ i ể m quan tr ọ ng v ề đố i và tham bi ế n c ủ a ch ươ ng trình con:
S ố l ượ ng đố i s ố hay tham s ố th ự c s ự (arguments) nh ấ t thi ế t ph ả i
b ằ ng s ố tham bi ế n (parameters)
Th ứ t ự là quan tr ọ ng Đố i s ố đầ u tiên t ươ ng ứ ng v ớ i tham bi ế n đầ u tiên, đố i s ố th ứ k t ươ ng ứ ng v ớ i tham bi ế n th ứ k, …
Ki ể u d ữ li ệ u c ủ a m ỗ i đố i s ố ph ả i t ươ ng thích v ớ i ki ể u d ữ li ệ u c ủ a tham bi ế n t ươ ng ứ ng.
Tên không quan tr ọ ng Tên c ủ a đố i s ố không nh ấ t thi ế t ph ả i gi ố ng
v ớ i tên tham bi ế n t ươ ng ứ ng c ủ a nó.
Phân bi ệ t hai cách truy ề n d ữ li ệ u cho hàm/th ủ t ụ c: truy ề n theo tham chi ế u ( by reference ) hay truy ề n theo tr ị (by value)
c ủ a đố i s ố đượ c truy n cho ch ươ ng trình con, cho phép ch ươ ng trình con truy nh ậ p t ớ i bi n th ự c s ự và thay đổ i n ộ i dung c ủ a nó.
ch ươ ng trình con, cho phép ch ươ ng trình con truy nh ậ p
đ n “b ả n sao” c ủ a bi n Truy n theo tr ị b ả o toàn n ộ i dung c ủ a bi n ban đầ u
Trang 4– Tránh ph ả i l ặ p l ạ i m ộ t đ o ạ n ch ươ ng trình (code)
2 Các b b ư ư ớ c th ự c hi ệ n phát tri ể n ch ch ươ ươ ng ng trình
Hi ể u rõ yêu c ầ u bài toán: có th ể di ễ n đạ t l ạ i bài toán
b ằ ng ngôn ng ữ đặ c t ả , các kí hi ệ u toán h ọ c hay các công th ứ c.
• M ụ c tiêu chung c ủ a ch ươ ng trình là gì?
• Ch ươ ng trình c ầ n d ữ li ệ u vào là gì?
• D ữ li ệ u ra c ủ a ch ươ ng trình là gì? s ẽ nh ư th ế nào? k ế t xu ấ t ra
đ âu? (màn hình, máy in, đĩ a?)
• D ữ li ệ u vào và ra nên ở đị nh d ạ ng nào?
• Công th ứ c tính hay cách x ử lý th ế nào để có k ế t qu ả (d ữ li ệ u) ra?
Trang 5Các b b ư ư ớ c th ự c hi ệ n phát tri ể n ch ch ươ ươ ng ng trình
Hình thành ý t ưở ng v ề cách gi ả i bài toán
• Ch ươ ng trình có th ể đượ c phân tách thành các quá trình r ờ i
r ạ c (các mô đ un) nh ư th ế nào?
• Ch ươ ng trình chính s ẽ s ử d ụ ng các mô đ un này nh ư th ế nào? Các mô đ un giao ti ế p v ớ i nhau nh ư th ế nào?
• Nh ữ ng mô đ un này có c ầ n tách thành các ph ầ n ch ứ c n ă ng nh ỏ
h ơ n?
Thi ế t k ế thu ậ t toán b ằ ng ph ươ ng pháp tinh ch ỉ nh d ầ n
t ừ ng b ướ c.
Cài đặ t ch ươ ng trình theo thu ậ t toán
• Vi ế t ch ươ ng trình chính (vi ệ c vi ế t các mô đ un nh ư th ế nào s ẽ
hoàn thi ệ n sau Thay vào đ ó, có th ể t ạ m đư a ra nh ữ ng l ệ nh
gi ả đị nh để ch ươ ng trình có th ể h ọ at độ ng Đ i ề u này cho phép th ử nghi ệ m tính logic c ủ a ch ươ ng trình chính)
• Cu ố i cùng, vi ế t các mô đ un Ki ể m nghi ệ m và duy ệ t l ỗ i t ừ ng mô
đ un th ậ t k ỹ r ồ i tr ướ c khi đư a vào ch ươ ng trình chính N ế u mô
đ un đượ c phân tách thành nhi ề u ti ế n trình nh ỏ h ơ n thì ph ả i
vi ế t mã (code) cho các ti ế n trình này tr ướ c, th ử nghi ệ m và duy ệ t l ỗ i c ẩ n th ậ n r ồ i m ớ i ghép l ạ i thành mô đ un
Trang 6PH ƯƠ NG PH ÁP TINH CH Ỉ NH T Ừ NG B NG B Ư Ư Ớ C
Chi ế n l ượ c thi ế t k ế t ừ trên xu ố ng (top - down)
• Thi ế t k ế gi ả i thu ậ t t ừ t ổ ng th ể đế n chi ti ế t
• Module hoá bài toán
– Chia bài toán (module chính) thành các module con cho đế n khi
m ỗ i module con là m ộ t bài toán đ ã bi ế t cách gi ả i quy ế t
• “Chia để tr ị ”
– Chia (Divide): Chia bài toán l ớ n, thành nhi ề u bài toán nh ỏ
– Tr ị (Conquer): Gi ả i t ừ ng bài toán nh ỏ
– K ế t h ợ p (Combine): T ạ o ra l ờ i gi ả i cho bài toán cu ố i cùng b ằ ng cách s ử d ụ ng thông tin t ừ k ế t qu ả gi ả i các bài toán nh ỏ
PH ƯƠ NG PH ÁP TINH CH Ỉ NH T Ừ NG B NG B Ư Ư Ớ C
Stepwise refinement
Module hoá bài toán, thi ế t k ế ki ể u top-down
• B ướ c 0 Trình bày ý chính c ủ a gi ả i thu ậ t b ằ ng ngôn ng ữ t ự
nhiên
• B ướ c 1 tr ở đ i: Chi ti ế t hoá d ầ n nh ữ ng ý trong gi ả i thu ậ t, s ử
d ụ ng nhi ề u ngôn ng ữ gi ả code (gi ả mã − pseudo code) h ơ n
K ế t qu ả cu ố i cùng c ủ a quá trình tinh ch ỉ nh là ch ươ ng trình vi ế t trên ngôn ng ữ l ậ p trình đ ã ch ọ n tr ướ c v ớ i c ấ u trúc d ữ li ệ u d ạ ng
l ư u tr ữ , cài đặ t c ụ th ể
Trang 7• Ý t ưở ng thu ậ t toán:
– Tìm các s ố t ừ 10 đế n 99 tho ả mãn yêu c ầ u và ghi vào m ả ng S và n
là s ố l ượ ng các s ố tìm đượ c.
– Hi ể n th ị k ế t qu ả t ừ m ả ng S ra màn hình.
Trang 9PH ƯƠ NG PH ÁP TINH CH Ỉ NH T Ừ NG B NG B Ư Ư Ớ C
B ướ c 4 Ki ể m tra xem x và s ố đả o c ủ a nó có nguyên t ố
cùng nhau hay không
Function SodaoNTCN
• Vào: x là s ố nguyên d ươ ng
• Ra: True, n ế u x và s ố đả o nguyên t ố cùng nhau
False, n ế u ng ượ c l ạ i
• if x và Sodao(x) là Nguyên t ố cùng nhau then Return True
else Return False;
PH ƯƠ NG PH ÁP TINH CH Ỉ NH T Ừ NG B NG B Ư Ư Ớ C
B ướ c 5 Ki ể m tra hai s ố nguyên d ươ ng có là nguyên t ố
cùng nhau hay không.
Function NTCN
• Vào: x, y là 2 s ố nguyên d ươ ng
• Ra: True, n ế u x và y là nguyên t ố cùng nhau
False, n ế u ng ượ c l ạ i
• if UCLN(x, y) = 1 then Return True
else Return False;
Trang 102 N ế u n b ằ ng 0 thì tr ả v ề UCLN = m và k ế t thúc thu ậ t toán
Ng ượ c l ạ i, chuy ể n sang b ướ c 4.
Trang 15– Giám đố c giao nhi ệ m v ụ c ầ n hoàn thành cho nhân viên
– Nhân viên nh ậ n thông tin, th ự c hi ệ n, tr ả l ạ i k ế t qu ả
– Giám đố c không bi ế t chi ti ế t v ề quá trình th ự c hi ệ n
main
Trang 16• Parameter-list: các tham s ố cách nhau b ằ ng d ấ u “,”
– Ph ả i khai báo ki ể u d ữ li ệ u cho t ừ ng tham s ố
Cú pháp đị nh ngh ĩ a (ti ế p theo)
• Các khai báo và các l ệ nh: thân c ủ a hàm (kh ố i)
– Các bi ế n có th ể đượ c đị nh ngh ĩ a bên trong hàm
– Các hàm không đượ c đị nh ngh ĩ a trong hàm khác
Trang 17fig05_04.c (Part 1 of 2)
1 /* Fig 5.4: fig05_04.c /* Fig 5.4: fig05_04.c
2 Finding the maximum of three integers */ Finding the maximum of three integers */
3 #include <stdio.h> <stdio.h>
4
5 int maximum( int x, int y, int z ); /* function prototype */ /* function prototype */ 6
7 /* function main begins program execution */ /* function main begins program execution */ 8 int main() main() 9 { {
10 int number1; /* first integer */ /* first integer */ 11 int number2; /* second integer */ /* second integer */ 12 int number3; /* third integer */ /* third integer */ 13 14 printf( "Enter three integers: " ); ); 15 scanf( "%d%d%d" , &number1, &number2, &number3 ); , &number1, &number2, &number3 ); 16
17 /* number1, number2 and number3 are arguments /* number1, number2 and number3 are arguments 18 to the maximum function call */ to the maximum function call */ 19 printf( "Maximum is: %d\ "Maximum is: %d \ \n" n" , maximum( number1, number2, number3 ) , maximum( number1, number2, number3 ) maximum( number1, number2, number3 ) ); ); ); 20 21 return ; /* indicates successful termination */ /* indicates successful termination */ 22 23 } /* /* end main */ end main */ end main */ 24 Enter three integers: 22 85 17 Maximum is: 85 Enter three integers: 85 22 17 Maximum is: 85 25 /* Function maximum definition */ /* Function maximum definition */
26 /* x, y and z are parameters */ /* x, y and z are parameters */
27 int maximum( int x, int y, int z ) z )
28 { {
29 int max = x; /* assume x is largest */ /* assume x is largest */
30
31 if ( y > max ) { /* if y /* if y is larger than max, assign y to max */ is larger than max, assign y to max */ is larger than max, assign y to max */
32 max = y; max = y; max = y;
33 } } /* end if */ /* end if */
34
35 if ( z > max ) { /* if z is larger than max, assign z to max */ /* if z is larger than max, assign z to max */
36 max = z; max = z; max = z;
37 } } /* end if */ /* end if */
38
39 return max; /* max is largest value */ /* max is largest value */
40
41 } /* end function maximum */ /* end function maximum */
Trang 18Bi ế n toàn c ụ c và bi ế n đị a ph ươ ng
Bi ế n toàn c ụ c: là nh ữ ng bi ế n đượ c s ử d ụ ng ở m ọ i n ơ i trong ch ươ ng trình.
• C ấ p phát b ộ nh ớ cho bi ế n toàn c ụ c: c ấ p phát b ộ nh ớ t ĩ nh
Bi ế n đị a ph ươ ng: là bi ế n ch ỉ có giá tr ị trong th ờ i gian hàm ho ạ t độ ng, sau khi k ế t thúc hàm thì nh ữ ng bi ế n khai báo bên trong hàm và các tham s ố truy ề n cho hàm
Trang 191 /* Fig 5.12: fig05_12.c/* Fig 5.12: fig05_12.c
2 A scoping example */A scoping example */
3 #include <stdio.h> <stdio.h>
4
5 void useLocal( void ); /* function prototype */ /* function prototype */ 6 void useStaticLocal( void ); /* function prototype */ /* function prototype */ 7 void useGlobal( void ); /* function prototype *//* function prototype */on prototype */ 8
9 int x = 1; /* global variable *//* global variable */ 10 11 /* function main begins program execution *//* function main begins program execution */ 12 int main() main() 13 {{
14 int x = 5; /* local variable to main *//* local variable to main */ 15 16 printf("local x in outer scope of main is %d"local x in outer scope of main is %d\\\nnn"", x );, x ); 17 18 { { /* start new scope *//* start new scope */
19 int x = 7; /* local variable to new scope *//* local variable to new scope */
20
21 printf( printf( "local"local x in inner scope of main is %d x in inner scope of main is %d x in inner scope of main is %d\\\n"n", x );, x );
22 } } /* end new scope *//* end new scope */
23 24 printf( "local x in outer scope of main is %d"local x in outer scope of main is %d\\\n"n", x );, x ); 25 26 useLocal(); /* useLocal has automatic local x */ /* useLocal has automatic local x */ 27 useStaticLocal(); /* useStaticLocal has static local x */ /* useStaticLocal has static local x */ 28 useGlobal(); /* useGlobal uses global x */ /* useGlobal uses global x */ 29 useLocal(); /* useLocal reinitializes automatic local x *//* useLocal reinitializes automatic local x */x */ 30 useStaticLocal(); /* static local x retains its prior value */ /* static local x retains its prior value */ 31 useGlobal(); /* global x also retains its value */ /* global x also retains its value */ 32 33 printf( "local x in main is %d"local x in main is %d\\\n"n", x );, x ); 34 35 return ; /* indicates successful termination *//* indicates successful termination */ion */ 36 37 } /* end main *//* end main */ 38 39 /* useLocal reinitializes local variable x during each call */ /* useLocal reinitializes local variable x during each call */ 40 void useLocal( void ) ) 41 { {
42 int x = 25; /* initialized each time useLocal is called */ /* initialized each time useLocal is called */ 43 44 printf( ""\\\nlocal x in nlocal x in nlocal x in a is %d after entering aa is %d after entering aa is %d after entering a\\\n"n", x );, x ); 45 x++; x++;
46 printf( "local x in a is %d before exiting a"local x in a is %d before exiting a\\\n"n", x );, x );
47 } /* end function useLocal *//* end function useLocal */
48
Trang 2049 /* useStaticLocal initializes static local variable x only the first time
50 the function is called; value of x is saved between calls to thisthe function is called; value of x is saved between calls to this
59 printf( "local static x is %d on exiting b"local static x is %d on exiting b\\\n"n", x );, x );
60 }} /* end function useStaticLocal *//* end function useStaticLocal */
61
62 /* function useGlobal modifies global variable x during each call *//* function useGlobal modifies global variable x during each call */
63 void useGlobal( void ))
64 {{
65 printf( ""\\\nglobal x is %d on entering cnglobal x is %d on entering cnglobal x is %d on entering c\\\n"n", x );, x );
66 x *= 10;;
67 printf( "global x"global x is %d on exiting c is %d on exiting c is %d on exiting c\\\n"n", x );, x );
68 } /* end function useGlobal *//* end function useGlobal */
local x in outer scope of main is 5
local x in inner scope of main is 7
local x in outer scope of main is 5
local x in a is 25 after entering a
local x in a is 26 before exiting a
local static x is 50 on entering b
local static x is 51 on exiting b
global x is 1 on entering c
global x is 10 on exiting c
local x in a is 25 after entering a
local x in a is 26 before exiting a
local static x is 51 on entering b
local static x is 52 on exiting b
global x is 10 on entering c
global x is 100 on exiting c
local x in main is 5
Trang 21• S ử d ụ ng toán t ử & để truy ề n đị a ch ỉ c ủ a bi ế n
• Cho phép chúng ta thay đổ i m ộ t v ị trí th ự c s ự trên b ộ nh ớ
• Các array thì không s ử d ụ ng & b ở i vì tên array là con tr ỏ
S ử d ụ ng * để thay đổ i giá tr ị c ủ a tham bi ế n trong hàm
void Intdouble( int *number ) {
*number = 2 * ( *number );
}
1 /* Fig 7.6: fig07_06.c /* Fig 7.6: fig07_06.c
2 Cube a variable using callCube a variable using call -bybyby -value */value */value */
3 #include <stdio.h> <stdio.h>
13 /* pass number by value to cubeByValue */ /* pass number by value to cubeByValue */
14 number = cubeByValue( number );number = cubeByValue( number );number = cubeByValue( number );
22 /* calculate and return cube of integer argument *//* calculate and return cube of integer argument */
23 int cubeByValue( int n ) n )
Trang 221 /* Fig 7.7: fig07_07.c/* Fig 7.7: fig07_07.c
2 Cube a variable using callCube a variable using call -bybyby -reference with a pointer argument */reference with a pointer argument */reference with a pointer argument */
3
4 #include <stdio.h> <stdio.h> 5
6 void cubeByReference( int *nPtr ); /* prototype *//* prototype */ 7
8 int main() main() 9 {{
10 int number = 5; /* initialize number *//* initialize number */ 11 12 printf( "The original value of number is %d", number );, number ); 13
14 /* pass address of number to cubeByReference */ /* pass address of number to cubeByReference */ 15 cubeByReference( &number );cubeByReference( &number );cubeByReference( &number ); 16 17 printf( ""\\\nThe new value of number is %dnThe new value of number is %dnThe new value of number is %d\\\n"n", number );, number ); 18 19 return ; /* indicates successful termination *//* indicates successful termination */ 20 21 } /* end main *//* end main */ 22 23 /* calculate cube of *nPtr; modifies variable number in main *//* calculate cube of *nPtr; modifies variable number in main */ 24 void cubeByReference( int *nPtr ) *nPtr )
25 {{
26 *nPtr = *nPtr * *nPtr * *nPtr; *nPtr = *nPtr * *nPtr * *nPtr; /* cube *nPtr *//* cube *nPtr */
27 } /* end function cubeByReference *//* end function cubeByReference */
Gọi hàm và sử dụng truyền biến con trỏ
*nPtr được sử dụng (*nPtr là số nguyên)
Truyền tham biến sử dụng pointer, trỏ tới số integer.
The original value of number is 5
The new value of number is 125
const
• bi ế n không đượ c phép thay đổ i
• S ử d ụ ng const n ế u hàm không c ầ n thay đổ i giá tr ị c ủ a bi ế n
• C ố tình thay đổ i bi ế n const s ẽ gây l ỗ i
const pointers
• Tr ỏ t ớ i vùng nh ớ c ố đị nh
• Ph ả i đượ c kh ở i t ạ o khi đị nh ngh ĩ a
• int *const myPtr = &x;
– Ki ể u int *const – con tr ỏ h ằ ng tr ỏ đế n vùng nh ớ ki ể u int
• const int *myPtr = &x;
– Con tr ỏ thông th ườ ng tr ỏ đế n const int
• const int *const Ptr = &x;
– con tr ỏ const tr ỏ đế n m ộ t vùng nh ớ const int
– x c ó th ể thay đổ i, nh ư ng *Ptr th ì không.