










Preview text:
11/2/2025 NỘI DUNG
Trường Đại học Thủ Dầu Một
Viện Công nghệ số • Giới thiệu 1 • Khái niệm về hàm 2 CƠ SỞ LẬP TRÌNH • Hàm chuẩn 3 • Hàm tự định nghĩa 4 Chương IV • Hàm đệ quy cơ bản 5 Hàm • Bài tập 6 Chương 4. Hàm 2 1 2 Kết quả học tập 1. Giới thiệu (1/4)
v Viết chương trình tính S = a! + b! + c! với a, b, c là 3
v Phân tích được các chương trình phức tạp thành
số nguyên dương nhập từ bàn phím. các chương trình con. Chương trình chính
v Viết hàm giải quyết các chương trình con.
v 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 Nhập Nhập Nhập Tính Tính Tính a > 0 b > 0 c > 0 s1=a! s2=b! s3=c! Chương 4. Hàm 3 Chương 4. Hàm 4 3 4 1 11/2/2025 1. Giới thiệu (2/4) 1. Giới thiệu (3/4)
v 3 đoạn lệnh nhập a, b, c > 0
v 3 đoạn lệnh tính s1 = a!, s2 = b!, s3 = c! do {
{ Tính s1 = a! = 1 * 2 * … * a }
printf(“Nhap mot so nguyen duong: ”); s1 = 1;
scanf(“%d”, &a);
for (i = 2; i <= a ; i++)
} while (a <= 0);
s1 = s1 * i; 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; Chương 4. Hàm 5 Chương 4. Hàm 6 5 6 1. Giới thiệu (4/4)
2. Khái niệm về hàm (1/4)
v Trong những chương trình lớn phức tạp hoặc chương
v Giải pháp => Viết 1 lần và sử dụng nhiều lần
trình có những đoạn lệnh viết lặp đi lặp lại nhiều lần;
Ø Đoạn lệnh nhập tổng quát, với n = a, b, c
Để tránh rườm rà và mất thời gian khi viết chương trình: do {
printf(“Nhap mot so nguyen duong: ”);
Ø Người ta thường phân chia chương trình thành các module.
scanf(“%d”, &n);
Ø Mỗi module giải quyết một công việc nào đó.
} while (n <= 0);
Ø Đ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; Chương 4. Hàm 7 Chương 4. Hàm 8 7 8 2 11/2/2025
2. Khái niệm về hàm (2/4)
2. Khái niệm về hàm (3/4) v Chương trình con là:
v 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:
v 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,
dạng hàm, không có thủ tục.
bản chất không đổi nhưng giá trị các tham số cung cấp khác nhau.
Ø Giá trị hàm có thể không cần dùng đến
Chia để trị: chia chương trình lớn thành các chương trình nhỏ rồi 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. Chương 4. Hàm 9 Chương 4. Hàm 10 9 10
2. Khái niệm về hàm (4/4) 3. Hàm chuẩn (1/4) v Hàm có hai loại:
v Hàm chuẩn là những hàm đã được định nghĩa sẵn trong
Ø Hàm chuẩn: là những hàm đã được định nghĩa sẵn trong các thư viện của C/C++. một thư viện nào đó;
Ø Hàm tự định nghĩa: là những hàm do người dùng tự xây
v Muốn sử dụng các hàm chuẩn thì phải khai báo thư
dựng để sử dụng khi viết một chương trình nào đó.
viện trước khi sử dụng bằng lệnh: #include
v Trong chương này, chúng ta chỉ tập trung vào phần tự
v Một số thư viện thường dùng:
định nghĩa hàm: Định nghĩa, truyền tham số, trả giá trị, gọi hàm,….
Ø stdio.h: Chứa các hàm vào/ ra chuẩn (standard input/output)
của C. Gồm printf(), scanf(), gets(), puts(), fflush(), …
Ø iostream.h: Chứa các hàm vào/ ra chuẩn (standard input/output)
của C++. Gồm cin>>, cout<<, … Chương 4. Hàm 11 Chương 4. Hàm 12 11 12 3 11/2/2025 3. Hàm chuẩn (2/4) 3. Hàm chuẩn (3/4)
v Một số thư viện thường dùng: (tt)
v 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(), … Chương 4. Hàm 13 Chương 4. Hàm 14 13 14
4. Hàm tự định nghĩa 3. Hàm chuẩn (4/4)
4.1. Xây dựng hàm (1/5)
v Ví dụ: Chương trình kiểm tra số nguyên n có phải là số v Cú pháp: chính phương. () #include { ; #include ; int main() { } int n; float k; v Trong đó:
printf("Nhap n: = "); Hàm tính
Ø : Là các kiểu dữ liệu của C được dùng làm kiểu trả
scanf("%d", &n); căn bậc 2 về của hàm.
k = sqrt ((float)n);
Ø : Nên đặt ngắn gọn, phản ánh chức năng của hàm.
if (k*k == n)
printf("%4d la SCP.\n", n);
Ø : Có thể có hoặc không tuỳ thuộc vào else
mục đích sử dụng của hàm
printf("%4d la khong SCP.\n", n);
Ø : Là biến chỉ được sử dụng trong thân hàm. }
Ø : Là các lệnh để thực hiện công việc của hàm. Chương 4. Hàm 15 Chương 4. Hàm 16 15 16 4 11/2/2025
4.1. Xây dựng hàm (2/5)
4.1. Xây dựng hàm (3/5) v Ví dụ: v Chú ý:
long giaithua(int n)
1. Hàm có thể có giá trị trả về hoặc không. {
int UCLN(int a, int b) {
Nếu hàm có giá trị trả về thì 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 là void.
for (i=1;i<=n;i++) else b -= a; gt *= i ; return a; } void IN()
long giaithua(int n) return gt; { { }
printf("Welcome to C"); int i; } void IN() long gt ;
int UCLN(int a, int b) {
Chỉ ra các thành phần trong mỗi hàm?
for (i=1;i<=n;i++) { gt *= i ;
printf("Welcome to C");
while (a!=b)
Sự khác nhau giữa các hàm? return gt;
if (a>b) a -= b; } else b -= a; } return a; } Chương 4. Hàm 17 Chương 4. Hàm 18 17 18
4.1. Xây dựng hàm (4/5)
4.1. Xây dựng hàm (5/5) v Chú ý: v 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.
long giaithua(int N)
int UCLN(int a, int b)
int UCLN(int a, int b) { { { int i;
while (a!=b)
while (a!=b) long GT ;
if (a>b) a -= b;
if (a>b) a -= b;
for (GT=1,i=1;i<=N;i++) else b -= a; else b -= a; GT *= i ; return a; return a; return(GT); } } } Chương 4. Hàm 19 Chương 4. Hàm 20 19 20 5 11/2/2025
4.2. Lời gọi hàm (1/4)
4.2. Lời gọi hàm (2/4)
v 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 ()
for (int i=1; i<=n; i++) { ;
if (n%i==0) printf("%d\t",i); ; } } void main() {
Ø Gọi hàm: Lời gọi hàm là một câu lệnh độc lập int n; (); 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ị getch(); } Chương 4. Hàm 21 Chương 4. Hàm 22 21 22
4.2. Lời gọi hàm (3/4)
4.2. Lời gọi hàm (4/4)
Ví dụ: Xây dựng hàm tính tổng các ước số của n.
v Hàm trả giá trị: int Tonguocso(int n) { Ø Khai báo hàm: int S=0; ()
for (int i=1; i<=n; i++)
if (n%i==0) S=S+i; { ; return(S); ; } void main() return ; { } int n, tong;
Ø Gọi hàm: Lời gọi hàm phải nằm trong một biểu thức
printf("Nhap n: "); scanf("%d",&n);
tong=Tonguocso(n); //Gọi hàm trả giá trị = ();
printf("Tong cac uoc so cua %d la %5d",n,tong);
Ø Hàm này thường sử dụng khi thực hiện các chức năng: tính
//printf("Tong cac uoc so cua %d la %5d", n,Tonguocso(n));
tổng, tích, trung bình, đếm, kiểm tra, tìm kiếm. getch(); } Chương 4. Hàm 23 Chương 4. Hàm 24 23 24 6 11/2/2025
4.3. Hoạt động của hàm (1/2)
4.3. Hoạt động của hàm (2/2)
v Khi gặp một lời gọi máy sẽ tạm dời chỗ chuyển đến void main(){ hàm tương ứng. int a; long gt;
v Quá trình theo trình tự sau:
printf("Vao a=“); scanf("%d",&a);
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 N a ) {
Ø 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=1 ;
thì máy sẽ xóa các tham số, biến cục bộ và ra khỏi hàm.
for (i=1; i <= N a ; 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. } Chương 4. Hàm 25 Chương 4. Hàm 26 25 26
4.4. Truyền tham số cho hàm (1/5)
4.4. Truyền tham số cho hàm (2/5)
Ø Truyền theo giá trị:
v Có hai cách truyền tham số cho hàm:
Ví dụ: Viết chương trình tìm UCLN của 2 số nguyên dương a và b.
Ø Truyền theo giá trị: Không làm thay đổi giá trị của tham số #include
vào khi ra khỏi hàm cho dù trong thân hàm có câu lệnh làm … int UCLN(int m, int n)
thay đổi giá trị của nó hay không. {
while (m!=n)
Ø Truyền theo địa chỉ: Làm thay đổi giá trị của biến truyền vào
if (m>n) m -= n;
khi ra khỏi hàm. Các tham số được truyền vào theo địa chỉ. void main()
else n -= m;
Ø Trong C++ có thêm cách truyền theo tham biến: Cũng làm { return m; }
thay đổi giá trị của tham số truyền vào khi ra khỏi hàm.
int m=6, n = 10;
printf("UCLN cua %d va %d la %d\n", m, n, UCLN(m,n));
printf(“Gia tri cua m la %d, n la %d\n", m, n); } UCLN cua 6 va 10 la 2 Kết quả Gia tri cua m la 6, n la 10 Chương 4. Hàm 27 Chương 4. Hàm 28 27 28 7 11/2/2025
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
Ví dụ: Viết hàm hoán đổi để hoán đổi giá trị của 2 số a và b.
void hoandoi(int a, int b) #include Kết quả
void hoandoi(int *a, int *b) { int tam; { int tam;
tam=a; a=b; b=tam;
tam=*a; *a=*b; *b=tam; } Kết quả } void main() void main()
{ int x, y;
{ 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); getch(); } } Chương 4. Hàm 29 Chương 4. Hàm 30 29 30
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ố khi khai báo hàm) v Biến toàn cục:
Ví dụ: Viết hàm hoán đổi để hoán đổi giá trị của 2 số a và b.
Ø Biến toàn cục là biến được khai báo bên ngoài tất cả định nghĩa #include hàm.
void hoandoi(int &a, int &b)
Ø Biến toàn cục duy trì giá trị của nó trong suốt thời gian thực thi { int tam;
chương trình, bất kỳ hàm nào cũng có thể sử dụng biến này.
tam=a; a=b; b=tam; Ø Ví dụ: } Kết quả #include void main()
int x = 1; // x là biến toàn cục { int x, y; int main()
x=10; y=20; {
printf("Truoc khi hoan doi x=%d, y=%d\n", x, y); ... hoandoi(x, y); }
printf("Sau khi hoan doi x=%d, y=%d\n", x, y); getch(); } Chương 4. Hàm 31 Chương 4. Hàm 32 31 32 8 11/2/2025
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) v Biến cục bộ:
v Khi khai báo hàm sau lời gọi nó thì ta phải khai báo
Ø Biến cục bộ là biến được khai báo bên trong một hàm hay một nguyên mẫu cho hàm. khối lệnh nào đó.
v Nguyên mẫu hàm phải được khai báo trước bất kỳ lời
Ø Biến cục bộ chỉ có tác dụng trong thân hàm hay trong khối
gọi hay định nghĩa hàm nào.
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ó. v Cú pháp: Ø Ví dụ: (); hoặc:
int Tonguocso(int n) (); { v Ví dụ:
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 int UCLN(int a, int b);
if (n%i==0) S=S+i; Hoặc int UCLN(int, int); return(S); } Chương 4. Hàm 33 Chương 4. Hàm 34 33 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 int KT(int k); int KT(int k)
v 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() int i;
Nếu chỉ có một giá trị được truyền trở lại hàm thì xây dựng hàm { if (n<2)
theo kiểu hàm trả giá trị. int n; return 0;
printf("Nhap N: ");
Nếu có nhiều giá trị được truyền trở lại hàm thì xây dựng hàm theo if(n==2)
scanf("%d",&n);
kiểu hàm không trả giá trị (void) và sử dụng tham số tham chiếu return 1 ;
printf("Cac so NT tu 2 den %d cho những giá trị đó. int i=2; la:\n");
Ø Hàm làm gì? Xác định tên hàm.
While (i<=sqrt((float)n)) INSNT(n); i++;
Ø Cần những thông tin gì để hàm xử lý? Xác định tham số. } if(n%i!=0)
Với tham số đã xác định, xác định xem đã có giá trị trước khi vào
void INSNT(int n) return(1); hàm chưa: { else
Nếu chưa có Tham chiếu.
for (int i=2;i<=n;i++) return(0);
Nếu đã có mà sau khi thực hiện xong hàm vẫn không thay đổi
if (KT(i)==1) printf("%d\t",i); } Tham trị. }
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. Chương 4. Hàm 35 Chương 4. Hàm 36 35 36 9 11/2/2025
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 v Khái niệm v Gồm có 2 phần:
Ø Trong thân một hàm có thể gọi tới một hàm khác.
Ø Phần cơ sở (phần suy biến đệ quy)
Ø Nếu hàm gọi đến chính nó thì được gọi hàm đệ quy.
Ø Phần đệ quy: Sử dụng lại hàm lúc đầu tuy nhiên giá trị truyền
Ø Số lần gọi này phải có giới hạn (điểm dừng)
vào cho các tham số thì khác. v Ví dụ if if (trường trường hợp cơ sở ) sở
Định nghĩa hàm giai thừa
Ø Tính GT(n) = n! = n*(n-1)*…*2*1 { int GT(int n)
trình bày cách giải bài toán Ø Hay: {
(giả định đã có cách giải) if (n==0)
GT(n) = n*GT(n-1). Vậy thay vì tính GT(n) ta sẽ đi tính GT(n-1) } return 1;
sau đó lấy kết quả nhân với n.
else /* trường hợp tổng quát*/
Riêng với trường hợp n=0, chúng ta đã biết 0!=1 hay GT(0)=1. { else
Trường hợp này không cần tính theo công thức trên.
gọi đệ qui tới hàm (đang lập) với
giá trị khác của tham số return(n*GT(n-1)); } } Chương 4. Hàm 37 Chương 4. Hàm 38 37 38 5.3. Ví dụ
5.4. Các bài toán có thể dùng đệ quy int GT(int n) {
Tính giai thừa của số nguyên n. if (n==0)
v Phương pháp đệ quy thường áp dụng cho các bài toán #include return 1;
phụ thuộc tham số có hai đặc điểm sau:
// Ðịnh nghĩa đệ quy hàm GiaiThua else
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 {
toán cùng dạng nhưng giá trị tham số thì bị thay đổi. Sau một int n; 3*GT(2) 3*2=6
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: "); 2*GT(1) 2*1=2 biến.
scanf("%d",&n);
printf("%d! = %d", n, GT(n)); 1*GT(0) 1*1=1 } 1 Chương 4. Hàm 39 Chương 4. Hàm 40 39 40 10 11/2/2025 Bài tập (1/3) Bài tập (2/3)
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 nhập vào từ bàn phím).
đó đã tối giản hay chưa.
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.
6. Viết hàm để tính số Fibonaci thứ n, biết rằng:
3. Viết chương trình tính giá trị của biểu thức: F = 0 0
12 + (1+2)2 + (1+2+3)2 +…..+ (1+2+3+…n)2 F = F =1 1 2 F = F + F n n – 1 n – 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. Chương 4. Hàm 41 Chương 4. Hàm 42 41 42 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. Chương 4. Hàm 43 43 11