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ử

 

doc29 trang | Chuyên mục: C/C++ | Chia sẻ: dkS00TYs | Lượt xem: 1638 | Lượt tải: 0download
Tóm tắt nội dung C++ và Lập trình hướng đối tượng - Chương 2: Hàm trong C++, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
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:

  • docC++ và Lập trình hướng đối tượng - Chương 2 Hàm trong C++.DOC