Chương 3Hàm Function Lập trình đơn thể Mỗi module có dữ liệu riêng độc lập với module khác Main ProgramAlso a module Data Module1 + Procedure1 Module2 + Procedure2 Procedure3 Lập trình
Trang 1Chương 3
Hàm (Function)
Lập trình đơn thể
Mỗi module có dữ liệu riêng độc lập với module khác
Main Program(Also a module)
Data
Module1 +
Procedure1
Module2 +
Procedure2 Procedure3
Lập trình đơn thể (tt)
“Chia để trị”: phân rã bài toán thành các bài
toán con cho đến khi “bài toán con” nhận
được “đủ nhỏ”.
Mỗi “bài toán con” được giải quyết bằng một
module, độc lập với các module khác.
Trong C mỗi module chính là 1 hàm.
Phân tích: top down.
Thiết kế: bottom up.
Lập trình đơn thể (tt)
Bài toán ban đầu
module1 module2
module11 module12
modulek
Ưu điểm của phương pháp lập trình đơn thể?
Trang 2Cú pháp của hàm
<type_function> f_name(parameters)
{
/* các khai báo cục bộ */
/* các câu lệnh */
[return <Exp>;] /* có thể có hoặc không*/
}
Cú pháp của hàm (tt)
Ví dụ 1:
void chao() {
printf(“\nxin chao”);
}
Ví dụ 2:
int tong(int n) {
int i,t=0;
for(i=1;i<=n;++i)t=t+i;
return t;
}
Cú pháp của hàm (tt)
Ví dụ 3:
int ucln(int x, int y)
{
while(x*y)
if(x>y)x=x%y;
else y=y%x;
return (x+y);
}
Lời gọi hàm
Ví dụ:
chao();
kq1=tong(12); kq2=tong(kq1);
kq3=ucln(kq1,15);
Có thể không có
<tên_hàm>([danh sách tham số thực])
Trang 3Các bước thực hiện lời gọi hàm
Giả sử int a, b, kq; là các biến toàn cục và
a=6; b=8;
Xét lời gọi hàm: kq = ucln(a,b); (*)
Khi đó các bước sau đây được thực hiện:
B1: Lưu địa chỉ của câu lệnh kế tiếp sau lời gọi
hàm (*) làm địa chỉ quay về sau khi kết thúc
hàm.
B2: Cấp phát vùng nhớ cho các tham số và các
biến cục bộ.
Các bước thực hiện lời gọi hàm (tt)
6 8
a b Data Segment
Stack Segment
kq
(bước 2)
Các bước thực hiện lời gọi hàm (tt)
B3: Sao chép giá trị của tham số thực
cho tham số hình thức
6 8
a b
kq
Các bước thực hiện lời gọi hàm (tt)
B4: Thực hiện các câu lệnh trong thân hàm
6 8
a b
kq
Trang 4Các bước thực hiện lời gọi hàm (tt)
B5: Trả lại kết quả bởi lệnh return
6 8
a b
kq 2
Các bước thực hiện lời gọi hàm (tt)
B6: Giải phóng các vùng nhớ đã cấp phát
ở B2, lấy địa chỉ đã lưu ở B1 thực hiện tiếp chương trình
6 8
a b
2
kq
Cơ chế truyền tham trị
Giá trị của tham số thực được sao chép
cho tham số hình thức
Tham số thực luôn luôn được bảo toàn
Như ở ví dụ trên giá trị của a và b sau
khi thực hiện (*) vẫn không thay đổi
(trong khi x và y đã thay đổi)
Con trỏ (pointer) và cơ chế truyền địa chỉ
Định nghĩa: con trỏ là biến dùng để chứa địa chỉ của biến khác
Khai báo:
Ví dụ:
<kiểu_ct> *<tên_ct>;
int *p;
Khai báo con trỏ kiểu nguyên int
Trang 5Cách sử dụng con trỏ
Dùng tên con trỏ, giống như một biến bình thường.
Dùng dạng khai báo *<tên_ct>, cho kết quả là dữ liệu
mà con trỏ đang “trỏ” tới.
Có thể dùng các phép toán đối với con trỏ (phần sau)
Ví dụ:
int x=13, *p;
p=&x; //p trỏ tới x.
printf(“\n%d duoc luu tai dia chi %p”,x,p);
printf(“\np dang tro toi du lieu la %d”,*p);
Cách sử dụng con trỏ (tt)
13
&x
x=*p
p
Truyền địa chỉ
Trong những trường hợp cần làm cho
tham số thực bị thay đổi thì phương
pháp truyền tham trị không đáp ứng
được Vậy cần có một phương pháp
khác, đó là:
Tham số hình thức nhận địa chỉ của
tham số thực (nên tham số hình thức
phải là một con trỏ)
Truyền địa chỉ
Ví dụ:
void hoan_vi(int *x, int *y) {
int t=*x;
*x=*y;
*y=t;
} Giả sử int a,b là các biến toàn cục và a=5; b=7; Xét lời gọi hàm: hoan_vi(&a,&b); khi đó:
Trang 6Truyền địa chỉ (tt)
&a &b
x y
6
t
Hàm đệ quy
Đối tượng đệ quy: là đối tượng được xây dựng thông qua chính nó (đối tượng có thể là: bài toán, hàm, kiểu dữ liệu )
Ví dụ: xét bài toán P(n) = 1+2+ +n Bài toán này có lời giải (đệ quy như sau):
>
+
−
=
=
) 0 ( )
1 ( ) (
0 ) 0 (
n n n
p n p p
Hàm đệ quy (tt)
Hàm đệ quy là hàm mà trong thân của
nó chứa lời gọi đến chính nó
Ví dụ 1: hàm tính p(n)
int p(int n)
{
if(n==0)return 0;
else return p(n-1)+n;
}
Phần neo
Phần đệ quy
Hàm đệ quy (tt)
Ví dụ 2: tính F(n) biết
− +
−
=
=
=
) 2 ( ) 1 ( ) (
1 ) 2 ( ) 1 (
n f n
f n f
f f
với n>2
int F(int n) {
if(n==1||n==2) return 1;
else return F(n-1)+F(n-2);
}
Trang 7Phân tích hàm đệ quy
Xét lời gọi hàm
t=F(4);
Số hàm được gọi
chính là số nút trên
cây.
Do đó với kích thước
tham số lớn hàm đệ
quy tiêu tốn nhiều
thời gian và bộ nhớ.
t=F(4)
+
||
1 1||
||
1 +
Hỏi đáp