C++ và Lập trình hướng đối tượng - Chương 2: Hàm trong C++
Chương này trình bầy những khả năng mới của C++ trong việc xây dựng và sử dụng hàm. Đó là:
+ Kiểu tham chiếu và việc truyền dữ liệu cho hàm bằng tham chiếu.
+ Đối tham chiếu hằng (const)
+ Đối có giá trị mặc định
+ Hàm trực tuyến
+ Việc định nghĩa chồng các hàm
+ Việc định nghĩa chồng các toán tử
eam& is,PS &p) { cout << "Nhap tu va mau: " ; is >> p.a >> p.b ; return is; } int uscln(int x, int y) { x=abs(x); y=abs(y); if (x*y==0) return 1; while (x!=y) if (x>y) x-=y; else y-=x; return x; } PS rutgon(PS p) { PS q; int x; x=uscln(p.a,p.b); q.a = p.a / x ; q.b = p.b / x ; return q; } PS operator+(PS p1, PS p2) { PS q; q.a = p1.a*p2.b + p2.a*p1.b; q.b = p1.b * p2.b ; return rutgon(q); } PS operator-(PS p1, PS p2) { PS q; q.a = p1.a*p2.b - p2.a*p1.b; q.b = p1.b * p2.b ; return rutgon(q); } PS operator*(PS p1, PS p2) { PS q; q.a = p1.a * p2.a ; q.b = p1.b * p2.b ; return rutgon(q); } PS operator/(PS p1, PS p2) { PS q; q.a = p1.a * p2.b ; q.b = p1.b * p2.a ; return rutgon(q); } void main() { PS p, q, z, u, v ; PS s; cout <<"\nNhap cac PS p, q, z, u, v:\n " ; cin >> p >> q >> z >> u >> v ; s = (p - q*z) / (u + v) ; cout << "\n Phan so s = " << s; getch(); } Ví dụ 2: Chương trình đưa vào các hàm toán tử: operator- có một đối dùng để đảo dấu một đa thức operator+ có 2 đối dùng để cộng 2 đa thức operator- có 2 đối dùng để trừ 2 đa thức operator* có 2 đối dùng để nhân 2 đa thức operator^ có 2 đối dùng để tính giá đa thức tại x operator<< có 2 đối dùng để in đa thức operator>> có 2 đối dùng để nhập đa thức Chương trình sẽ nhập 4 đa thức: p, q, r, s. Sau đó tính đa thức: f = -(p+q)*(r-s) Cuối cùng tính giá trị f(x), với x là một số thực nhập từ bàn phím. #include #include #include struct DT { double a[20]; // Mang chua cac he so da thuc a0, a1,... int n ; // Bac da thuc } ; ostream& operator<< (ostream& os, DT d); istream& operator>> (istream& is,DT &d); DT operator-(const DT& d); DT operator+(DT d1, DT d2); DT operator-(DT d1, DT d2); DT operator*(DT d1, DT d2); double operator^(DT d, double x); // Tinh gia tri da thuc ostream& operator<< (ostream& os, DT d) { os << " - Cac he so (tu ao): " ; for (int i=0 ; i<= d.n ; ++i) os << d.a[i] <<" " ; return os; } istream& operator>> (istream& is, DT &d) { cout << " - Bac da thuc: " ; cin >> d.n; cout << "Nhap cac he so da thuc:\n" ; for (int i=0 ; i<= d.n ; ++i) { cout << "He so bac " << i << " = " ; is >> d.a[i] ; } return is; } DT operator-(const DT& d) { DT p; p.n = d.n; for (int i=0 ; i<=d.n ; ++i) p.a[i] = -d.a[i]; return p; } DT operator+(DT d1, DT d2) { DT d; int k,i; k = d1.n > d2.n ? d1.n : d2.n ; for (i=0; i<=k ; ++i) if (i<=d1.n && i<=d2.n) d.a[i] = d1.a[i] + d2.a[i]; else if (i<=d1.n) d.a[i] = d1.a[i]; else d.a[i] = d2.a[i]; i=k; while (i>0 && d.a[i]==0.0) --i; d.n = i; return d ; } DT operator-(DT d1, DT d2) { return (d1 + (-d2)); } DT operator*(DT d1, DT d2) { DT d; int k, i, j; k = d.n = d1.n + d2.n ; for (i=0; i<=k; ++i) d.a[i] = 0; for (i=0 ; i<= d1.n ; ++i) for (j=0 ; j<= d2.n ; ++j) d.a[i+j] += d1.a[i]*d2.a[j] ; return d; } double operator^(DT d, double x) { double s=0.0 , t=1.0; for (int i=0 ; i<= d.n ; ++i) { s += d.a[i]*t; t *= x; } return s; } void main() { DT p,q,r,s,f; double x,g; clrscr(); cout > p; cout > q; cout > r; cout > s; cout > x; f = -(p+q)*(r-s); g = f^x; cout << "\nDa thuc f " << f ; cout << "\n x = " << x; cout << "\nf(x) = " << g; getch(); } Đ 9. Các bài toán về ma trận và véc tơ Trong mục này sẽ xét các ma trận thực vuông cấp n và các véc tơ thực cấp n. Chúng được biểu diễn thông qua các kiểu cấu trúc MT và VT: struct MT { double a[20][20] ; // Mang a chứa các phần tử ma trận int n ; // Cấp ma trận } ; struct VT { double b[20]; // Mang chua cac phan tu cua vec to int n ; // Cap vec to } ; Để xử lý ma trận và véc tơ, chúng ta xây dựng 9 hàm toán tử: ostream& operator<< (ostream& os, const MT& x); // In ma trận ostream& operator<< (ostream& os, const VT& v); // In véc tơ istream& operator>> (istream& is,MT& x); // Nhập ma trận istream& operator>> (istream& is, VT &v); // Nhập véc tơ MT operator+(const MT& x1, const MT& x2); // Cộng 2 ma trận MT operator-(const MT& x1, const MT& x2); // Trừ 2 ma trận MT operator*(const MT& x1, const MT& x2); // Nhân 2 ma trận VT operator*(const MT& x, const VT& v); // Nhân ma trận véc tơ MT operator!(MT x); // Nghịch đảo ma trận Thuật toán cho 8 hàm toán tử đầu tương đối quen thuộc không có gì phải bàn. Để nghịch đảo ma trận có nhiều cách, ở đây chúng ta dùng phương pháp Jordance như sau. Giả sử cần nghịch đảo ma trận x cấp n. Ta dùng thêm ma trận đơn vị y. Sau đó thực hiện đồng thời các phép tính trên cả x và y sao cho x trở thành đơn vị. Kết quả y chính là nghịch đảo của x. Thuật toán được tiến hành trên n bước. Nội dung của bước k (k = 1,...,n) như sau: Tìm chỉ số r ( k <= r <= n) sao cho abs(x[r,k]) = max { abs(x[i,k] với i = k,...,n } Nếu abs(x[r,k]) = 0 thì ma trận không có nghịch đảo và thuật toán kết thúc giữa chừng. Hoán vị hàng k với hàng r trong cả 2 ma trận x và y. Chia hàng k của cả x và y cho tg = x[k,k] (mục đích làm cho x[k,k] = 1). Biến đổi để cột k của x trơ thành véc tơ đơn vị bằng cách làm cho các phần tử x[i,k] = 0 (với i khác k). Muốn vậy ta thực hiện các phép tính sau trên cả x và y: (hàng i) = (hàng i) - x[i,k]*(hàng k) , với mọi i khác k Nội dung chương trình là nhập 4 ma trận X, Y, R, S và véc tơ u. Sau đó tính véc tơ v theo công thức: v = ((X + Y)*(R - S))-1u Như sẽ thấy trong hàm main() dưới đây, nhờ các hàm toán tử mà câu lệnh tính v được viết gần giống như công thức toán học nêu trên. /* Chương trình */ #include #include #include #include struct MT { double a[20][20]; // Mang chua cac phan tu ma tran int n ; // Cap ma tran } ; struct VT { double b[20]; // Mang chua cac phan tu cua vec to int n ; // Cap vec to } ; ostream& operator<< (ostream& os, const MT& x); ostream& operator<< (ostream& os, const VT& v); istream& operator>> (istream& is,MT& x); istream& operator>> (istream& is, VT &v); MT operator+(const MT& x1, const MT& x2); MT operator-(const MT& x1, const MT& x2); MT operator*(const MT& x1, const MT& x2); VT operator*(const MT& x, const VT& v); MT operator!(MT x); // Tinh ma tran nghich dao ostream& operator<< (ostream& os, const MT& x) { os << setprecision(2) << setiosflags(ios::showpoint); for (int i=1 ; i<= x.n ; ++i) { os << "\n" ; for (int j=1; j<=x.n; ++j) os << setw(6) << x.a[i][j] ; } os << "\n" ; return os; } ostream& operator<< (ostream& os, const VT& v) { os << setprecision(2) << setiosflags(ios::showpoint); for (int i=1 ; i<= v.n ; ++i) os << setw(6) << v.b[i] ; os << "\n" ; return os; } istream& operator>> (istream& is, MT& x) { cout << " - Cap ma tran: " ; is >> x.n; cout << "Nhap cac phan tu :\n" ; for (int i=1 ; i<= x.n ; ++i) for (int j=1; j<=x.n; ++j) { cout << "PT hang " << i << " cot " << j << " = " ; is >> x.a[i][j] ; } return is; } istream& operator>> (istream& is, VT& v) { cout << " - Cap vec to: " ; is >> v.n; cout << "Nhap cac phan tu :\n" ; for (int i=1 ; i<= v.n ; ++i) { cout << "Phan tu thu " << i << " = " ; is >> v.b[i] ; } return is; } MT operator+(const MT& x1, const MT& x2) { if (x1.n!=x2.n) { cout << "\nKhong thuc hien duoc phep cong vi 2 MT khong cung cap"; getch(); return x1; } else { MT x; int i, j, n; n = x.n = x1.n ; for (i=1; i<=n; ++i) for (j=1; j<=n ;++j) x.a[i][j] = x1.a[i][j] + x2.a[i][j] ; return x; } } MT operator-(const MT& x1, const MT& x2) { if (x1.n!=x2.n) { cout << "\nKhong thuc hien duoc phep tru vi 2 MT khong cung cap"; getch(); return x1; } else { MT x; int i, j, n; n = x.n = x1.n; for (i=1; i<=n; ++i) for (j=1; j<=n ;++j) x.a[i][j] = x1.a[i][j] - x2.a[i][j] ; return x; } } MT operator*(const MT& x1, const MT& x2) { if (x1.n!=x2.n) { cout << "\nKhong thuc hien duoc phep nhan vi 2 MT khong cung cap"; getch(); return x1; } else { MT x; int n, i, j,k; n = x.n = x1.n; for (i=1; i<=n; ++i) for (j=1; j<=n ;++j) { x.a[i][j] = 0.0 ; for (k=1 ; k<=n; ++k) x.a[i][j] += x1.a[i][k]*x2.a[k][j] ; } return x; } } VT operator*(const MT& x, const VT& v) { if (x.n != v.n) { cout << "\n Cap ma tran khac cap vec to, phep nhan vo nghia"; getch(); return v; } else { VT u; int n; n = u.n = v.n ; for (int i=1; i <=n ; ++i) { u.b[i] = 0; for (int j=1; j<=n; ++j) u.b[i] += x.a[i][j]*v.b[j]; } return u; } } MT operator!(MT x) { MT y; int i,j,k,r,n; double tg; n = y.n = x.n ; for (i=1 ; i<=n ; ++i) for (j=1 ; j<=n ; ++j) if (i==j) y.a[i][j] = 1; else y.a[i][j] = 0; for (k=1; k<=n; ++k) { r=k; for (i=k+1; i<=n; ++i) if (abs(x.a[i][k]) > abs(x.a[r][k]) ) r = i; if (abs(x.a[r][k]) < 1.0E-8) { cout << "\n Ma tran suy bien, khong co nghich dao" ; getch(); return x; } /* Hoan vi hang r va hang k */ for (j=1 ; j<=n ; ++j) { tg = x.a[k][j]; x.a[k][j] = x.a[r][j]; x.a[r][j] = tg; tg = y.a[k][j]; y.a[k][j] = y.a[r][j]; y.a[r][j] = tg; } /* Chia hang k cho a[k,k] */ tg = x.a[k][k] ; for (j=1 ; j<=n ; ++j) { x.a[k][j] /= tg; y.a[k][j] /= tg; } /* Khu cot k : lam cho a[i,k] = 0 voi i != k */ for (int i=1; i<= n ; ++i) if (i != k) { tg = x.a[i][k] ; for (j=1 ; j<=n ; ++j) { x.a[i][j] -= tg*x.a[k][j] ; y.a[i][j] -= tg*y.a[k][j] ; } } } return y; } void main() { MT x,y,r,s; VT u,v; clrscr(); cout > x; cout > y; cout > r; cout > s; cout > u; v = !((x+y)*(r-s))*u ; cout << "\nVec to v = xu " << v ; getch(); }
File đính kèm:
- C++ và Lập trình hướng đối tượng - Chương 2 Hàm trong C++.DOC