Ngôn ngữ lập trình - Chapter 6 (HUST) Thầy Vũ Song Tùng

LI
lienhejb
0 lượt tải
25
0

Nội dung tài liệu

Trang 1

goupee.vn goupee.com Lập trình Chương6: Lập trình tổng quát cuu duong than cong . com fb.com/goupee.vn 2/10/2017 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 2

goupee.vnNội dung goupee.com  6.1 Khuân mẫu hàm (Function template)  6.2 Khuân mẫu lớp  6.3 Thuật toán tổng quát cuu duong than cong . com fb.com/goupee.vn Chương 5: Lập trình tổng quát 2 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 3

goupee.vn6.1Khuân mẫu hàm goupee.com  Ví dụ hàm tìm giá trị lớn nhất a. Tìm max hai số nguyên int max(const int &a, const int &b){ return (a > b)? a: b; } b. Tìm max hai số thực float max(const float &a, const float &b){ return (a > b)? a: b; }  Nhận xét: Các hàm tìm max của hai số chỉ khác nhau về kiểu dữ liệu, thuật toán giống nhau.cuu duong than cong . com  Tương tự như vậy có rất nhiều hàm chỉ khác nhau về kiểu dữ liệu, không khác về thuật toán  Giải pháp: tổng quát hóa các hàm chỉ khác nhau về kiểu  khuôn mẫu hàm fb.com/goupee.vn Chương 5: Lập trình tổng quát 3 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 4

goupee.vn Ví dụ tổng quát hóa hàm max goupee.com Tham số khuôn mẫu template <class T> T max(const T &a,const T &b){ Sử dụng từ khóa return (a > b)? a: b; class hoặc typename để khai báo tham số } khuôn mẫu  Khuôn mẫu hàm inline template <typename T> inline T max(const T &a,const T &b) { return (a > b)? a : b; }  Sử dụng Compiler sẽ tạo một hàm theo khuôn mẫu có dạng int max(const int&, const int&) int max(5,7); cuu duong than cong . com fb.com/goupee.vn Chương 5: Lập trình tổng quát 4 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 5

goupee.vn goupee.com  Ví dụ sử dụng void main() { int i1 = 1, i2 = 5; double d1 = 1.0, d2 = 2.0; double d = max(d1,d2); // max<double>(double,double) char c = max('c','a'); // max<char>(char, char) d = max(i1,d1); // error: ambiguous c = max('c',i1); // error: ambiguous d = max<double>(d1,i1); // OK: explicit qualification c = max<int>('c',i1); // OK: explicit qualification }  Áp dụng cho complex? class complex{ void main{ double real, imag; complex c1(1.1,2.0); public: complex c2(2.0,2.2); complex(double r=0,int complex c = max(c1,c2); i=0); cuu duong than cong . com}; double get_real(); Lỗi, vì lớp complex trên chưa định void set_real(double); nghĩa phép so sánh > sử dụng trong double get_imag(); hàm khuôn mẫu max void set_imag(double); }; fb.com/goupee.vn Chương 5: Lập trình tổng quát 5 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 6

goupee.vn Giải pháp cho trường hợp trên là định nghĩa toán tửgoupee.com so sánh lớn hơn cho lớp complex.  Một khuôn mẫu hàm cũng có thể được nạp chồng bởi hàm cùng tên hoặc bởi một khuôn mẫu hàm cùng tên (khác số lượng các tham số hoặc kiểu của ít nhất một tham số) – Hàm cùng tên để thực hiện cho các thuật toán đặc biệt. (Ví dụ, hàm max giữa hai chuỗi ký tự có thuật toán thực hiện khác với tìm max của hai số int hoặc double) – Khuôn mẫu hàm cùng tên template <class T> T max(T a, T b, T c) {...} template <class T> T max(T* a, int n) {...} nhưng không được như thế này: template cuu duong than cong . com<class T> T max(T a, T b, T c) {...} template <class X> X max(X a, X b, X c) {...} fb.com/goupee.vn Chương 5: Lập trình tổng quát 6 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 7

goupee.vn goupee.com  Tham số khuôn mẫu hàm có thể có hơn một tham số kiểu, ví dụ: template <class A, class B> void swap(A& a, B& b){…}  Ví dụ: template <class A,class B> void swap( A &a, B &b){ A temp = a; a = b; //đúng khi b tương thích với a b = temp; //đúng khi temp tương thích với b } void main(){ int a = 5; doublecuu duong than cong . comb = 10.2; swap(a,b); //swap<int,double>(int,double) swap(b,a); //swap<double,int>(double,int) } fb.com/goupee.vn Chương 5: Lập trình tổng quát 7 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 8

goupee.vnTóm lược goupee.com  Khi sử dụng compiler cần biết mã nguồn thực hiện khuôn mẫu hàm, do vậy khai báo và định nghĩa khuôn mẫu hàm nên để ở header file  sử dụng template sẽ công khai hết phần thực hiện  Mã hàm khuôn mẫu chỉ được thực sự sinh ra khi và chỉ khi khuôn mẫu hàm được sử dụng với kiểu cụ thể  Một khuôn mẫu hàm được sử dụng nhiều lần với các kiểu khác nhau thì nhiều hàm khuôn mẫu được tạo ra  Một khuôn mẫu hàm được sử dụng nhiều lần với cùng một kiểu, thì chỉ có một hàm khuôn mẫu đượccuu duong than cong . com tạo fb.com/goupee.vn Chương 5: Lập trình tổng quát 8 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 9

goupee.vnƯu/nhược điểm của khuôn mẫu hàmgoupee.com  Ưu điểm – Tiết kiệm được mã nguồn – Tính mở: nâng cao tính sử dụng lại, thuật toán viết một lần sử dụng vô số lần – Cho phép xây dựng các thư viên chuẩn rất mạnh như các thư viện thuật toán thông dụng: sao chép, tìm kiếm, sắp xếp, lựa chọn,…  Nhược điểm – Không che giấu được mã nguồn thực thi, vì compiler phải biết mã nguồn khi biên dịch – Theo dõi, tìm kiếm lỗi phức tạp, đôi khi lỗi nằm ở phần sử dụng nhưng compiler lại báo trong phần định nghĩa khuôncuu duong than cong . com mẫu hàm fb.com/goupee.vn Chương 5: Lập trình tổng quát 9 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 10

goupee.vn6.2Khuôn mẫu lớp goupee.com  Nghiên cứu lớp số phức #include <iostream.h> class IntComplex{ int real,imag; public: Complex(int r = 0, int i =0): real(r),imag(i) {} int get_real() const { return real; } int get_imag() const { return imag; } Complex operator+(const Complex& b) const { Complex z(real + b.real, imag + b.image); return z; } Complex operator-(const Complex& b) const { return Complex(real - b.real, imag - b.imag); } cuu duong than cong . com ... }; fb.com/goupee.vn Chương 5: Lập trình tổng quát 10 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 11

goupee.vn goupee.com class DoubleComplex{ double real,imag; public: Complex(double r = 0, double i =0): real(r),imag(i) {} double get_real() const { return real; } double get_imag() const { return imag; } Complex operator+(const Complex& b) const { Complex z(real + b.real, imag + b.image); return z; } Complex operator-(const Complex& b) const { return Complex(real - b.real, imag - b.imag); } ... };  Hai lớp số phức trên khác nhau gì? Giống nhau gì?cuu duong than cong . com fb.com/goupee.vn Chương 5: Lập trình tổng quát 11 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 12

goupee.vn goupee.com  Tương tự nhu vậy, trong thực tế có rất nhiều cấu trúc dữ liệu chỉ khác nhau về kiểu dữ liệu còn hoàn toàn giống về phép toán, ví dụ như vector, list, complex,…  Để tiết kiệm mã nguồn thực thi  tổng quát hóa kiểu dữ liệu cho lớp template <class T> class Complex{ T real,imag; public: Complex(T r = 0, T i =0): real(r),imag(i) {} T get_real() const { return real; } T get_imag() const { return imag; } Complex operator+(const Complex& b) const { Complex z(real + b.real, imag + b.image); return z; } cuu duong than cong . com Complex operator-(const Complex& b) const; ... }; fb.com/goupee.vn Chương 5: Lập trình tổng quát 12 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 13

goupee.vn goupee.com  Định nghĩa hàm thành viên bên ngoài khai báo lớp template <class T> Complex<T>::Complex operator-(const Complex<T>& b) const { return Complex<T>(real - b.real, imag - b.imag); }  Sử dụng void main{ Complex<int> c1(1,1), c2(2,3); Complex<int> c3 = c1+c2; Complex<double> c4(1.0,2.0), c5(3.0,5.0); Complex<double> c6 = c4 + c5; }; cuu duong than cong . com fb.com/goupee.vn Chương 5: Lập trình tổng quát 13 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 14

goupee.vnTham số khuôn mẫu goupee.com  Tham số khuôn mẫu có thể là hằng hoặc kiểu (để làm tham số mặc định) template <class T = int, class N = 10> class Array{ T data[N]; public: ... Tham số mặc định };  Sử dụng void main(){ Array<int,10> a; Giống nhau Array<int>Array<> cuu duong than cong . comb;c; } fb.com/goupee.vn Chương 5: Lập trình tổng quát 14 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 15

goupee.vnBài tập goupee.com  Xây dựng một khuôn mẫu hàm cho phép tìm giá trị lớn nhất/hoặc nhỏ nhất trong một mảng  Tổng quát hóa kiểu dữ liệu cho lớp array, thực hiện các hàm thành viên cần thiết để có thể – Khai báo và khởi tạo giá trị ban đầu – Hủy bộ nhớ khi không còn sử dụng – Thực hiện các phép toán +,-, +=, -=,… cuu duong than cong . com fb.com/goupee.vn Chương 5: Lập trình tổng quát 15 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 16

goupee.vn6.3Thuật toán tổng quát goupee.com  Ví dụ: hãy viết hàm sắp xếp các phần tử của một mảng theo thứ tự từ nhỏ đến lớn void sort(int *p, int n){ for(int i = 0; i < n-1; i++) for(int j = n-1; j > i; --j) if(p[j] < p[j-1]) swap(p[j], p[j-1]); } void swap(int &a, int &b){ int t = a; a = b; b = t; } cuu duong than cong . com fb.com/goupee.vn Chương 5: Lập trình tổng quát 16 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 17

goupee.vn 1. Tổng quát hóa kiểu dữ liệu của các phần tử goupee.com template <class T> void sort(T *p, int n){ for(int i = 0; i < n-1; i++) for(int j = n-1; j > i; --j) if(p[j] < p[j-1]) swap(p[j], p[j-1]); } void swap(T &a, T &b){ T t = a; a = b; b = t; }  Thuật toán trên áp dụng cho nhiều kiểu dữ liệu có định nghĩa phép so sánh nhỏ hơn Int p[100]; cuu duong than cong . com sort(p,100); //OK char p2[100]; sort(p2,100); //OK complex<double> p3[100]; sort(p3,100) //Lỗi, chỉ áp dụng được khi lớp complex định //nghĩa phép fb.com/goupee.vnso sánh nhỏ hơn Chương 5: Lập trình tổng quát 17 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 18

 Câu hỏi: làm thế nào để ta có thể sắp xếp lại từ lớn goupee.vn goupee.com đến nhỏ mà không cần phải viết lại hàm  Giải pháp: cho thêm tham biến vào khai báo hàm enum comparetype {less, greater, abs_less, abs_greater}; template <class T> void sort(T *p, int n,comparetype c){ for(int i = 0; i < n-1; i++) for(int j = n-1; j > i; --j) switch(c){ case less: if(p[j] < p[j-1]) swap(p[j], p[j-1]); break; case greater: if(p[j] > p[j-1]) swap(p[j], p[j-1]); break; case abs_less: if(abs(p[j]) < abs(p[j-1]) cuu duong than cong . comswap(p[j], p[j-1]); break; case abs_greater: if(abs(p[j]) > abs(p[j-1])) swap(p[j], p[j-1]); break; } } fb.com/goupee.vn Chương 5: Lập trình tổng quát 18 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 19

goupee.vn Nhược điểm: goupee.com – Hiệu quả không cao – Tốc độ chậm – Không có tính năng mở: ví dụ nếu muốn só sánh số phức theo phần thực thì không dùng được cách trên  Giải pháp: tổng quát hóa phép toán template <class T, class Compare> void sort(T *p, int n, Compare comp){ for(int i = 0; i < n-1; i++) for(int j = n-1; j > i; --j) if(comp(p[j], p[j-1])) swap(p[j], p[j-1]); }  Kiểu Compare có thể là – Một hàm cuu duong than cong . com – Một đối tượng thuộc lớp có định nghĩa lại toán tử gọi hàm fb.com/goupee.vn Chương 5: Lập trình tổng quát 19 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Trang 20

goupee.vn Kiểu Compare là một hàm goupee.com template <class T> inline bool less(const T &a, const T &b){ return a < b; //return operator<(a,b) } template <class T> inline bool greater(const T &a, const T &b){ return a > b; //return operator>(a,b) } – Sử dụng int v[100]; double d[100]; Một hàm sort(v,100,less<int>); sort(d,100,greater<double>) cuu duong than cong . com fb.com/goupee.vn Chương 5: Lập trình tổng quát 20 CuuDuongThanCong.com https://fb.com/tailieudientucntt

Hiển thị 20 trang đầu. Tải tài liệu để xem đầy đủ.

Bình luận (0)

Đăng nhập để tham gia bình luận

Chưa có bình luận nào. Hãy là người đầu tiên!