Bài giảng Lập trình chương 6 trang bị cho người học những kiến thức cơ bản về lập trình tổng quát như: Khuôn mẫu hàm (function template), khuân mẫu lớp, thuật toán tổng quát. Mời các bạn cùng tham khảo.
.c om an co ng Lập trình cu u du o ng th Chương 6: Lập trình tổng quát 2/10/2017 CuuDuongThanCong.com https://fb.com/tailieudientucntt Nội dung cu u du o ng th an co ng c om 6.1 Khuân mẫu hàm (Function template) 6.2 Khuân mẫu lớp 6.3 Thuật tốn tổng qt Chương 5: Lập trình tổng qt CuuDuongThanCong.com https://fb.com/tailieudientucntt 6.1 Khuân mẫu hàm c om Ví dụ hàm tìm giá trị lớn a Tìm max hai số nguyên int max(const int &a, const int &b){ an co } ng return (a > b)? a: b; th b Tìm max hai số thực ng float max(const float &a, const float &b){ } du o return (a > b)? a: b; Nhận xét: Các hàm tìm max hai số khác kiểu liệu, thuật tốn giống Tương tự có nhiều hàm khác kiểu liệu, khơng khác thuật tốn Giải pháp: tổng qt hóa hàm khác kiểu khuôn mẫu hàm cu u Chương 5: Lập trình tổng qt CuuDuongThanCong.com https://fb.com/tailieudientucntt Ví dụ tổng qt hóa hàm max Tham số khuôn mẫu template T max(const T &a,const T &b){ c om Sử dụng từ khóa class typename để khai báo tham số khn mẫu return (a > b)? a: b; ng } co Khuôn mẫu hàm inline du o Sử dụng ng th an template inline T max(const T &a,const T &b) { return (a > b)? a : b; } cu u int max(5,7); Compiler tạo hàm theo khn mẫu có dạng int max(const int&, const int&) Chương 5: Lập trình tổng quát CuuDuongThanCong.com https://fb.com/tailieudientucntt Ví dụ sử dụng ng th Áp dụng cho complex? an co ng c om void main() { int i1 = 1, i2 = 5; double d1 = 1.0, d2 = 2.0; double d = max(d1,d2); // max(double,double) char c = max('c','a'); // max(char, char) d = max(i1,d1); // error: ambiguous c = max('c',i1); // error: ambiguous d = max(d1,i1); // OK: explicit qualification c = max('c',i1); // OK: explicit qualification } cu u du o class complex{ double real, imag; public: complex(double r=0,int i=0); double get_real(); void set_real(double); double get_imag(); void set_imag(double); }; Chương 5: Lập trình tổng quát CuuDuongThanCong.com void main{ complex c1(1.1,2.0); complex c2(2.0,2.2); complex c = max(c1,c2); }; Lỗi, lớp complex chưa định nghĩa phép so sánh > sử dụng hàm khuôn mẫu max https://fb.com/tailieudientucntt Giải pháp cho trường hợp định nghĩa toán tử so sánh lớn cho lớp complex ng c om Một khuôn mẫu hàm nạp chồng hàm tên khuôn mẫu hàm tên (khác số lượng tham số kiểu tham số) ng th an co – Hàm tên để thực cho thuật toán đặc biệt (Ví dụ, hàm max hai chuỗi ký tự có thuật tốn thực khác với tìm max hai số int double) – Khuôn mẫu hàm tên du o template T max(T a, T b, T c) template T max(T* a, int n) { } { } u không này: { } template X max(X a, X b, X c) { } cu template T max(T a, T b, T c) Chương 5: Lập trình tổng quát CuuDuongThanCong.com https://fb.com/tailieudientucntt .c om Tham số khn mẫu hàm có tham số kiểu, ví dụ: ng template void swap(A& a, B& b){…} co Ví dụ: cu u du o ng th an template void swap( A &a, B &b){ A temp = a; a = b; //đúng b tương thích với a b = temp; //đúng temp tương thích với b } void main(){ int a = 5; double b = 10.2; swap(a,b); //swap(int,double) swap(b,a); //swap(double,int) } Chương 5: Lập trình tổng quát CuuDuongThanCong.com https://fb.com/tailieudientucntt Tóm lược cu u du o ng th an co ng c om Khi sử dụng compiler cần biết mã nguồn thực khuôn mẫu hàm, khai báo định nghĩa khuôn mẫu hàm nên để header file sử dụng template công khai hết phần thực Mã hàm khuôn mẫu thực sinh khuôn mẫu hàm sử dụng với kiểu cụ thể Một khuôn mẫu hàm sử dụng nhiều lần với kiểu khác nhiều hàm khuôn mẫu tạo Một khuôn mẫu hàm sử dụng nhiều lần với kiểu, có hàm khn mẫu tạo Chương 5: Lập trình tổng quát CuuDuongThanCong.com https://fb.com/tailieudientucntt Ưu/nhược điểm khuôn mẫu hàm c om Ưu điểm th an co ng – Tiết kiệm mã nguồn – Tính mở: nâng cao tính sử dụng lại, thuật tốn viết lần sử dụng vô số lần – Cho phép xây dựng thư viên chuẩn mạnh thư viện thuật tốn thơng dụng: chép, tìm kiếm, xếp, lựa chọn,… ng Nhược điểm cu u du o – Không che giấu mã nguồn thực thi, compiler phải biết mã nguồn biên dịch – Theo dõi, tìm kiếm lỗi phức tạp, đơi lỗi nằm phần sử dụng compiler lại báo phần định nghĩa khuôn mẫu hàm Chương 5: Lập trình tổng qt CuuDuongThanCong.com https://fb.com/tailieudientucntt 6.2 Khn mẫu lớp c om Nghiên cứu lớp số phức cu u du o ng th an co ng #include 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); } }; Chương 5: Lập trình tổng quát CuuDuongThanCong.com 10 https://fb.com/tailieudientucntt du o ng th an co ng c om 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); } }; cu u Hai lớp số phức khác gì? Giống gì? Chương 5: Lập trình tổng quát CuuDuongThanCong.com 11 https://fb.com/tailieudientucntt ng c om Tương tự nhu vậy, thực tế có nhiều cấu trúc liệu khác kiểu liệu cịn hồn tồn giống phép tốn, ví dụ vector, list, complex,… Để tiết kiệm mã nguồn thực thi tổng quát hóa kiểu liệu cho lớp cu u du o ng th an co template 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; } Complex operator-(const Complex& b) const; }; Chương 5: Lập trình tổng quát CuuDuongThanCong.com 12 https://fb.com/tailieudientucntt Định nghĩa hàm thành viên bên khai báo lớp co ng c om template Complex::Complex operator-(const Complex& b) const { return Complex(real - b.real, imag - b.imag); } an Sử dụng cu u du o ng th void main{ Complex c1(1,1), c2(2,3); Complex c3 = c1+c2; Complex c4(1.0,2.0), c5(3.0,5.0); Complex c6 = c4 + c5; }; Chương 5: Lập trình tổng qt CuuDuongThanCong.com 13 https://fb.com/tailieudientucntt Tham số khn mẫu c om Tham số khn mẫu kiểu (để làm tham số mặc định) th an co ng template class Array{ T data[N]; public: Tham số mặc định }; du o ng Sử dụng Giống cu u void main(){ Array a; Array b; Array c; } Chương 5: Lập trình tổng quát CuuDuongThanCong.com 14 https://fb.com/tailieudientucntt Bài tập co ng c om Xây dựng khn mẫu hàm cho phép tìm giá trị lớn nhất/hoặc nhỏ mảng Tổng quát hóa kiểu liệu cho lớp array, thực hàm thành viên cần thiết để cu u du o ng th an – Khai báo khởi tạo giá trị ban đầu – Hủy nhớ khơng cịn sử dụng – Thực phép tốn +,-, +=, -=,… Chương 5: Lập trình tổng quát CuuDuongThanCong.com 15 https://fb.com/tailieudientucntt 6.3 Thuật toán tổng quát c om Ví dụ: viết hàm xếp phần tử mảng theo thứ tự từ nhỏ đến lớn cu u du o ng th an co ng 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; } Chương 5: Lập trình tổng quát CuuDuongThanCong.com 16 https://fb.com/tailieudientucntt Tổng quát hóa kiểu liệu phần tử ng th an co ng c om template 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; } du o Thuật toán áp dụng cho nhiều kiểu liệu có định nghĩa phép so sánh nhỏ cu u Int p[100]; sort(p,100); //OK char p2[100]; sort(p2,100); //OK complex p3[100]; sort(p3,100) //Lỗi, áp dụng lớp complex định //nghĩa phép so sánh nhỏ Chương 5: Lập trình tổng quát CuuDuongThanCong.com https://fb.com/tailieudientucntt 17 Câu hỏi: làm để ta xếp lại từ lớn đế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 cu u du o ng th an co ng c om enum comparetype {less, greater, abs_less, abs_greater}; template 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]) swap(p[j], p[j-1]); break; case abs_greater: if(abs(p[j]) > abs(p[j-1])) swap(p[j], p[j-1]); break; } } Chương 5: Lập trình tổng quát CuuDuongThanCong.com 18 https://fb.com/tailieudientucntt Nhược điểm: c om – Hiệu không cao – Tốc độ chậm – Khơng có tính mở: ví dụ muốn só sánh số phức theo phần thực không dùng cách ng Giải pháp: tổng qt hóa phép tốn du o ng th an co template 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]); } u Kiểu Compare cu – Một hàm – Một đối tượng thuộc lớp có định nghĩa lại tốn tử gọi hàm Chương 5: Lập trình tổng quát CuuDuongThanCong.com 19 https://fb.com/tailieudientucntt Kiểu Compare hàm c om template inline bool less(const T &a, const T &b){ return a < b; //return operator b; //return operator>(a,b) } th – Sử dụng Một hàm cu u du o ng int v[100]; double d[100]; sort(v,100,less); sort(d,100,greater) Chương 5: Lập trình tổng quát CuuDuongThanCong.com 20 https://fb.com/tailieudientucntt – So sánh số phức c om template inline bool less_real(const complex &a, const complex &b){ return (a.get_real() > b.get_real()) //return operator>(a,b) } cu u du o ng th an complex c[100]; Sort(c,100,less_real); co ng – Sử dụng Chương 5: Lập trình tổng quát CuuDuongThanCong.com 21 https://fb.com/tailieudientucntt Kiểu compare đối tượng có định nghĩa lại toán tử gọi hàm co ng c om template struct Less { bool operator()(const T &a, const T &b){ return ab; } }; int v[100]; double d[100]; sort(v,100,Less()); sort(d,100,Greater()) Một đối tượng Chương 5: Lập trình tổng quát CuuDuongThanCong.com 22 https://fb.com/tailieudientucntt Bài tập an – Hàm thực phép toán co ng c om Áp dụng tổng quát hóa kiểu liệu tổng qt hóa phép tốn để xây dựng hàm càn thiết thực phép toán cộng, trừ, nhân, chia phần tử hai mảng Sau viết chương trình minh họa cách sử dụng Gợi ý: ng th template void operation(T *p1, T *p2, T *result,int n, OP op){ } du o – Định nghĩa phép toán theo dạng hàm u template T add(const T &a, const T &b){ } cu – Hoặc định nghĩa phép toán theo dạng đối tượng template struct Add{ }; Chương 5: Lập trình tổng quát CuuDuongThanCong.com 23 https://fb.com/tailieudientucntt Chương trình th an co ng c om template void operation(T* p1, T* p2,T* result,int n, OP op){ for(int i = 0;i