BÀI 1 : MỞ ĐẦU - Đường còn dài, ta cứ đi rồi sẽ đến. Cố tâm dồn

Download Report

Transcript BÀI 1 : MỞ ĐẦU - Đường còn dài, ta cứ đi rồi sẽ đến. Cố tâm dồn

CHƯƠNG 1
2
Chương 6
HÀM
Functions
1
Mục đích viết Hàm?
 Trong chương trình có nhiều đoạn chương
trình lặp lại giống hệt nhau
 Trong chương trình có nhiều đoạn chương
trình có chức năng tương tự nhau
 Cần phần chia một chương trình dài, phức tạp
thành các chương trình ngắn hơn, đơn giản
hơn.
 Do phân chia vào các chương trình con nên
giảm tải công việc cho hàm main hơn
2
1. Hàm là gì?
Hàm hay còn gọi là chương trình con (sub
program)
Nó là một đoạn chương trình nhằm thực hiện
một thao tác, một công đoạn nào đó của toàn
bộ hệ thống chương trình.
Có 2 loại hàm: hàm thư viện và hàm tự định
nghĩa (tự thiết kế)
Hàm thư viện
Hàm thư viện:
 Là những hàm đã được xây dựng sẵn. Muốn sử
dụng các hàm thư viện phải khai báo thư viện
chứa nó.
 Cú pháp chung của một hàm thư viện là:
< ReturnType > functionName ([<Kiểu tham số><Tên tham số>][,…])
Một số hàm toán học thông dụng
Khi sử dụng các hàm toán học ta phải khai báo thư viện
<math.h>
5
Hàm thư viện
Hàm do người dùng định nghĩa:
int TestSoChan(int n);
void InputArray(int A[], int spt);
Tổng quan ta khai báo
cú pháp hàm như thế
nào?
2. Cú pháp tổng quát của một hàm?
 Phần trong dấu <…> : là bắt buộc phải có
 Phần trong dấu […]: là không bắt buộc có
Giải thích Hàm
• <kiểu kết quả> là kiểu dữ liệu của kết quả trả về, có thể
là: int, byte, char, float, void, … Một hàm có thể có
hoặc không có kết quả trả về. Trong trường hợp hàm
không có kết quả trả về ta sử dụng kiểu kết quả là void.
• <Kiểu tham số>: kiểu dữ liệu của tham số
• <Tham số >: là tham số truyền dữ liệu vào cho hàm,
một hàm có thể có hoặc không có tham số. Tham số
này là tham sô hình thức.
• [<return>[<biểu thức>]] dùng để thoát khỏi một hàm và
có thể trả về một giá trị nào đó.
3. Gọi Hàm
Một hàm khi đã định nghĩa nhưng chúng vẫn
chưa được thực thi, hàm chỉ được thực thi khi
trong chương trình có một lời gọi đến hàm đó.
Cú pháp gọi hàm:
< Tên hàm > ([ Danh sách các tham số ])
Ghi chú: phần trong <…> là bắt buộc có, phần
trong[…] là không bắt buộc.
Tính chất của ‘Hàm’
Hàm có thể được gọi từ chương trình chính
(hàm main) hoặc từ một hàm khác.
Hàm có thể có giá trị trả về hoặc không. Nếu
hàm không có giá trị trả về thì lúc đó ta gọi
hàm là thủ tục (procedure)
Nguyên tắc hoạt động của Hàm
Hàm có thể được gọi từ nhiều chỗ khác nhau
trong chương trình.
Khi hàm được gọi, khối lệnh tương ứng của hàm
được thực thi.
Sau khi thực hiện xong, quyền điều khiển được
trả về cho chương trình gọi.
Minh họa việc gọi các Hàm
f1()
{
void main()
{
.
.
.
...;
...;
}
f1();
.
.
.
…
f2();
.
.
…
…
f2()
{
...;
f1();
}
.
f3();
f2();
f3()
{
.
.
.
}
...;
f1();
…
f2();
}
12
4. Tham số hình thức và tham sô thực
Tham hình thức
Khi hàm cần nhận tham số (parameter) để
thực thi, thì ở phần khai báo hàm ta cần liệt
kê danh sách các tham số đặt trong cặp dấu
ngoặc (…), liền sau phần tên hàm.
Danh sách các tham số này để nhận giá trị từ
chương trình gọi.
Các tham số ở phần khai báo ta gọi là các
tham số hình thức.
13
4. Tham số hình thức và tham số thực
(tt)
Tham số thực
Khi gọi hàm, ta cung cấp các tham số cụ thể
cho hàm(nếu có), các tham số này sẽ được
sao chép vào các tham số hình thức tưng ứng
ở phần khai báo.
Các tham số đưa vào tại thời điểm gọi hàm
thì ta gọi là tham số thực (tham số thực
sự).
14
Ví dụ
#include <iostream.h>
//------------khai bao Prototype (Ham mau)-------int min(int a, int b);
Tham số thực sự
Tham số hình thức
//------------CHUONG TRINH CHINH------------void main()
{
int x=40, y=30,soNN;
soNN = min(x,y); // ta gọi hàm min, truyền vào 2 tham số
// kết quả hàm min ta gán cho biến soNN
cout << “So nho nhat la: “ << soNN;
}
//------------Trien Khai Cac Ham--------------------int min(int a, int b) // bo dau cham phay ‘;’
{
if(a<b)
return a; // Tra gia tri a ve cho Ham
else
return b; // Tra giá trị b về cho Hàm
}
Truyền tham trị và truyền tham biến
 4.1Truyền tham trị (call by value)
 Bằng cách này, ta gửi giá trị của tham số thực
cho tham số hình thức tưng ứng của hàm.
 Do vậy, gía trị của tham số thực không bị thay
đổi khi kết thúc hàm
Ví dụ: Cách truyền tham trị
Tham số thực sự
#include <iostream.h>
//------------khai bao Prototype (Ham mau)-------void doubleNum(int a);
void main()
Tham số hình thức
{
int y = 40;
doubleNum(y);
cout << “y= “ <<y << endl;
Truyền tham trị
}
//------------Trien Khai Cac Ham--------------------void doubleNum( int a)
{
a = a*2;
cout << “Inside doubleNum function. a = “ << a;
}
Minh họa cách truyền tham trị
y: 40
a: 40
80
18
Truyền tham trị và truyền tham biến
4.2 Truyền tham chiếu (call by reference)
 Bằng cách này, ta gửi địa chỉ của tham số thực
cho tham số hình thức tưng ứng của hàm.
 Do vậy, gía trị của tham số thực bị thay đổi khi
kết thúc hàm (còn gọi là truyền bằng địa chỉ)
 Tham số hình thức và tham số thực có cùng một
địa chỉ trong bộ nhớ máy tính.
Ví dụ: Cách truyền tham biến
Tham số
thực sự
#include <iostream.h>
#include <conio.h>
//------------khai bao Prototype (Ham mau)-------void DoiCho2So(int &a, int &b );
void main()
Tham số hình
{
thức
int so1 = 40, so2= -10;
DoiCho2So(so1,so2);
cout <<" So 1: "<<so1<<"\n"<<"So 2: "<<so2;
}
//------------Trien Khai Cac Ham--------------------void DoiCho2So(int &a, int &b )
{
int temp;
temp=a;
a=b;
b=temp;
}
Truyền tham
biến
Minh họa cách truyền tham trị
so1: -5
a
so2: 80
b
21
Truyền tham biến là con trỏ
Ngoài ra:
Để tham số hình thức được truyền bằng tham biến
thì tham số hình thức phải là một con trỏ và khi
gọi hàm ta phải gửi cho nó một địa chỉ (phần này
nói rõ hơn ở Chương 5 Con trỏ)
Nên ta khai báo theo cách thứ 2 như sau:
void DoiCho2So(int *a, int *b);
Toán tử lấy điạ chỉ
Và khi gọi hàm như sau:
&
DoiCho2So(&so1,&so2);
22
5. Truyền mảng vào Hàm
Khi tham số hình thức ta đưa vào là một mảng
(Array), thì việc truyền mảng là truyền theo tham
biến (reference)
Ví dụ:
void InputArray(int A[], int spt);
Biến A có kiểu dữ liệu là mảng,
Truyền tham biến
Ghi chú: sẽ nói rõ hơn phần mảng ở chương 4
23
6.Đối số của hàm main
 Hàm main có thể có đối số được khai như sau:
int main(int argc, char *argv[])
{
…
return 0;
}
Trong đó:
• argc : ghi nhận số đối số thực tế khi chay chương trình
• argv[] : mảng các con trỏ, trỏ tới địa chỉ đầu tiên của
chuỗi các đối số khi chạy chương trình
Lưu ý
• Khi một chương trình không yêu cầu cung cấp đối
số dòng lệnh, ta khai báo hàm main như sau
void main()
{
…
return ; // Do khai báo kiểu void
// nên dòng này ta cũng có thể không ghi
}
7. Lệnh return
 Lệnh return dùng để thoát khỏi một hàm và có thể trả về một
giá trị nào đó.
o return ; //không trả về giá trị , (trường hợp ta khai báo là void)
o return <biểu thức>; //Trả về giá trị của biểu thức
o return (<biểu thức>); //Trả về giá trị của biểu thức*/
Lưy ý:
Nếu hàm có kết quả trả về, ta bắt buộc ta phải sử dụng câu
lệnh return để trả về kết quả cho hàm.
8. Khái niệm đệ qui
 Một hàm trong đó có lời gọi tới chính nó gọi là hàm đệ
qui ( Ta nói tắt là ”nó gọi chính nó”)
 Ta cần xác định rõ điểm kết thúc đệ qui (end recursion),
nếu không sẽ bị tràn bộ nhớ stack (stack overflow)
 Do vậy, một hàm đệ qui sau một số lần đệ qui sẽ thỏa
mãn một điều kiện kết thúc đệ qui.
Dạng tổng quát hàm đệ qui
ReturnType RecursiveFunction(…)
{
Điều kiện dừng
if (condition)
end_Recursion;
else
RecursiveFunction(…);
}
Gọi lại chính nó
Khử đệ qui
• Viết theo đệ qui có thể ngắn gọn hơn
• Tuy nhiên, hàm đệ qui thường cần nhiều không
gian bộ nhớ stack để lưu trữ mã lệnh sau mỗi lần
tự gọi lại chính nó, do đó có thể làm chương trình
chay chậm
• Thay vì viết một hàm đệ qui ta có thể sử dụng
một hoặc nhiều vòng lặp để thay thế đệ qui (khử
đệ qui)
Ví dụ tính n! (n giai thừa)
n! = 1* 2 * 3 *…* (n-1) *n = (n-1)! *n (với 0!=1)
int giaiThua(int n)
Điều kiện dừng
{
int gt;
Gọi lại chính nó
if(n==0)
return(1);
else
gt = giaiThua n*(n-1);
return gt;
}
9. Khai báo hàm mẫu (Prototype)
• Về nguyên tắc, chúng ta viết hàm trước khi sử
dụng thì cũng không cần khai báo prototype cho
hàm.
• Lời khuyên, chúng ta cũng nên khai báo
prototype cho hàm rồi mới viết hàm. Vì việc khai
báo prototype cho hàm giúp cho trình biên dịch
kiểm soát khi chúng ta viết hàm cũng như sử
dụng hàm có đúng như đã được mẫu khai báo
không.
Ví dụ
#include <iostream.h>
#include < ... >
//------------khai bao Prototype (Ham mau)-------int min(int a, int b);
int tong(int a, int b);
int tich(int a, int b);
//------------CHUONG TRINH CHINH------------void main()
{
int x=5,y=- 10;
cout<< min (x,y);
cout<<“\n” <<tong(x,y);
cout<<“\n”<<tich(x,y);
}
//------------Viết Cac Ham--------------------int min(int a, int b) // ta nhớ bo dau cham phay ‘;’ khi viết
{
if(a<b)
return a; // Tra gia tri a ve cho Ham
else
return b; // Tra giá trị b về cho Hàm
}
int tong(int a, int b) // ta nhớ bo dau cham phay ‘;’ khi viết
{
….
}
[1] . Khai báo
prototype
[2]. Viết nội dung
cho hàm
Finish.
33