26
Ni dung trình bày • Tham chiếu và hàm có nhiu giá trtrv. • Hàm có đốismc định • Quá ti hàm • Hàm inline • Hàm đệ quy

Bai Giang 6

  • Upload
    nbb3i

  • View
    1.689

  • Download
    1

Embed Size (px)

Citation preview

Page 1: Bai Giang 6

Nội dung trình bày

• Tham chiếu và hàm có nhiều giá trị trả về.• Hàm có đối số mặc định • Quá tải hàm• Hàm inline• Hàm đệ quy

Page 2: Bai Giang 6

Tham chiếu là gì ?

• Tham chiếu là một bí danh của biến khác.• Khi tạo ra một tham chiếu, gán nó lên một

biến khác thì tham chiếu hoạt động nhưchính biến đã gán đến nó.

• Cú pháp:<Kiểu giá trị> &Tên tham chiếu = Biến đã tồn tại;

• Ví dụ:int a = 6;int &b = a;

Page 3: Bai Giang 6

Tham chiếu là gì ?

• Tham chiếu tương tự trong thực tế nhưmột người có thể được gán một bí danhkhác (một người có nhiều tên gọi khácnhau).

• Trong mô hình bộ nhớ máy tính thì địa chỉcủa tham chiếu chính là địa chỉ của biếnmà nó tham chiếu đến.

Page 4: Bai Giang 6

Tham chiếu là gì ?

• Ta không thể gán thêm một lần nữa têncủa tham chiếu cho một biến khác.int a = 5;int b = 8;int &c = a;&c = b; // Lỗi tại đây

• Kiểu dữ liệu của tham chiếu phải trùng vớikiểu dữ liệu của biến mà nó tham chiếuđến.

Page 5: Bai Giang 6

Tham chiếu là gì ?

• Ta có thể tham chiếu đến một bí danh(cũng là một tham chiếu)int a = 5;int &b = a;int &c = b;

• Ta chỉ được tham chiếu đến một biến cụthể chứ không được tham chiếu đến mộtkiểu dữ liệu.int &x = int; // Lỗi tại đây

Page 6: Bai Giang 6

Truyền tham chiếu cho hàm• Nhắc lại về truyền tham trị:

– Đối số truyền cho hàm là các tham trị– Ví dụ:

void Doicho(int x, int y){

int tam;tam=x;x=y;y=tam;

}– Giá trị của các tham số hình thức x, y chỉ được đổi

chỗ cho nhau trong pham vi của hàm. Nhưng giá trịcác tham số thực sẽ không đổi chỗ được cho nhau.

Page 7: Bai Giang 6

Truyền tham chiếu cho hàm• Truyền tham chiếu cho hàm:

– Để các tham số thực có thể đổi chỗ được cho nhau, ta thay cácđối số truyền cho hàm là các tham trị.

– Ví dụ:void Doicho(int &x, int &y){

int tam;tam=x;x=y;y=tam;

}– Khi goi hàm, biến được truyền trưc tiếp, 2 giá trị x và y thực sựđược đổi chỗ cho nhau

int a = 5, b = 8;Doicho(a, b);

Page 8: Bai Giang 6

Hàm trả về nhiều giá trị

• Ta đã học hàm trả về một giá trị, đó chínhlà giá trị trả về cho hàm (thông qua câulệnh return)

• Chúng ta sẽ sử dụng kỹ thuật truyền thamchiếu để thay đổi các biến ngoài ngay bêntrong hàm, và như vậy ta có thể coi hàm“trả về” nhiều giá trị.

Page 9: Bai Giang 6

Hàm trả về nhiều giá trị• Ví dụ:

– Xây dựng hàm trả về giá trị của diện tích và chu vi hình tròn với đầu vào là bán kính r

void HinhTron(float r, float &dientich, float &chuvi){

dientich = 3.14 * r * r;chuvi = 2 * 3.14 * r;

}– Khi gọi hàm phải truyền biến vào tham chiếu để nhận

giá trị trả vềHinhTron(r, dt, cv);

Page 10: Bai Giang 6

Hàm có đối số mặc định

• Hàm có đối số mặc định là hàm chứa đốisố mà giá trị của đối số được xác địnhtrước ngay ở phần khai báo hàm (đối sốmặc định)– Ví dụ:

void f (int x = 1){

….}

Page 11: Bai Giang 6

Hàm có đối số mặc định

• Nếu ta không truyền tham số thực vào chohàm tại đối số có giá trị mặc định thì đối sốtại vị ví trí đó sẽ tự động nhận giá trị mặcđịnh làm giá trị của đối số.– Ví dụ:

Nếu ta gọi hàm như sau: f(5); thì x sẽ nhận giá trị 5Nếu ta gọi hàm như sau: f(); thì x sẽ nhận giá trị 1

Page 12: Bai Giang 6

Hàm có đối số mặc định

• Các đối mặc định phải là các đối số cuốicùng tính từ trái sang phải.– Ví dụ:

• Các hàm có đối số mặc định sau là đúng:int tinhToan(int x, int y = 7);void soThuc(float x, int y = 12, float z = 1.1);

• Các hàm có đối số mặc định sau là sai:int tinhToan(int x = 6, int y);void soThuc(float x = 2.3, int y = 12, float z);

Page 13: Bai Giang 6

Quá tải hàm (Overloading Function)

• Trong ngôn ngữ C và các ngôn ngữ khác, tathấy rằng mỗi hàm đảm nhận một chức năngnào đó đều có một tên riêng biệt.

• Tuy nhiên có nhiều hàm có cùng một ý nghĩanhưng lại có tên gọi nhau do giá trị đầu vào hay giá trị trả về của hàm có kiểu dữ liệu khác nhau.– Ví dụ: Trong C có 3 hàm trả về giá trị tuyệt đối:

int abs(int i);

long labs(long l);

double fabs(double d);

Page 14: Bai Giang 6

Quá tải hàm

• C++ cho phép tạo ra các hàm khác nhaucó tên trùng nhau. Đây chính là quá tảihàm.

• Ví dụ:int abs(int i);long abs(long i);double abs(double d);int Tong(int a, int b);int Tong(int a, int b, int c);long Tong(long a, long b);

Page 15: Bai Giang 6

Các đặc điểm của quá tải hàm

• Các hàm quá tải có những đặc điểm sau:– Số lượng tham số của các hàm quá tải có thể

khác nhau. Nếu số lượng tham số trùng nhauthì kiểu dữ liệu của các tham số phải khácnhau.

– Giá trị trả về của các hàm quá tải có thể trùnghoặc khác nhau miễn là tham số phải khácnhau.

Page 16: Bai Giang 6

Các đặc điểm của quá tải hàm

• Các khai báo sau sẽ bị báo lỗi khi biêndịch:int Tong(int a, int b);long Tong(int a, int b);

• Các khai báo sau sẽ không bị báo lỗi khibiên dịch:long Tong(int a, float b);long Tong(int a, int b);float Tong(int a);

Page 17: Bai Giang 6

Các đặc điểm của quá tải hàm

• Chú ý: Cần đảm bảo các kiểu khác nhaucủa các tham số của các hàm quá tải làcác kiểu khác nhau thực sự

• Ví dụ: Kiểu được typedef thật ra chỉ là mộtbiệt danh của một kiểu đã có, vì vậy đoạnchương trình sau sẽ bị sai

typedef int Songuyen;int Tang(int a);int Tang(Songuyen a);

Page 18: Bai Giang 6

Hàm inline

• Khi định nghĩa một hàm, trình biên dịch chỉtạo ra một bộ chỉ thị trong bộ nhớ. Khi hàm được gọi, chương trình sẽ tự động chuyển quyền điều khiển đến đoạn mã chứa bộ chỉ thị của hàm.

• Các thực hiện này cho phép tiết kiệm bộnhớ khi thực hiện chương trình nhưng lại làm giảm tốc độ thực hiện chương trình.

Page 19: Bai Giang 6

Hàm inline

• Ta sử dụng từ khoá inline khi khai báo hàm đểtrình biên dịch không tạo ra một bộ chỉ thị đối với hàm. Thay vào đó tại mỗi nơi trong chương trình có lời gọi hàm, trình biên dịch sẽ chèn đoạn mã của hàm vào ngay chỗ đó.

• Cách sử dụng từ khoá inline cho phép tăng tốc độ thực hiện chương trình, nhưng lại chiếm không gian bộ nhớ nhiều hơn, do đó ta chỉ nên sử dụng từ khoá inline đối với các hàm không lớn lắm.

Page 20: Bai Giang 6

Hàm inline

• Ví dụ:inline double cube(doule side){

return side * side * side;}void main(){

double sideValue = 4;cout << cude(sideValue) << endl;

}

Page 21: Bai Giang 6

Đệ quy

• Đệ quy (Recursion) là một phương phápdùng trong các chương trình máy tínhtrong đó có một hàm tự gọi đến chính nó.

Page 22: Bai Giang 6

Khái niệm hình thức về đệ quy• Trong toán học và khoa học máy tính, các tính chất

(hoặc cấu trúc) được gọi là đệ quy nếu trong đó một lớpcác đối tượng hoặc phương pháp được xác định bằngviệc xác định một số rất ít các trường hợp hoặc phươngpháp đơn giản (thông thường chỉ một) và sau đó xácđịnh quy tắc đưa các trường hợp phức tạp về cáctrường hợp đơn giản.

• Chẳng hạn, định nghĩa sau là định nghĩa đệ quy của tổtiên:– Bố mẹ của một người là tổ tiên của người ấy ('trường hợp cơ

bản); – Bố mẹ của tổ tiên một người bất kỳ là tổ tiên của người ấy (“

bước đệ quy).

Page 23: Bai Giang 6

Định nghĩa theo đệ quy

• Một khái niệm X được định nghĩa theo đệqui nếu trong định nghĩa X có sử dụngngay chính khái niệm X.

• Ví dụ:– Định nghĩa số Số tự nhiên

• 0 là một số tự nhiên. • n là số tự nhiên nếu n - 1 là số tự nhiên.

– Định nghĩa Hàm giai thừa n! • 0! = 1 • Nếu n > 0 thì n! = n(n - 1)!

Page 24: Bai Giang 6

Hàm đệ quy

• Một hàm được gọi là đệ quy nếu trong quá trìnhthực hiện nó có phần phải gọi đến chính nó.

• Cấu trúc chính của một hàm đệ quy– Một hàm đệ quy về cơ bản gồm hai phần:

• Phần cơ sở: chứa các tác động của hàm với một số giá trị cụthể ban đầu của tham số.

• Phần đệ quy: Định nghĩa tác động cần được thực hiện chogiá trị hiện thời của các tham số bằng các tác động đã đượcđịnh nghĩa trước đây với kích thước tham số nhỏ hơn.

Page 25: Bai Giang 6

Hàm đệ quy

• Ví dụ: Xây dựng hàm đệ quy tính n!long giaiThua(int n){

if (n == 1)return 1;

elsereturn n * giaiThua(n - 1);

}

Page 26: Bai Giang 6

Hàm đệ quy• Qui trình thực hiện: Trong ví dụ trên, qui trình thực hiện như sau:

Khi có lệnh gọi hàm, chẳng hạn: – x = giaiThua(3);

thì máy sẽ ghi nhớ là: – giaiThua(3) := 3 * giaiThua (2); và đi tính giaiThua (2)

kế tiếp máy lại ghi nhớ: – giaiThua(2) := 2 * giaiThua (1); và đi tính giaiThua (1)

Theo định nghĩa của hàm thì: – giaiThua(1) := 1;

Máy sẽ quay ngược lại: – giaiThua(2) := 2 * 1; cho kết quả là 2

Tiếp tục: – giaiThua(3) := 3 * 2; cho kết quả là 6

Như vậy kết quả cuối cùng trả về là 6. Ta có: 3! = 6.