
0
K
KỸ
ỸTHU
THUẬ
ẬT L
T LẬ
ẬP TRÌNH
P TRÌNH
KỸTHUẬT PHÁT TRIỂN CHƯƠNG TRÌNH
NỘI DUNG
Hàm và Thủtục
Phát triển chương trình bằng phương pháp tinh
chỉnh dần từng bước.
Định nghĩa và sửdụng hàm trong ngôn ngữC
Hàm đệ quy
1
Đ
Đị
ịnh ngh
nh nghĩ
ĩa v
a và
às
sử
ửd
dụ
ụng h
ng hà
àm trong C
m trong C
Hàm trong C
•Các Modules trong C
•Một chương trình bao gồm các hàm do người sửdụng tạo dựng và các
hàm thư viện
–Thư viện chuẩn C có một lượng lớn các hàm và có thể được mởrộng thêm
–Vídụ: khi dùng #include <stdio.h>, ta có thểgọi hàm scanf,…
Lời gọi hàm
•Xuất phát từ chương trình chính (main) hoặc từ1 hàm nào đó.
•Yêu cầu gọi các hàm:
–Cung cấp tên hàm và các đối số
–Hàm thực hiện các hành động hoặc các thao tác
–Hàm trảlại kết quả
2
Ngữnghĩa lời gọi hàm:
–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
worker1 worker2 worker3
worker4 worker5
3
Cú pháp định nghĩa hàm
return-value-type function-name( parameter-list )
{
khai báo dữliệu và các lệnh
}
•Function-name: Tên hàm
•Return-value-type: kiểu dữliệu của kết quảtrảvề(mặc
định làint)
–void – hàm không trảlại kết quả
•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ố.

4
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
•Kiểm soát kết quảtrảvềbằng lệnh return
–Nếu không có kết quảtrảvề
–return;
–hoặc gặp dấu ngoặc móc } để kết thúc
–Nếu có kết quảtrảvề
–return biểu_thức;
fig05_04.c (Part 1 of 2)
fig05_04.c (Part 1 of 2)
1 /* Fig. 5.4: fig05_04.c
2 Finding the maximum of three integers */
3 #include <stdio.h>
4
5 int maximum( int x, int y, int z ); /* function prototype */
6
7 /* function main begins program execution */
8 int main()
9 {
10 int number1; /* first integer */
11 int number2; /* second integer */
12 int number3; /* third integer */
13
14 printf( "Enter three integers: " );
15 scanf( "%d%d%d", &number1, &number2, &number3 );
16
17 /* number1, number2 and number3 are arguments
18 to the maximum function call */
19 printf( "Maximum is: %d\n", maximum( number1, number2, number3 ) );
20
21 return 0; /* indicates successful termination */
22
23 } /* end main */
24
Enter three integers: 22 85 17
Maximum is: 85
Enter three integers: 85 22 17
Maximum is: 85
Enter three integers: 22 17 85
Maximum is: 85
25 /* Function maximum definition */
26 /* x, y and z are parameters */
27 int maximum( int x, int y, int z )
28 {
29 int max = x; /* assume x is largest */
30
31 if ( y > max ) { /* if y is larger than max, assign y to max */
32 max = y;
33 } /* end if */
34
35 if ( z > max ) { /* if z is larger than max, assign z to max */
36 max = z;
37 } /* end if */
38
39 return max; /* max is largest value */
40
41 } /* end function maximum */
7
Ph
Phạ
ạm vi c
m vi củ
ủa bi
a biế
ến
n
Biế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 sẽ
không tồn tại nữa.

8
Cấp phát bộnhớcho biến địa phương: cấp phát tự
động, cần đến đâu cấp phát đến đó, mỗi lần gọi hàm là
một lần cấp phát.
Biến địa phương tĩnh static: Yêu cầu cấp phát các biến
của hàm ởvịtrí cố định, tĩnh tại, luôn được dùng cho
hàm. Vì vậy, giá trịcủa các biến này có thểtồn tại ngay
cảkhi hàm đã kết thúc hoạt động của hàm.
1 /* Fig. 5.12: fig05_12.c
2 A scoping example */
3 #include <stdio.h>
4
5 void useLocal( void ); /* function prototype */
6 void useStaticLocal( void ); /* function prototype */
7 void useGlobal( void ); /* function prototype */
8
9 int x = 1; /* global variable */
10
11 /* function main begins program execution */
12 int main()
13 {
14 int x = 5; /* local variable to main */
15
16 printf("local x in outer scope of main is %d\n", x );
17
18 { /* start new scope */
19 int x = 7; /* local variable to new scope */
20
21 printf( "local x in inner scope of main is %d\n", x );
22 } /* end new scope */
23
24 printf( "local x in outer scope of main is %d\n", x );
25
26 useLocal(); /* useLocal has automatic local x */
27 useStaticLocal(); /* useStaticLocal has static local x */
28 useGlobal(); /* useGlobal uses global x */
29 useLocal(); /* useLocal reinitializes automatic local x */
30 useStaticLocal(); /* static local x retains its prior value */
31 useGlobal(); /* global x also retains its value */
32
33 printf( "local x in main is %d\n", x );
34
35 return 0; /* indicates successful termination */
36
37 } /* end main */
38
39 /* useLocal reinitializes local variable x during each call */
40 void useLocal( void )
41 {
42 int x = 25; /* initialized each time useLocal is called */
43
44 printf( "\nlocal x in a is %d after entering a\n", x );
45 x++;
46 printf( "local x in a is %d before exiting a\n", x );
47 } /* end function useLocal */
48
49 /* useStaticLocal initializes static local variable x only the first time
50 the function is called; value of x is saved between calls to this
51 function */
52 void useStaticLocal( void )
53 {
54 /* initialized only first time useStaticLocal is called */
55 static int x = 50;
56
57 printf( "\nlocal static x is %d on entering b\n", x );
58 x++;
59 printf( "local static x is %d on exiting b\n", x );
60 } /* end function useStaticLocal */
61
62 /* function useGlobal modifies global variable x during each call */
63 void useGlobal( void )
64 {
65 printf( "\nglobal x is %d on entering c\n", x );
66 x *= 10;
67 printf( "global x is %d on exiting c\n", x );
68 } /* 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
13
Truy
Truyề
ền m
n mả
ảng
ng cho
cho h
hà
àm
m
Để truyền mộtmảng cho hàm, chỉra tên củamảng,
không sửdụng cặp “[]”
int myArray[ 24 ];
myFunction( myArray, 24 );
–Kích thước của mảng cần được truyền qua hàm
•Mảng được truyền thông qua lời gọi tham chiếu
•Tên củamảng là địa chỉphần tử đầu tiên
•Hàm biết được nơi lưu trữmảng
–Thực hiện thay đổi tại vịtrí chứa mảng trong bộnhớ
Truyền các phần tửmảng
•Truyền thông qua lời gọi bởi giá trị(truyền theo trị)
•Truyền tên mảng cùng chỉsốtới hàm (ví dụ:myarray[3])
14
Truy
Truyề
ền m
n mả
ảng cho h
ng cho hà
àm
m
Khai báo nguyên mẫu hàm (function prototype) để
truyền mảng cho hàm
void modifyArray( int b[], int arraySize );
•Có thểbỏqua tên mảng trong khai báo nguyên mẫu hàm
–int b[] có thể được viếtint[]
–int arraySize có thể được viết đơn giản là int
• Tên của array chính là &array[ 0 ] (địa chỉcủa phần tử
đầu tiên trong mảng) do vậy khi truyền mảng (tham
biến) thông qua gọi hàm không cần sửdụng dấu &
Ví dụgọi hàm với khai báo nguyên mẫu trên:
int a[10], n = 10;
modifyArray( a, n); // không sửdụng &a
array = 0012FF78
&array[0] = 0012FF78
&array = 0012FF78
1 /* Fig. 6.12: fig06_12.c
2 The name of an array is the same as &array[ 0 ] */
3 #include <stdio.h>
4
5 /* function main begins program execution */
6 int main()
7 {
8 char array[ 5 ]; /* define an array of size 5 */
9
10 printf( " array = %p\n&array[0] = %p\n"
11 " &array = %p\n",
12 array, &array[ 0 ], &array );
13
14 return 0; /* indicates successful termination */
15
16 } /* end main */
Ví dụ: Tên của array chính là &array[ 0 ] (địa chỉcủa phần tử
đầu tiên trong mảng)

1 /* Fig. 6.13: fig06_13.c
2 Passing arrays and individual array elements to functions */
3 #include <stdio.h>
4 #define SIZE 5
5
6 /* function prototypes */
7 void modifyArray( int b[], int size );
8 void modifyElement( int e );
9
10 /* function main begins program execution */
11 int main()
12 {
13 int a[ SIZE ] = { 0, 1, 2, 3, 4 }; /* initialize a */
14 int i; /* counter */
15
16 printf( "Effects of passing entire array by reference:\n\nThe "
17 "values of the original array are:\n" );
18
19 /* output original array */
20 for ( i = 0; i < SIZE; i++ ) {
21 printf( "%3d", a[ i ] );
22 } /* end for */
23
24 printf( "\n" );
25
Ví dụ:
-Truyền mảng b và thay đổi các phần tửcủa mảng khi gọi hàm (tham chiếu)
-Truyền phần tửcủa mảng qua hàm (tham trị)
fig06_13.c (Part 2 of 3)
fig06_13.c (Part 2 of 3)
26 /* pass array a to modifyArray by reference */
27 modifyArray( a, SIZE );
28
29 printf( "The values of the modified array are:\n" );
30
31 /* output modified array */
32 for ( i = 0; i < SIZE; i++ ) {
33 printf( "%3d", a[ i ] );
34 } /* end for */
35
36 /* output value of a[ 3 ] */
37 printf( "\n\n\nEffects of passing array element "
38 "by value:\n\nThe value of a[3] is %d\n", a[ 3 ] );
39
40 modifyElement( a[ 3 ] ); /* pass array element a[ 3 ] by value */
41
42 /* output value of a[ 3 ] */
43 printf( "The value of a[ 3 ] is %d\n", a[ 3 ] );
44
45 return 0; /* indicates successful termination */
46
47 } /* end main */
48
49 /* in function modifyArray, "b" points to the original array "a"
50 in memory */
51 void modifyArray( int b[], int size )
52 {
53 int j; /* counter */
54
55 /* multiply each array element by 2 */
56 for ( j = 0; j < size; j++ ) {
57 b[ j ] *= 2;
58 } /* end for */
59
60 } /* end function modifyArray */
61
62 /* in function modifyElement, "e" is a local copy of array element
63 a[ 3 ] passed from main */
64 void modifyElement( int e )
65 {
66 /* multiply parameter by 2 */
67 printf( "Value in modifyElement is %d\n", e *= 2 );
68 } /* end function modifyElement */
-Mảng b sẽ thay đổi giá trịsau khi gọi thực hiện hàm modifyArray
-Phần tử a[3] không thay đổi khi truyền cho biến e khi gọi hàm modifyElement
Effects of passing entire array by reference:
The values of the original array are:
0 1 2 3 4
The values of the modified array are:
0 2 4 6 8
Effects of passing array element by value:
The value of a[3] is 6
Value in modifyElement is 12
The value of a[ 3 ] is 6

