- Khái niệm- Khai báo và định nghĩa - Lời gọi và sử dụng hàm - Biến và truyền tham số - Khai báo hàm trùng tên Hàm... Trong một chương trình có thể chứa nhiều hàm - Một hàm có thể được g
Trang 1LẬP TRÌNH C++
(3 Tín chỉ)
Gv: Nguyễn Văn Hùng
Trang 2Ngôn ngữ lập trình C++
6.1 Hàm 6.2 Hàm và mảng dữ liệu 6.3 Hàm và cấu trúc
6.4 Đệ quyChương 6: HÀM (FUNCTION)
Trang 3- Khái niệm
- Khai báo và định nghĩa
- Lời gọi và sử dụng hàm
- Biến và truyền tham số
- Khai báo hàm trùng tên
Hàm
Trang 4- Một chương trình trong C++ có thể gồm nhiều hàm Nhưng
có một hàm chính với tên gọi là hàm main().
- Khi thực thi chương trình, nó luôn bắt đầu từ hàm main().
- Hàm giúp cho việc phân đoạn chương trình một cách riêng
rẽ Hàm có thể được sử dụng nhiều lần trong một chương
trình hoặc sử dụng ở nhiều chương trình khác nhau
- Hàm có một số đặc điểm sau:
Trang 5Khái niệm
- Nằm trong hoặc ngoài chương trình có lời gọi đến hàm
Trong một chương trình có thể chứa nhiều hàm
- Một hàm có thể được gọi từ hàm main(), từ một hàm khác hay được gọi bởi chính nó (trường hợp đệ quy)
- Không có hàm lồng nhau
- Có 3 cách truyền giá trị cho hàm:
• Truyền theo tham biến
• Truyền theo tham trị
• Truyền theo tham trỏ
Trang 7Khai báo và định nghĩa hàm
Hàm định nghĩa sẵn: có trong tệp thư viện *.h Để sử dụng được các hàm này ta cần phải khai báo tệp tiêu đề theo cú
pháp #include<Tentaptinthuvien>
#include<cmath>
Trang 8Ngôn ngữ lập trình C++
Khai báo và định nghĩa hàm
Hàm do người lập trình tự định nghĩa: có thể được khai báo ở đầu chương trình theo cú pháp:
Kieu_du_lieu Ten_ham(Danh_sach_kieu_doi_so);
Trong đó:
Kieu_du_lieu: là kiểu trả về của hàm int, float, char, Trường hợp hàm không trả về giá trị thì khai báo kiểu void Trường
hợp không chỉ rõ kieu_tra_ve thì ngầm định là kiểu int
Ten_ham: được đặt theo quy tắc đặt tên.
Danh_sach_kieu_doi_so: có thể có hoặc không Trường hợp
không có thì gọi là hàm không có đối số
Trang 9Khai báo và định nghĩa hàm
Các câu lệnh;
return (biểu thức);
}
Trang 10double kq = 1 ; // kq để lưu kết quả
for (i=1; i<=n; i++)
kq *= x ; return kq;
}
Trang 11Khai báo và định nghĩa hàm
Định nghĩa hàm:
* Hàm không trả về giá trị:
Nếu hàm không trả lại giá trị (còn gọi là hàm kiểu void):
- kieudulieu: sử dụng từ khóa void
- Trong thân hàm có thể có khoặc không câu lệnh return
Nếu có thì sau return không có biểu thức
Trang 12Hàm có thể được gọi từ hàm khác hoặc từ chính bản thân nó
- Gọi hàm: để thực hiện việc gọi hàm, sử dụng tên của hàm được gọi và theo sau là các tham số thực tế được đặt trong
cặp dấu ngoặc đơn ( )
Cú pháp: Ten_ham(Ds_tham_so_thuc_te);
Trong đó: Ds_tham_so_thuc_te phân tách nhau bởi dấu phẩy
(,)
Trang 13}
main() // tính giá trị 2x 3 -5x 2 -4x + 1
{ float x ; double f ; cout << “x =” ; cin >> x;
f = 2* luythua(x,3) -5* luythua(x,2) -4*x + 1; }
Trang 14Ngôn ngữ lập trình C++
Biến và truyền tham số
- Phân loại biến:
+ Biến thường+ Biến con trỏ với dấu * trước tên biến
+ Biến tham chiếu: thực chất là một bí danh được gán cho một biến nào đó Lúc đó, chỗ nào xuất hiện biến thì cũng tương đương dùng bí danh và ngược lại
- Cú pháp khai báo biến tham chiếu:
Kieudulieu &ten_bien_tham_chieu=ten_bien_duoc_tham_chieu
Tác dụng: tạo ra một biến tham chiếu mới và cho nó tham
chiếu đến biến được tham chiếu (cùng kiểu) Khi đó, biến
tham chiếu còn được gọi là bí danh của biến được tham
chiếu
Trang 15Biến và truyền tham số
Ví dụ:
int a, b;
int &a1=a, &b1=b;
a=2; b=3;
cout<<"a= "<<a<<" b= "<<b<<endl;
cout<<"a1= "<<a1<<" b1= "<<b1<<endl;
cout<<a1 + b1<<endl;
cout<<a1++<<endl;
cout<<++a1<<endl;
Trang 16Ngôn ngữ lập trình C++
Biến và truyền tham số
Lưu ý:
- Biến tham chiếu phải được khởi tạo khi khai báo
- Mặc dù giống con trỏ nhưng không dùng được các phép toán trên con trỏ cho biến tham chiếu Nói chung chỉ nên dùng
trong truyền tham số cho hàm
Trang 17Biến và truyền tham số
+ Truyền theo tham trị
+ Truyền theo tham biến
+ Truyền theo tham trỏ
Trang 18Ngôn ngữ lập trình C++
Biến và truyền tham số
+ Truyền theo tham trị:
- Trong phương pháp nkày:
+ Các tham số hình thức (đối số) chỉ nhận giá trị vào cho chương trình con mà không trả kết quả về
+ Tham số hình thức được xem như là một biến cục bộ
của chương trình con và được cấp phát ô nhớ riêng
+ Các tham số thực tế là một biểu thức (một biến, một
hằng, một hàm, một biểu thức thực sự)
Trang 19Tham số hình thức Tham trị: biến cục bộ Tham trỏ: con trỏ Tham biến: biến tham chiếu
Tham số thực tế Tham trị: biểu thức (biến, hằng, hàm, ) Tham trỏ: một biến Chứa địa chỉ ô nhớ
Tham biến: biến tham chiếu
BT: 1->8 (trừ 4) cuối C6
sx nhanh, sp chọn
Trang 20+ Khi kết thúc: sự thay đổi giá trị của tham số hình thức
không làm ảnh hưởng đến giá trị của tham số thực tế
Trang 21Biến và truyền tham số
chương trình chính ta có các biến a, b đang chứa các giá trị
a=2, b=3 và biến f chưa có giá trị Để tính a b và gán giá trị tính
được cho f, ta có thể gọi f = luythua(a,b) Khi gặp lời gọi này,
chương trình sẽ tổ chức như sau:
- Tạo 2 biến mới có tên x và n Gán nội dung các ô nhớ này bằng các giá trị trong lời gọi, tức gán 2 cho x và 3 cho n
- Tới phần khai báo của hàm, chương trình tạo thêm
các biến kq và i
- Tiến hành tính toán (gán lại kết quả cho kq)
- Cuối cùng lấy kết quả trong kq gán cho ô nhớ f
- Kết thúc hàm quay về chương trình gọi
Trang 23Biến và truyền tham số
+ Truyền theo tham biến:
- Trong phương pháp này:
+ Tham số hình thức là tham số vào ra, do đó nó sẽ nhận giá trị vào cho chương trình con và trả về kết quả cho chương
Trang 24Ngôn ngữ lập trình C++
Biến và truyền tham số
+ Truyền theo tham biến:
void Hoanvi( int &x, int &y)
Trang 25Biến và truyền tham số
+ Truyền theo tham trỏ:
Trong phương pháp này:
- Tham số hình thức là tham số vào ra, do đó nó sẽ nhận giá trị vào cho chương trình con và trả về kết quả cho chương
Trang 26Ngôn ngữ lập trình C++
Biến và truyền tham số
+ Truyền theo tham trỏ:
void Hoanvi( int *p, int *q)
{
int t; // khai báo biến tạm t
t = *p ; // đặt giá trị của t bằng nội dung nơi p trỏ tới
*p = *q ; // thay nội dung nơi p trỏ bằng nội dung nơi q trỏ
*q = t ; // thay nội dung nơi q trỏ tới bằng nội dung của t
}
- Như vậy, nếu ta cho p trỏ tới biến x và q trỏ tới biến y thì hàm Hoanvi sẽ thực sự làm thay đổi nội dung của x, y chứ không phải của p, q
- Lúc này, lời gọi hàm sẽ là Hoanvi(&x, &y) (tức truyền địa chỉ
của x cho p, p trỏ tới x và tương tự q trỏ tới y)
Trang 27Khai báo hàm trùng tên
- Hàm trùng tên hay còn gọi là hàm chồng (overload) Đây là một kỹ thuật cho phép sử dụng cùng tên gọi cho các hàm
“giống nhau” nhưng xử lý trên các kiểu dữ liệu khác nhau hoặc trên số lượng dữ liệu khác nhau
int max( int a, int b) { return (a > b) ? a: b ; } float max( float a, float b) { return (a > b) ? a: b ; } char max( char a, char b) { return (a > b) ? a: b ; }
Khi đó, tùy thuộc vào giá trị của đối số trong lời gọi hàm để
chạy hàm thích hợp Chẳng hạn, max(3, 5), max(3.0, 5.0),
max(‘O’,‘K’), …
Trang 28Ngôn ngữ lập trình C++
Khai báo hàm trùng tên
- Như vậy, đặc điểm của các hàm trùng tên là trong danh sách đối của chúng phải có ít nhất một cặp đối khác kiểu nhau,
hoặc số lượng các đối khác nhau
- Tóm lại, điều kiện để các hàm có thể định nghĩa chồng là:
+ Số lượng các đối trong hàm là khác nhau+ Hoặc có ít nhất 1 đối có kiểu khác nhau giữa các hàm
Kỹ thuật chồng tên còn có thể áp dụng cả cho các toán tử: +, -,
*, /, …
Trang 29Hàm và mảng dữ liệu
- Hàm làm việc với mảng cần có 2 thông tin
+ Điạ chỉ bắt đầu của mảng (địa chỉ cơ sở)+ Số phần tử xử lý trong mảng
- Truyền mảng một chiều cho hàm
- Truyền mảng hai chiều cho hàm
Trang 30- Ta có 2 cách khai báo đối số
mảng nhưng không chỉ ra số phần tử Chẳng hạn, int x[];
float A[];
hạn:
int *p; float *q;
Trang 31{ int a[100] ; // mảng a chứa tối đa 100 phần tử
nhap(a,7); // vào 7 phần tử đầu tiên cho a
Trang 32- Ta cũng có 2 cách khai báo đối số
Trang 33}
Trang 34Ngôn ngữ lập trình C++
Hàm và cấu trúc
Đối số của hàm là cấu trúc:
Một cấu trúc có thể được sử dụng để làm đối số của hàm dưới các dạng sau đây:
- Là một biến cấu trúc, khi đó đối số là một cấu trúc
- Là một con trỏ cấu trúc, đối số là địa chỉ của một cấu trúc
- Là một tham chiếu cấu trúc, đối số là một cấu trúc
- Là một mảng cấu trúc hoặc con trỏ mảng, đối số là tên mảng cấu trúc
Trang 35Hàm và cấu trúc
- Giá trị của hàm là cấu trúc:
Cũng tương tự như các kiểu dữ liệu cơ bản, giá trị trả lại của một hàm cũng có thể là các cấu trúc dưới các dạng sau:
- Là một biến cấu trúc
- Là một con trỏ cấu trúc
- Là một tham chiếu cấu trúc
Trang 36Sophuc Cong(Sophuc x, Sophuc y) {
float thuc;
float ao;
};
Trang 38cout << "x - y = " ; In(Tru(x,y)) ; }
Trang 39- Khái niệm
- Đặc điểm
Đệ quy
Trang 40Ngôn ngữ lập trình C++
Khái niệm đệ quy
- Đệ quy là một kỹ thuật cho phép trong thân một hàm nào đó
có lời gọi đến chính nó
- Cần phải tránh trường hợp trình tự vô hạn của việc gọi hàm (đệ quy vô hạn)
Trang 41Đặc điểm của bài toán đệ quy
- Giải bài toán bằng thuật toán đệ quy là đưa bài toán hiện tại
về một bài toán cùng loại, cùng tính chất nhưng ở cấp độ thấp hơn
- Quá trình này tiếp tục cho đến lúc bài toán được đưa về một cấp độ mà tại đó có thể giải được
- Từ kết quả ở cấp độ này, ta sẽ lần ngược để giải được bài toán ở cấp độ cao hơn cho đến lúc giải được bài toán ở cấp
độ ban đầu
Trang 42Ngôn ngữ lập trình C++
Đặc điểm của bài toán đệ quy
- Đệ quy có sự liên hệ rất chặt chẽ với quy nạp toán học
- Đệ quy mạnh ở điểm nó có thể định nghĩa một tập vô hạn
các đối tượng chỉ bằng một số hữu hạn các mệnh đề
- Ưu thế của thuật toán đệ quy: chỉ cần giải bài toán tại một số trường hợp đặc biệt nào đó, các trường hợp khác được xác định thông qua trường hợp đặc biệt
* Mọi thuật toán đệ quy đều gồm hai phần:
- Phần cơ sở (trường hợp suy biến): Là các trường hợp không cần thực hiện lại thuật toán
- Phần đệ quy: Là phần trong thuật toán có yêu cầu gọi
đệ quy
Trang 45Đệ quy
Ví dụ 3:
Viết hàm tính xn bằng đệ quy với 10=1
int Luythua(int x, int n)
Trang 479-19 (-12, 17, 18)
Trang 48Ngôn ngữ lập trình C++
Tổ chức chương trình
Các loại biến và tác dụng của nó:
+ Biến cục bộ (local variable): là các biến được khai báo
trong thân của hàm và nó chỉ có tác dụng trong hàm chứa nó
Kể cả các biến được khai báp trong hàm main() thì cũng chỉ
có tác dụng trong hàm đó mà thôi
- Biến cục bộ chỉ tồn tại trong thời gian hàm chứa nó còn thực thi Nghĩa là được cấp phát khi hàm chứa nó được gọi tới
(hoạt động) và hủy bỏ khi hàm kết thúc
- Đối số của các hàm cũng được xem như là biến cục bộ
- Ta có thể khai báo các biến giống nhau ở các hàm khác
nhau
Trang 49Tổ chức chương trình
Các loại biến và tác dụng của nó:
+ Biến toàn cục (global variable): là các biến được khai báo bên ngoài tất cả các hàm Nó thường được khai báo ở đầu
chương trình (trước hàm main)
- Biến toàn cục tồn tại trong suốt quá trình thực thi chương
trình
- Tất cả các hàm đều sử dụng được các biến này nếu trong
hàm đó không có biến khai báo trùng tên
- Một hàm nếu có biến trùng tên với biến ngoài thì biến ngoài
bị che đối với hàm này Có nghĩa nếu i được khai báo như một biến ngoài và ngoài ra trong một hàm nào đó cũng có biến i,
Trang 50khai báo chúng như biến ngoài
Tóm lại, nguyên tắc tổng quát nhất là cố gắng tạo hàm một
cách độc lập, khép kín, không chịu ảnh hưởng của các hàm khác và không gây ảnh hưởng đến hoạt động của các hàm
khác đến mức có thể
Trang 51Tổ chức chương trình
Các chỉ thị tiền xử lý:
- Chỉ thị bao hàm tệp #include
Cho phép tham chiếu tới nội dung các tệp đã có (tệp tiêu đề)
và ghép nội dung các tệp này vào chương trình trước khi dịch.Việc khai báo các tệp này được thực hiện theo cú pháp:
#include<tep>
Hoặc #include “duong_dan\tep”
Ví dụ:
#include<iostream>
Trang 52Cú pháp: #define macroName StringValue
Tác dụng: trước khi dịch, bộ tiền xử lý sẽ tìm trong chương
trình và thay thế bất kỳ vị trí xuất hiện nào của macroName bởi StringName
Macro thường được sử dụng để định nghĩa các hằng hoặc
thay cụm từ này thành một cụm từ khác dễ nhớ hơn
Trang 53- Max sẽ được thay bởi 10
- true sẽ được thay bởi 1
begin int ok, i;
Trang 54- Ngoài việc chỉ thị #define cho phép thay macroName bởi
một xâu ký tự bất kỳ, nó còn có thể được viết dưới dạng có đối
Trang 559-19 (-12, 17, 18)
Trang 563 Sử dụng hàm, viết chương trình kiểm tra một năm nhập vào có phải là năm nhuận hay không? Sau đó hiển thị lên màn hình tất cả các năm nhuận nằm trong đoạn [1000,
2000]
4 Sử dụng hàm, viết chương trình xóa dấu cách đầu tiên trong xâu Sau đó xóa tất cả các dấu cách trong xâu.
Trang 57Bài tập thực hành
5 Sử dụng hàm, viết chương trình kiểm tra một số bất kỳ nhập vào từ bàn phím có phải là số hoàn hảo hay không? Sau đó hiển tìm và hiển thị lên màn hình tất cả các số hoàn hảo <= n Với n bất kỳ được nhập vào từ bàn phím Trong
đó, số hoàn hảo là số bằng tổng tất cả các ước của nó trừ
Trang 589 Sử dụng hàm đệ quy, viết chương trình tính số Fibonacci thứ
n Sau đó tính và hiển thị kết quả tổng m số Fibonacci đầu tiên Với m nguyên dương được nhập vào từ bàn phím Trong đó, số Fibonacci được định nghĩa như sau:
1 nếu n = 1 hoặc n = 2 Fibonaci(n) =
Fibonaci(n-1) + Fibonaci(n-2) nếu n>2
10 Sử dụng hàm đệ quy, viết chương trình tìm ƯCLN của 2
số nguyên dương x, y theo công thức sau:
UCLN(x,y-x) nếu x < y
Trang 59Bài tập thực hành
11 Sử dụng hàm đệ quy, viết chương trình tìm ƯCLN của
2 số nguyên dương x, y theo công thức sau:
UCLN(x,y) = x nếu y = 0
UCLN(y, x%y) nếu y khác 0
12 Viết chương trình nhập vào một số bất kỳ rồi hiển thị ra màn hình theo thứ tự ngược lại Chẳng hạn, số nhập vào là
1234 thì kết quả xuất ra là 4321
13 Sử dụng hàm đệ quy, viết chương trình tính x lũy thừa
n Với x là số thực, n là số nguyên được nhập vào từ bàn phím.
14 Xây dựng hàm đệ quy tính S(n) = (2n)! với n được
Trang 60Ngôn ngữ lập trình C++
Bài tập thực hành
15 Sử dụng hàm đệ quy, viết chương trình tính tổng P(n) =
13 + 23 + … + n3 với n được nhập vào từ bàn phím.
16 Viết chương trình tính tổ hợp chập k của n với k, n
nguyên dương được nhập vào từ bàn phím theo công thức sau: n!/(k!*(n-k)!)
17 Xây dựng hàm đệ quy đếm số chữ số có trong một số nguyên bất kỳ được nhập vào từ bàn phím
18 Viết chương trình tìm tất cả các số tự nhiên có 4 chữ số
mà trong đó mỗi số không có 2 chữ số nào giống nhau.
19 Sử dụng hàm đệ quy viết chương trình tính tổng S(n)¬
= 1! + 2! + 3! + … + n! Với n nguyên dương được nhập vào từ bàn phím.