Ngôn ngữ lập trình Chương VIII: Lập trình hàm 89
• Các hàm điều khiển
- (IF E
1
E
2
E
3
) nhận vào 3 biểu thức E
1
, E
2
và E
3
. Nếu E
1
khác NIL thì hàm
trả về giá trị của E
2
ngược lại trả về giá trị của E
3
- (IF E
1
E
2
) tương đương (IF E
1
n
E
n
)
[(T E
n+1
)]
)
Nếu ĐK
1
khác NIL thì trả về kết quả là giá trị của E
1
, ngược lại sẽ xét ĐK
2
.
Nếu ĐK
2
khác NIL thì trả về kết quả là giá trị của E
2
, ngược lại sẽ xét ĐK
3Nếu ĐK
n
khác NIL thì trả về kết quả là giá trị của E
n
, ngược lại sẽ trả về NIL
hoặc trả về kết quả là giá trị của E
n+1
E
n
) nhận vào n biểu thức E
1
, E
2
, E
n
. Hàm định trị các
biểu thức E
1
, E
2
, E
n
từ trái sang phải và trả về kết quả là giá trị của biểu
thức E1.
Hàm do người lập trình định nghĩa
Cú pháp định nghĩa hàm là:
(defun <tên hàm> <danh sách các tham số hình thức>
<biểu thức>
)
Ví dụ 1: Ðịnh nghĩa hàm lấy bình phương của số a
(defun binh_phuong (a)
(* a a)
)
Sau khi nạp hàm này cho LISP, ta có thể sử dụng như các hàm đã được định nghĩa
trước.
>(binh_phuong 5)
= 25
-
t
r
a
c
k
.
c
o
m
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
• Lời gọi đệ quy phải bao hàm yếu tố dẫn đến các trường hợp “dừng”.
Ví dụ 1: Viết hàm tính n giai thừa
Công thức đệ quy tính n giai thừ
a là
⎩
⎨
⎧
−
=
=
1)!(n*n
0nneu 1
n!
Hàm (giai_thua N) viết bằng ngôn ngữ LISP:
(defun giai_thua (n)
(if (= n 0) 1 ; trường hợp “dừng”
(* n (giai_thua (1- n))); n-1 là yếu tố dẫn đến trường hợp dừng
) ; If
)
Ví dụ 2: Viết hàm DIV chia a cho b lấy phần nguyên, viết bằng đệ quy.
Công thức đệ quy:
⎩
⎨
⎧
−+
<
=
b DIV b)(a1
(T (phan_tu (1- i) (cdr L)))
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
.
Ngôn ngữ lập trình Chương VIII: Lập trình hàm 91
) ; cond
)
Trong chương trình trên, (null L) là trường hợp “dừng” thứ nhất; (= i 1) là trường hợp
“dừng” thứ hai; (cdr L) là yếu tố dẫn đến trường hợp “dừng” thứ nhất và (1- i) yếu tố
dẫn đến trường hợp “dừng” thứ hai.
8.3.5 Các hàm nhập xuất
• (LOAD <Tên tập tin>)
Nạp một tập tin vào cho LISP và trả về T nếu việc nạp thành công, ngược lại trả về
NIL. Tên tập tin là một chu
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
u
-
t
r
a
c
k
.
c
o
m
.
Ngôn ngữ lập trình Chương VIII: Lập trình hàm 92
= 6
Biến cục bộ
Biến cục bộ (local variables) là biến mà phạm vi của nó chỉ nằm trong hàm mà nó
được tạo ra. Biến cục bộ sẽ tự động giải phóng hàm tạo ra nó kết thúc.
• (LET ( (var1 E1) (var2 E2) (vark Ek)) Ek+1 En)
Ta thấy hàm này có 2 phần: phần gán trị cho các biến và phần định trị các biểu thức.
Gán trị của biểu thức E
i
cho biến cục bộ var
i
tương ứng và thực hiện (PROGN E
k+1
E
phím và gọi hàm (ptb2 a b c) để thực hiện việc giải phương trình. Có hai phương
pháp để viết hàm này.
Phương pháp 1: dùng các biến toàn cục a, b, c
(defun giai_ptb2 ()
(progn
(print “Chương trình giải phương trình bậc hai“)
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
.
Ngôn ngữ lập trình Chương VIII: Lập trình hàm 93
(princ “Nhập hệ số a: “) (setq a (read))
(princ “Nhập hệ số b: “) (setq b (read))
(princ “Nhập hệ số c: “) (setq c (read))
(ptb2 a b c)
)
Do XLISP không có công cụ để soạn thảo chương trình nên ta có thể sử dụng Notepad
để soạn thảo tập tin chương trình.
Trong một tập tin chương trình ta có thể định nghĩa nhiều hàm.
Lưu tập tin chương trình có tên theo quy định của DOS (8.3) với phần mở rộng .LSP
và để trong cặp dấu nháy kép.
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
.