Tải bản đầy đủ (.pdf) (41 trang)

KỸ THUẬT PHÁT TRIỂN CHƯƠNG TRÌNH

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (373.47 KB, 41 trang )

KỸ THUẬT LẬP TRÌNH

KỸ THUẬT PHÁT TRIỂN CHƯƠNG TRÌNH
NỘI DUNG
1.

Hàm và Thủ tục

2.

Phát triển chương trình bằng phương pháp tinh
chỉnh dần từng bước.

3.

Định nghĩa và sử dụng hàm trong ngôn ngữ C

4.

Hàm/thủ tục đệ quy

0

1. HÀM VÀ THỦ TỤC
Khái niệm hàm, thủ tục
Đối số và tham biến
Truyền dữ liệu cho hàm/thủ tục

1



1. HÀM VÀ THỦ TỤC
Thủ tục (Procedures) và Hàm (functions) thể hiện
hai dạng của chương trình con (subprograms)
Cho phép lặp đi lặp lại một đoạn code hoặc một tính
tốn nhất định.
Hà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.
2

Đố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);
begin
sum := num1 + num2;
end;

Phạm vi của các biến:
• biến cục bộ trong chương trình con
• biến tồn cục
3


Và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)

4

Truy n theo tham chi u: vị trí trong bộ nhớ (địa chỉ)
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ó.
Truy n theo trị: giá trị của đối số được truy n cho
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.

5


Ưu điểm của các hàm/thủ tục
• Chia tách và kiểm sốt (“Chia để trị”)
– Khả năng quản lý chương trình và phát triển
• Khả năng sử dụng lại các hàm/thủ tục
– Sử dụng các hàm/thủ tục đã có sẵn, chạy ổn định để xây
dựng các khối chương trình mới

– Tính trừu tượng: che dấu các chi tiết bên trong hàm
– Tránh phải lặp lại một đoạn chương trình (code)

6

2. Các bước thực hiện phát triển chương trình
Hiểu rõ yêu cầu bài tốn: có thể diễn đạt lại bài tốn
bằng ngơn ngữ đặc tả, các kí hiệu tố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?

7


Các bước thực hiện phát triển chương trình
Hình thành ý tưởng về cách giải bài tốn
• Chương trình có thể được phân tách thành các q 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?

8


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 tốn


Viết chương trình chính (việc viết các mơ đun như thế nào sẽ
hồ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.
9


PHƯƠNG PHÁP TINH CHỈNH TỪ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 hố bài tốn
– Chia bài tố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 tố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 tố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ỏ.

10

PHƯƠNG PHÁP TINH CHỈNH TỪ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.
? Làm cái gì?

• 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ể.
? Làm như thế nào?
11


PHƯƠNG PHÁP TINH CHỈNH TỪNG BƯỚC
Bài tốn: Tìm các số có 2 chữ số mà khi đảo trật tự của
hai số đó sẽ được một số nguyên tố cùng nhau với số
đã cho.
Bước 0:

12


PHƯƠNG PHÁP TINH CHỈNH TỪNG BƯỚC
Bước 1.
• Dữ liệu vào:
• Dữ liệu ra: Số ngun dương có 2 chữ số, là nguyên tố cùng
nhau với số đảo của nó.
• Ý tưởng thuật tố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.

13


PHƯƠNG PHÁP TINH CHỈNH TỪNG BƯỚC
Bước 2.
Function Tim
• Vào:
• Ra: mảng S và n
• Biến nguyên n lưu số lượng các số tìm được
1.

n := 0;

2.

Với mỗi số x trong [10..99],

Kiểm tra xem x có số đảo là nguyên tố cùng nhau hay khơng, nếu
đúng thì đưa x vào mảng S và n := n + 1;


14

PHƯƠNG PHÁP TINH CHỈNH TỪNG BƯỚC
Bước 3. Hàm tìm số đảo
• Function Sodao
– Vào: x là số nguyên dương
– Ra: Số đảo của x
– Ý tưởng: Từ x, lần lượt lấy các chữ số từ bên phải của x để tạo số
y từ trái sang phải.
1. Khởi đầu y:=0
2. Với x> 0, lặp quá trình lấy chữ số hàng đơn vị của x bổ sung
vào bên phải y
Tính y := y * 10 + (x mod 10);
x := x div 10
3. Trả về số đảo là y
15


PHƯƠNG PHÁP TINH CHỈNH TỪ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ố ngun 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;

16

PHƯƠNG PHÁP TINH CHỈNH TỪ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;

17


PHƯƠNG PHÁP TINH CHỈNH TỪNG BƯỚC
Bước 6. Tìm UCLN của hai số ngun dương: Thuật tốn Euclid
• Function UCLN
• Vào: m, n nguyên (m >= n>= 0)
• Ra: UCLN là ước chung lớn nhất của m,n



Biến r là số nguyên dương
1. Nếu m>n thì chuyển sang bước 2, ngược lại, hoán chuyển giá trị của m và
n.
2. Nếu n bằng 0 thì trả về UCLN = m và kết thúc thuật tốn
Ngược lại, chuyển sang bước 4.
3. Tính r là phần dư của phép chia m cho n.
4. Gán giá trị của n cho m và của r cho n. Quay lại bước 2.

18

PHƯƠNG PHÁP TINH CHỈNH TỪNG BƯỚC
Bước 7.
• Hàm tìm UCLN
Function UCLN(a,b: integer) : integer;
Var r: integer;
Begin
If m < n then
Begin r := m; m := n; n := r; end;
While n > 0 do
Begin
r := m MOD n;
m := n; n := r;
end;
return m;
End;
19



PHƯƠNG PHÁP TINH CHỈNH TỪNG BƯỚC
• Function NTCN (x: integer, y: integer): Boolean;
Begin
If UCLN(x, y) = 1 then return True
Else return False;
End;

20

PHƯƠNG PHÁP TINH CHỈNH TỪNG BƯỚC
• Function Sodao(x: integer): integer;
Var y: integer;
Begin
y := 0;
while x > 0 do
begin
y := 10*y + (x MOD 10);
x := x DIV 10;
end;
return y;
End;
21


• Function SodaoNTCN (x: integer): Boolean;
Begin
If

NTCN(x, Sodao(x)) then return True


Else return False;
End;

22

PHƯƠNG PHÁP TINH CHỈNH TỪNG BƯỚC
• Function Tim(Var s: array[1..80] of integer):integer;
Var x, n: integer;
Begin
n := 0;
for x := 10 to 99 do
if SodaoNTCN(x) then
begin

n := n + 1;
s[d] := x;

end;
return n;
end;
23


Bài tập 4.1
Bước 7. Cài đặt chương trình theo thuật tốn
(Bài tập 5.1)

24

Bài tập 4.2

Phát triển chương trình thực hiện các thao tác trên
phân số:
• Nhập vào phân số
• Hiển thị phân số
• Cộng, trừ hai phân số
• Nhân, chia hai phân số

25


KỸ THUẬT LẬP TRÌNH

KỸ THUẬT PHÁT TRIỂN CHƯƠNG TRÌNH
NỘI DUNG
1.

Hàm và Thủ tục

2.

Phát triển chương trình bằng phương pháp tinh
chỉnh dần từng bước.

3.

Định nghĩa và sử dụng hàm trong ngôn ngữ C

4.

Hàm đệ quy


26

3. Định nghĩa và sử dụng hàm trong C
Định nghĩa hàm
Phạm vi của biến
Truyền tham số

27


3. Định nghĩa và sử dụng hà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 đó.
• 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ả
28

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ề q trình thực hiện

main

worker1

worker4

worker2

worker3

worker5
29


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ố.

30

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;

31


1 /* Fig. 5.4: fig05_04.c
2

Finding the maximum of three integers */

3 #include <stdio.h>

fig05_04.c (Part 1 of 2)

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",
"%d%d%d", &number1, &number2, &number3 );

16
17
18
19


/* number1, number2 and number3 are arguments
to the maximum function call */
printf( "Maximum is: %d\
%d\n",
n", maximum( number1, number2, number3 ) );

20
21

return 0; /* indicates successful termination */

22
23 } /* end main */
24

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 */

Enter three
Maximum is:
Enter three
Maximum is:
Enter three
Maximum is:

integers: 22 85 17
85
integers: 85 22 17
85
integers: 22 17 85
85


Phạm vi của biế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 tồ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.

34

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, ln đượ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.

35


1

/* Fig. 5.12: fig05_12.c
A scoping example */

2
3

#include <stdio.h>

4
5

void useLocal( void );

/* function prototype */

6

void useStaticLocal( void ); /* function prototype */


7

void useGlobal( void );

/* function
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
printf("local x in outer scope of main is %d\
%d\n", x );

17
18


{ /* start new scope */
int x = 7; /* local variable to new scope */

19
20

printf( "local x in inner scope of main is %d\
%d\n",
n", x );

21
22

} /* end new scope */

23
24

printf( "local x in outer scope of main is %d\
%d\n",
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\

%d\n",
n", x );

34
35

return 0; /* indicates successful termination
termination */

36
37 } /* end main */
38
39 /* useLocal reinitializes local variable x during each call */
40 void useLocal( void )
41 {
42

int x = 25;
25;

/* initialized each time useLocal is called */

43
44

printf( "\nlocal x in a is %d after entering a\
a\n",
n", x );

45


x++;

46

printf( "local x in a is %d before exiting a\
a\n",
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
time useStaticLocal is called */

55


static int x = 50;
50;

56
57

printf( "\nlocal static x is %d on entering b\
b\n",
n", x );

58

x++;

59

printf( "local static x is %d on exiting b\
b\n",
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\
c\n",

n", x );

66

x *= 10;
10;

67

printf( "global x is %d on exiting c\
c\n",
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



×