Professional Documents
Culture Documents
Chuong 4 - Function
Chuong 4 - Function
1 • Giới thiệu
2 • Khái niệm về hàm
CƠ SỞ LẬP TRÌNH
3 • Hàm chuẩn
4 • Hàm tự định nghĩa
Chương 4
• Hàm đệ quy cơ bản
HÀM 5
6 • Bài tập
Phone: 0274. 3834930 Website: http://et.tdmu.edu.vn 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 2
Sử dụng hàm đã viết giải quyết bài toán ban đầu. Nhập Tính Xuất
a, b, c > 0 S = a! + b! + c! kết quả S
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 3 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 4
do { { Tính s2 = b! = 1 * 2 * … * b }
printf(“Nhap mot so nguyen duong: ”); s2 = 1;
scanf(“%d”, &b); for (i = 2; i <= b ; i++)
} while (b <= 0); s2 = s2 * i;
do { { Tính s3 = c! = 1 * 2 * … * c }
printf(“Nhap mot so nguyen duong: ”); s3 = 1;
scanf(“%d”, &c); for (i = 2; i <= c ; i++)
} while (c <= 0); s3 = s3 * i;
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 5 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 6
1
1. Giới thiệu (4/4) 2. Khái niệm về hàm (1/4)
Đoạn lệnh tính giai thừa tổng quát, n = a, b, c Các module như vậy gọi là các chương trình con.
// Tính s = n! = 1 * 2 * … * n
s = 1;
for (i = 2; i <= n ; i++)
s = s * i;
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 7 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 8
Chương trình con là: Trong một số ngôn ngữ lập trình khác, có 2 loại
Một đoạn chương trình có tên, đầu vào và đầu ra. chương trình con:
Có chức năng giải quyết một số vấn đề chuyên biệt cho Hàm (function): trả về giá trị thông qua tên hàm, sử dụng
trong các biểu thức và không được gọi như một lệnh.
chương trình chính.
Thủ tục (procedure): không có giá trị trả về, có thể tồn tại
Được gọi nhiều lần với các tham số khác nhau. độc lập và được gọi như là một câu lệnh.
Được sử dụng khi có nhu cầu: Trong C/C++: chỉ tồn tại chương trình con dưới
Tái sử dụng: có một số chương trình được thực hiện ở nhiều nơi,
bản chất không đổi nhưng giá trị các tham số cung cấp khác nhau.
dạng hàm, không có thủ tục.
Chia để trị: chia chương trình lớn thành các chương trình nhỏ rồi Giá trị hàm có thể không cần dùng đến
ghép lại. Có thể không có giá trị nào gán vào tên hàm (void)
Giúp chương trình trong sáng, dễ hiểu, dễ phát hiện lỗi Cung cấp các giá trị không phải là vô hướng
và cải tiến.
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 9 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 10
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 11 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 12
2
3. Hàm chuẩn (2/4) 3. Hàm chuẩn (3/4)
Một số thư viện thường dùng: (tt) Một số thư viện thường dùng: (tt)
conio.h: Chứa các hàm vào ra trong chế độ DOS (DOS alloc.h: Chứa các hàm liên quan đến việc quản lý bộ nhơ. Gồm
console). Gồm clrscr(), getch(), getche(), getpass(), cgets(), calloc(), realloc(), malloc(), free(), farmalloc(), farcalloc(),
cputs(), putch(), clreol(),… farfree(), …
math.h: Chứa các hàm toán học. Gồm abs(x), sqrt(x), log(x), io.h: Chứa các hàm vào ra cấp thấp. Gồm open(), _open(),
log10(x), sin(x), cos(x), tan(x), acos(x), asin(x), atan(x), read(), _read(), close(), _close(), creat(), _creat(), creatnew(),
pow(x,y), exp(x),… eof(), filelength(), lock(),…
string.h: Chứa các hàm về chuỗi. Gồm strlen(), strcpy(), graphics.h: Chứa các hàm liên quan đến đồ họa. Gồm
strncpy(), strcat(), strncat(), strcmp(), strncmp(), strchr(), initgraph(), line(), circle(), putpixel(), getpixel(), setcolor(), …
strlwr(), strupr(), …
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 13 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 14
4.1. Xây dựng hàm (2/5) 4.1. Xây dựng hàm (3/5)
Ví dụ:
Chú ý:
long giaithua(int N) UCLN(int a, int b)
1. Hàm có thể có giá trị trả về hoặc không.
{ { Nếu hàm có giá trị trả về thì <Kiểu DL> phải tương ứng với kiểu dữ
int i; while (a!=b) liệu trả về.
long GT ; if (a>b) a -= b; Nếu hàm không có giá trị trả về thì khai báo <Kiểu DL> là void.
for (GT=1,i=1;i<=N;i++) Mặc định hàm trả về kiểu int.
else b -= a;
GT *= i ; void IN()
return(GT); return a; {
long giaithua(int N)
} } { printf("Welcome to C");
int i; }
void IN() long GT ; UCLN(int a, int b)
{ Chỉ ra các thành phần trong mỗi hàm? for (GT=1,i=1;i<=N;i++) {
GT *= i ; while (a!=b)
printf("Welcome to C"); Sự khác nhau giữa các hàm? return(GT); if (a>b) a -= b;
} } else b -= a;
return a;
}
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 17 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 18
3
4.1. Xây dựng hàm (4/5) 4.1. Xây dựng hàm (5/5)
Chú ý: Chú ý:
2. Nếu hàm có giá trị trả về thì trong thân hàm phải có ít nhất một 3. Nếu hàm có đối số thì các đối số phải viết cách nhau bởi dấu
câu lệnh return để trả giá trị cho hàm theo cú pháp: phẩy (,) và phải khai báo kiểu dữ liệu cho mỗi đối số cho dù các
return(giá trị); hoặc return giá trị; đối có cùng kiểu.
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 19 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 20
4.2. Lời gọi hàm (1/4) 4.2. Lời gọi hàm (2/4)
Hàm không trả giá trị: Ví dụ: Xây dựng hàm in ra các ước số của n.
Khai báo hàm: void Inuocso(int n)
{
void <Tên hàm>(<DS các đối số>) for (int i=1; i<=n; i++)
{ <Khai báo các biến cục bộ>; if (n%i==0) printf("%d\t",i);
<Khối lệnh>; }
} int main()
{
Gọi hàm: Lời gọi hàm là một câu lênh độc lập int n;
<Tên hàm>(<danh sách tham số thực sự>); printf("Nhap n: ");
scanf("%d",&n);
Hàm này thường sử dụng khi thực hiện các chức năng: nhập, printf("Cac uoc so cua %d la: \n",n);
xuất, sắp xếp, liệt kê,… Inuocso(n); //Gọi hàm không trả giá trị
return 0;
}
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 21 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 22
4.2. Lời gọi hàm (3/4) 4.2. Lời gọi hàm (4/4)
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 23 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 24
4
4.3. Hoạt động của hàm (1/2) 4.3. Hoạt động của hàm (2/2)
Khi gặp một lời gọi máy sẽ tạm dời chỗ chuyển đến int main(){
hàm tương ứng. int a; long gt;
printf("Vao a=“); scanf("%d",&a);
Qua trình theo trình tự sau:
gt = giaithua(a);
Cấp phát bộ nhớ cho các biến cục bộ.
printf("Giai thua cua %d la %ld",a,gt);
Gán giá trị của các tham số thực cho các tham số hình thức }
tương ứng.
Thực hiện các câu lệnh trong thân hàm. long giaithua( int aN ) {
Khi gặp câu lệnh return hoặc dấu } cuối cùng của thân hàm int i; long GT ;
thì máy sẽ xóa các tham số, biến cục bộ và ra khỏi hàm. for (GT=1, i=1; i <= Na ; i++)
GT *= i ;
Nếu hàm có giá trị trả về (trong lệnh return) thì giá trị này return(GT);
sẽ được sử dụng trong các biểu thức chứa hàm này. }
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 25 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 26
4.4. Truyền tham số cho hàm (1/5) 4.4. Truyền tham số cho hàm (2/5)
4.4. Truyền tham số cho hàm (3/5) 4.4. Truyền tham số cho hàm (4/5)
Truyền theo địa chỉ: Sử dụng con trỏ để trỏ đến địa chỉ của
biến cần truyền vào làm tham số cho hàm. Nếu sửa chương trình thành:
*a là biến con trỏ a (dùng khi khai báo hàm), sẽ trỏ tới &x (là
địa chỉ của biến cần truyền vào trong hàm) #include <stdio.h>
void hoandoi(int a, int b)
Ví dụ: Viết hàm hoán đổi để hoán đổi giá trị của 2 số a và b.
#include <stdio.h> { int tam;
void hoandoi(int *a, int *b) tam=a; a=b; b=tam;
{ int tam; } Kết quả
tam=*a; *a=*b; *b=tam; Kết quả void main()
}
{ int x, y;
void main()
{ int x, y; x=10; y=20;
x=10; y=20; printf("Truoc khi hoan doi x=%d, y=%d\n", x, y);
printf("Truoc khi hoan doi x=%d, y=%d\n", x, y); hoandoi(x, y);
hoandoi(&x, &y); printf("Sau khi hoan doi x=%d, y=%d\n", x, y);
printf("Sau khi hoan doi x=%d, y=%d\n", x, y);
} }
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 29 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 30
5
4.4. Truyền tham số cho hàm (5/5) 4.5. Biến toàn cục và biến cục bộ (1/2)
Truyền theo tham biến trong C++: (thêm dấu & trước tham số Biến toàn cục:
khi khai báo hàm) Biến toàn cục là biến được khai báo bên ngoài tất cả định nghĩa
Ví dụ: Viết hàm hoán đổi để hoán đổi giá trị của 2 số a và b. hàm.
#include <stdio.h> Biến toàn cục duy trì giá trị của nó trong suốt thời gian thực thi
void hoandoi(int &a, int &b) chương trình, bất kỳ hàm nào cũng có thể sử dụng biến này.
{ int tam; Ví dụ:
tam=a; a=b; b=tam; #include <stdio.h>
}
Kết quả
int x = 1; // x là biến toàn cục
void main()
int main()
{ int x, y;
x=10; y=20; {
cout<<"Truoc khi hoan doi x="<< x<<", y="<<y<<endl; ...
hoandoi(x, y); }
cout<<"Sau khi hoan doi x="<< x<<", y="<<y<<endl;
}
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 31 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 32
4.5. Biến toàn cục và biến cục bộ (1/2) 4.6. Khai báo nguyên mẫu cho hàm (1/2)
Biến cục bộ: Khi khai báo hàm sau lời gọi nó thì ta phải khai báo
Biến toàn cục là biến được khai báo bên trong một hàm hay nguyên mẫu cho hàm.
một khối lệnh nào đó.
Nguyên mẫu hàm phải được khai báo trước bất kỳ lời
Biến cục cục bộ chỉ có tác dụng trong hàm thân hàm hay trong gọi hay định nghĩa hàm nào.
khối lệnh đó, nó sẽ bị hủy đi khi sự thực thi thoát khỏi hàm
hay khối chứa nó. Cú pháp:
Ví dụ: <Kiểu DL> <Tên hàm> (<danh sách các đối số>); hoặc:
int Tonguocso(int n) {
<Kiểu DL> <Tên hàm> (<danh sách các kiểu của đối số>);
int S=0; //S là biến cục bộ, có tác dụng trong hàm Tonguocso
for (int i=1; i<=n; i++) // i là biến cục bộ, có tác dụng trong lệnh for Ví dụ:
if (n%i==0) S=S+i; int UCLN(int a, int b);
return(S); Hoặc int UCLN(int, int);
}
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 33 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 34
4.6. Khai báo nguyên mẫu cho hàm (1/2) 4.7. Nguyên tắc khi xây dựng hàm
#include <stdio.h>
int KT(int k); Trước khi xây dựng hàm phải trả lời những câu hỏi:
void INSNT(int); Hàm trả về gì? Xác định kiểu dữ liệu trả về của hàm.
void main() { Nếu chỉ có một giá trị được truyền trở lại hàm thì xây dựng hàm
int n;
printf("Nhap N: "); scanf("%d",&n);
theo kiểu hàm trả giá trị.
printf("Cac so NT tu 2 den %d la:\n"); Nếu có nhiều giá trị được truyền trở lại hàm thì xây dựng hàm theo
INSNT(n); kiểu hàm không trả giá trị (void) và sử dụng tham số tham chiếu
} cho những giá trị đó.
void INSNT(int n) { Hàm làm gì? Xác định tên hàm.
for (int i=2;i<=n;i++) Cần những thông tin gì để hàm xử lý? Xác định tham số.
if (KT(i)==1) printf("%d\t",i); Với tham số đã xác định, xác định xem đã có giá trị trước khi vào
} hàm chưa:
int KT(int k) { Nếu chưa có Tham chiếu.
int i;
for (i=2;i<=k/2;i++)
Nếu đã có mà sau khi thực hiện xong hàm vẫn không thay đổi
if (k%i==0) break; Tham trị.
if (i > k/2) return(1); else return(0); Nếu có mà sau khi thực hiện xong hàm thì giá trị cũng bị thay đổi
} theo Tham chiếu.
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 35 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 36
6
5. Hàm đệ quy cơ bản 5.2. Cấu trúc của chương trình đệ quy
5.1. Khái niệm
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 37 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 38
int GT(int n) {
Tính giai thừa của số nguyên n. if (n==0) Phương pháp đệ quy thường áp dụng cho các bài toán
#include <stdio.h> return 1;
// Ðịnh nghĩa đệ quy hàm GiaiThua else phụ thuộc tham số có hai đặc điểm sau:
return(n*GT(n-1)); Bài toán dễ dàng giải quyết trong một số trường hợp riêng
}
ứng với các giá trị đặc biệt của tham số. Ta thường gọi là
//Hàm main trường hợp suy biến.
void main() GT(3) = 6
Trong trường hợp tổng quát, bài toán có thể quy về một bài
{
3*GT(2) 3*2=6 toán cùng dạng nhưng giá trị tham số thì bị thay đổi. Sau một
int n;
số hữu hạn bước biến đổi đệ quy nó sẽ dẫn tới trường hợp suy
printf("Nhap so nguyen n: ");
scanf("%d",&n);
2*GT(1) 2*1=2 biến.
printf("%d! = %d", n, GT(n)); 1*GT(0) 1*1=1
}
1
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 39 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 40
1. Viết hàm tìm số lớn nhất trong hai số. Áp dụng tìm số
4. Viết chương trình tính giá trị của biểu thức:
lớn nhất trong ba số a, b, c. Với a, b, c nhập từ bàn phím.
1/1+(1+2)/(1*2)+(1+2+3)/(1*2*3)+…..+(1+2+3+…n)/(1*2*3*...*n)
Yêu cầu: Xây dựng hàm tính tổng 1+2+…+k và tính tích 1*2*...*k
2. Viết hàm tìm UCLN của hai số a và b. Áp dụng: nhập
vào tử và mẫu số của một phân số, kiểm tra xem phân số 5. Viết chương trình in ra các số nguyên tố từ 2 đến n (n được
đó đã tối giản hay chưa. nhập vào từ bàn phím).
Yêu cầu: Xây dựng hàm kiểm tra số k có phải là số nguyên tố không.
3. Viết chương trình tính giá trị của biểu thức: 6. Viết hàm để tính số Fibonaci thứ n, biết rằng:
12 + (1+2)2 + (1+2+3)2 +…..+ (1+2+3+…n)2 F0 = F1 = 1
Fn = Fn – 1 + Fn – 2
Yêu cầu: Xây dựng hàm tính tổng 1+2+…+k
Áp dụng hàm trên để tính tổng n số Fibonaci đầu tiên.
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 41 14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 42
7
Bài tập (3/3)
7. Viết hàm tính an với a kiểu số thực, n nguyên dương theo 2 cách:
a) Không đệ quy.
b) Dùng đệ quy.
8. Viết chương trình nhập số nguyên dương n tối đa 5 chữ số, kiểm
tra xem các chữ số n có phải là số đối xứng hay không.
Yêu cầu: Xây dựng hàm kiểm tra n đối xứng hay không
9. Viết chương trình nhập số nguyên dương n tối đa 6 chữ số, đếm
xem n có bao nhiêu chữ số chẳn.
Yêu cầu: Xây dựng hàm đếm
10. Nhập số nguyên dương n (n>0). Đếm xem có bao nhiêu số hoàn
thiện nhỏ hơn n.
Yêu cầu: Xây dựng kiểm tra số nguyên k có phải là số hoàn thiện không.
14/01/2019 Bài giảng Cơ sở lập trình - Trường ĐH Thủ Dầu Một 43 Phone: 0274. 3834930 Website: http://et.tdmu.edu.vn