SLIDE1

Thursday, February 5, 2015

CÁC MỞ RỘNG CỦA C++

CÁC MỞ RỘNG CỦA C++ 
II.1. Các từ khóa mới của C++ 
 Để bổ sung các tính năng mới vào C, một số từ khóa (keyword) mới đã được đưa vào C++ ngoài các từ khóa có trong C. Các chương trình bằng C nào sử dụng các tên trùng với các từ khóa cần phải thay đổi trước khi chương trình được dịch lại bằng C++. Các từ khóa mới này là :  asm catch class delete friend inline new operator private protected public template this throw try virtual   
II.2. Cách ghi chú thích  C++
chấp nhận hai kiểu chú thích. Các lập trình viên bằng C đã quen với cách chú thích bằng /*…*/. Trình biên dịch sẽ bỏ qua mọi thứ nằm giữa /*…*/. 
II.3. Dòng nhập/xuất chuẩn 

[OOP C++] quản lý danh sách học sinh làm luận văn tốt nghiệp, thi tốt nghiệp, thi lại

[OOP C++] quản lý danh sách học sinh làm luận văn tốt nghiệp,  thi tốt nghiệp, thi lại
lập trình hướng đối tượng quản lý họ tên, năm sinh, điểm chín môn học của tất cả các học viên của lớp học. Cho biết bao nhiêu học viên trong lớp được phép làm luận văn tốt nghiệp, bao nhiêu học viên thi tốt nghiệp, bao nhiêu người phải thi lại và tên môn thi lại. Tiêu chuẩn để xét: Làm luận văn phải có điểm trung bình lớn hơn 7 trong đó không có môn nào dưới 5. Thi tốt nghiệp khi điểm trung bình không lớn hơn 7 và điểm các môn không dưới 5. Thi lại có môn dưới 5

LỊCH SỬ CỦA C++

LỊCH SỬ CỦA C++
Vào những năm đầu thập niên 1980, người dùng biết C++ với tên gọi "C with Classes" được mô tả trong hai bài báo của Bjarne Stroustrup (thuộc AT&T Bell Laboratories) với nhan đề "Classes: An Abstract Data Type Facility for the C Language" và "Adding Classes to C : AnExercise in Language Evolution". Trong công trình này, tác giả đã đề xuất khái niệm lớp, bổ sung việc kiểm tra kiểu tham số của hàm, các chuyển đổi kiểu và một số mở rộng khác vào ngôn ngữ C. Bjarne Stroustrup nghiên cứu mở rộng ngôn ngữ C nhằm đạt đến một ngôn ngữ mô phỏng (simulation language) với những tính năng hướng đối tượng. Trong năm 1983, 1984, ngôn ngữ "C with Classes" được thiết kế lại, mở rộng hơn rồi một trình biên dịch ra đời. Và chính từ đó, xuất hiện tên gọi "C++". Bjarne Stroustrup mô tả ngôn ngữ C++ lần đầu tiên trong bài báo có nhan đề "Data Abstraction in C". Sau một vài hiệu chỉnh C++ được công bố rộng rãi trong quyển "The C++ Programming Language" của Bjarne Stroustrup xuất hiện đánh dấu sự hiện diện thực sự của C++, người lập tình chuyên nghiệp từ đây đã có một ngôn ngữ đủ mạnh cho các dữ án thực tiễn của mình. Về thực chất C++ giống như C nhưng bổ sung thêm một số mở rộng quan trọng, đặc biệt là ý tưởng về đối tượng, lập trình định hướng đối tượng.Thật ra các ý tưởng về cấu trúc trong C++ đã xuất phát vào các năm 1970 từ Simula 70 và Algol 68. Các ngôn ngữ này đã đưa ra các khái niệm về lớp và đơn thể. Ada là một ngôn ngữ phát triển từ đó, nhưng C++ đã khẳng định vai trò thực sự của mình.

CÁC NGÔN NGỮ VÀ VÀI ỨNG DỤNG CỦA OOP

III. CÁC NGÔN NGỮ VÀ VÀI ỨNG DỤNG CỦA OOP
 Xuất phát từ tư tưởng của ngôn ngữ SIMULA67, trung tâm nghiên cứu Palo Alto (PARC) của hãng XEROR đã tập trung 10 năm nghiên cứu để hoàn thiện ngôn ngữ OOP đầu tiên với tên gọi là Smalltalk. Sau đó các ngôn ngữ OOP lần lượt ra đời như Eiffel, Clos, Loops, Flavors, Object Pascal, Object C, C++, Delphi, Java… Chính XEROR trên cơ sở ngôn ngữ OOP đã đề ra tư tưởng giao diện biểu tượng trên màn hình (icon base screen interface), kể từ đó Apple Macintosh cũng như Microsoft Windows phát triển giao diện đồ họa như ngày nay. Trong Microsoft Windows, tư tưởng OOP được thể hiện một cách rõ nét nhất đó là "chúng ta click vào đối tượng", mỗi đối tượng có thể là control menu, control menu box, menu bar, scroll bar, button, minimize box, maximize box, … sẽ đáp ứng công việc tùy theo đặc tính của đối tượng. Turbo Vision của hãng Borland là một ứng dụng OOP tuyệt vời, giúp lập trình viên không quan tâm đến chi tiết của chương trình gia diện mà chỉ cần thực hiện các nội dung chính của vấn đề.

MỘT SỐ KHÁI NIỆM MỚI TRONG LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG

II. MỘT SỐ KHÁI NIỆM MỚI TRONG LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG
 Trong phần này, chúng ta tìm hiểu các khái niệm như sự đóng gói, tính kế thừa và tính đa hình. Đây là các khái niệm căn bản, là nền tảng tư tưởng của lập trình hướng đối tượng. Hiểu được khái niệm này, chúng ta bước đầu tiếp cận với phong cách lập trình mới, phong cách lập trình dựa vào đối tượng làm nền tảng mà trong đó quan điểm che dấu thông tin thông qua sư đóng gói là quan điểm trung tâm của vấn đề.
 II.1. Sự đóng gói (Encapsulation)
 Sự đóng gói là cơ chế ràng buộc dữ liệu và thao tác trên dữ liệu đó thành một thể thống nhất, tránh được các tác động bất ngờ từ bên ngoài. Thể thống nhất này gọi là đối tượng.
Trong Objetc Oriented Software Engineering của Ivar Jacibson, tất cả các thông tin của một hệ thống định hướng đối tượng được lưu trữ bên trong đối tượng của nó và chỉ có thể hành động khi các đối tượng đó được ra lệnh thực hiện các thao tác. Như vật, sự đóng gói không chỉ đơn thuần là sự gom chung dữ liệu và chương trình vào trong một khối, chúng còn được hiểu theo nghĩa là sự đồng nhất giữa dữ liệu và các thao tác tác động lên dữ liệu đó.  Trong một đối tượng, dữ liệu hay thao tác hay cả hai có thể là riêng (private) hoặc chung (public) của đối tượng đó. Thao tác hay dữ liệu riêng là thuộc về đối tượng đó chỉ được truy cập bởi các thành phần của đối tượng, điều này nghĩa là thao tác hay dữ liệu riêng không thể truy cập bởi các phần khác của chương trình tồn tại ngoài đối tượng. Khi thao tác hay dữ liệu là chung, các phần khác của chương trình có thể truy cập nó mặc dù nó được định nghĩa trong một đối tượng. Các thành phần chung của một đối tượng dùng để cung cấp một giao diện có điều khiển cho các thành thành riêng của đối tượng. Cơ chế đóng gói là phương thức tốt để thực hiện cơ chế che dấu thông tin so với các ngôn ngữ lập trình cấu trúc.
 II.2. Tính kế thừa (Inheritance) 
Chúng ta có thể xây dựng các lớp mới từ các lớp cũ thông qua sự kế thừa. Một lớp mới còn gọi là lớp dẫn xuất (derived class), có thể thừa hưởng dữ liệu và các phương thức của lớp cơ sở (base class) ban đầu. Trong lớp này, có thể bổ sung các thành phần dữ liệu và các phương thức mới vào những thành phần dữ liệu và các phương thức mà nó thừa hưởng từ lớp cơ sở. Mỗi lớp (kể cả lớp dẫn xuất) có thể có một số lượng bất kỳ các lớp dẫn xuất. Qua cơ cấu kế thừa này, dạng hình cây của các lớp được hình thành. Dạng cây của các lớp trông giống như các cây gia phả vì thế các lớp cơ sở còn được gọi là lớp cha (parent class) và các lớp dẫn xuất được gọi là lớp con (child class). Ví dụ 1.2: Chúng ta sẽ xây dựng một tập các lớp mô tả cho thư viện các ấn phẩm. Có hai kiểu ấn phẩm: tạp chí và sách. Chúng ta có thể tạo một ấn phẩm tổng quát bằng cách định nghĩa các thành phần dữ liệu tương ứng với số trang, mã số tra cứu, ngày tháng xuất bản, bản quyền và nhà xuất bản. Các ấn phẩm có thể được lấy ra, cất đi và đọc. Đó là các phương thức thực hiện trên một ấn phẩm. Tiếp đó chúng ta định nghĩa hai lớp dẫn xuất tên là tạp chí và sách. Tạp chí có tên, số ký phát hành và chứa nhiều bài của các tác giả khác nhau . Các thành phần dữ liệu tương ứng với các yếu tố này được đặt vào định nghĩa của lớp tạp chí. Tạp chí cũng cần có một phương thức nữa đó là đặt mua. Các thành phần dữ liệu xác định cho sách sẽ bao gồm tên của (các) tác giả, loại bìa (cứng hay mềm) và số hiệu ISBN của nó. Như vậy chúng ta có thể thấy, sách và tạp chí có chung các đặc trưng ấn phẩm, trong khi vẫn có các thuộc tính riêng của chúng.
II.3. Tính đa hình (Polymorphism) 
Đó là khả năng để cho một thông điệp có thể thay đổi cách thực hiện của nó theo lớp cụ thể của đối tượng nhận thông điệp. Khi một lớp dẫn xuất được tạo ra, nó có thể thay đổi cách thực hiện các phương thức nào đó mà nó thừa hưởng từ lớp cơ sở của nó. Một thông điệp khi được gởi đến một đối tượng của lớp cơ sở, sẽ dùng phương thức đã định nghĩa cho nó trong lớp cơ sở. Nếu một lớp dẫn xuất định nghĩa lại một phương thức thừa hưởng từ lớp cơ sở của nó thì một thông điệp có cùng tên với phương thức này, khi được gởi tới một đối tượng của lớp dẫn xuất sẽ gọi phương thức đã định nghĩa cho lớp dẫn xuất. Như vậy đa hình là khả năng cho phép gởi cùng một thông điệp đến những đối tượng khác nhau có cùng chung một đặc điểm, nói cách khác thông điệp được gởi đi không cần biết thực thể nhận thuộc lớp nào, chỉ biết rằng tập hợp các thực thể nhận có chung một tính chất nào đó. Chẳng hạn, thông điệp “vẽ hình” được gởi đến cả hai đối tượng hình hộp và hình tròn. Trong hai đối tượng này đều có chung phương thức vẽ hình, tuy nhiên tuỳ theo thời điểm mà đối tượng nhận thông điệp, hình tương ứng sẽ được vẽ lên. Trong các ngôn ngữ lập trình OOP, tính đa hình thể hiện qua khả năng cho phép mô tả những phương thức có tên giống nhau trong các lớp khác nhau. Đặc điểm này giúp người lập trình không phải viết những cấu trúc điều khiển rườm rà trong chương trình, các khả năng khác nhau của thông điệp chỉ thực sự đòi hỏi khi chương trình thực hiện. Ví dụ 1.3: Xét lại ví dụ 1.2, chúng ta thấy rằng cả tạp chí và và sách đều phải có khả năng lấy ra. Tuy nhiên phương pháp lấy ra cho tạp chí có khác so với phương pháp lấy ra cho sách, mặc dù kết quả cuối cùng giống nhau. Khi phải lấy ra tạp chí, thì phải sử dụng phương pháp lấy ra riêng cho tạp chí (dựa trên một bản tra cứu) nhưng khi lấy ra sách thì lại phải sử dụng phương pháp lấy ra riêng cho sách (dựa trên hệ thống phiếu lưu trữ). Tính đa hình cho phép chúng ta xác định một phương thức để lấy ra một tạp chí hay một cuốn sách. Khi lấy ra một tạp chí nó sẽ dùng phương thức lấy ra dành riêng cho tạp chí, còn khi lấy ra một cuốn sách thì nó sử dụng phương thức lấy ra tương ứng với sách. Kết quả là chỉ cần một tên phương thức duy nhất được dùng cho cả hai công việc tiến hành trên hai lớp dẫn xuất có liên quan, mặc dù việc thực hiện của phương thức đó thay đổi tùy theo từng lớp. Tính đa hình dựa trên sự nối kết (Binding), đó là quá trình gắn một phương thức với một hàm thực sự. Khi các phương thức kiểu đa hình được sử dụng thì trình biên dịch chưa thể xác định hàm nào tương ứng với phương thức nào sẽ được gọi. Hàm cụ thể được gọi sẽ tuỳ thuộc vào việc phần tử nhận thông điệp lúc đó là thuộc lớp nào, do đó hàm được gọi chỉ xác định được vào lúc chương trình chạy. Điều này gọi là sự kết nối muộn (Late binding) hay kết nối lúc chạy (Runtime binding) vì nó xảy ra khi chương trình đang thực hiện.

LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG (OOP) LÀ GÌ ?

Lập trình hướng đối tượng (Object-Oriented Programming, viết tắt là OOP) là một phương pháp mới trên bước đường tiến hóa của việc lập trình máy tính, nhằm làm cho chương trình trở nên linh hoạt, tin cậy và dễ phát triển. Tuy nhiên để hiểu được OOP là gì, chúng ta hãy bắt đầu từ lịch sử của quá trình lập trình – xem xét OOP đã tiến hóa như thế nào.

I.1. Lập trình tuyến tính
 Máy tính đầu tiên được lập trình bằng mã nhị phân, sử dụng các công tắt cơ khí để nạp chương trình. Cùng với sự xuất hiện của các thiết bị lưu trữ lớn và bộ nhớ máy tính có dung lượng lớn nên các ngôn ngữ lập trình cấp cao đầu tiên được đưa vào sử dụng . Thay vì phải suy nghĩ trên một dãy các bit và byte, lập trình viên có thể viết một loạt lệnh gần với tiếng Anh và sau đó chương trình dịch thành ngôn ngữ máy. Các ngôn ngữ lập trình cấp cao đầu tiên được thiết kế để lập các chương trình làm các công việc tương đối đơn giản như tính toán. Các chương trình ban đầu chủ yếu liên quan đến tính toán và không đòi hỏi gì nhiều ở ngôn ngữ lập trình. Hơn nữa phần lớn các chương trình này tương đối ngắn, thường ít hơn 100 dòng. Khi khả năng của máy tính tăng lên thì khả năng để triển khai các chương trình phức tạp hơn cũng tăng lên. Các ngôn ngữ lập trình ngày trước không còn thích hợp đối với việc lập trình đòi hỏi cao hơn. Các phương tiện cần thiết để sử dụng lại các phần mã chương trình đã viết hầu như không có trong ngôn ngữ lập trình tuyến tính. Thật ra, một đoạn lệnh thường phải được chép lặp lại mỗi khi chúng ta dùng trong nhiều chương trình do đó chương trình dài dòng, logic của chương trình khó hiểu. Chương trình được điều khiển để nhảy đến nhiều chỗ mà thường không có sự giải thích rõ ràng, làm thế nào để chương trình đến chỗ cần thiết hoặc tại sao như vậy. Ngôn ngữ lập trình tuyến tính không có khả năng kiểm soát phạm vi nhìn thấy của các dữ liệu. Mọi dữ liệu trong chương trình đều là dữ liệu toàn cục nghĩa là chúng có thể bị sửa đổi ở bất kỳ phần nào của chương trình. Việc dò tìm các thay đổi không mong muốn đó của các phần tử dữ liệu trong một dãy mã lệnh dài và vòng vèo đã từng làm cho các lập trình viên rất mất thời gian.

[C++] in cách đọc số nguyên dương N nhập từ bàn phím

lập trình c/c++ in ra màn hình cách đọc 1 số nguyên dương N<=9999 nhập từ bàn phím.

Wednesday, February 4, 2015

[OOP C++] tìm ma trận nghịch đảo của mt vuông cấp n

lập trình hướng đối tượng tìm ma trận nghịch đảo của 1 ma trận vuông cấp n tùy ý

matran.h

#pragma once
#include<iostream>
#include<iomanip>
using namespace std;
class matran
{
private:
float a[100][100];
int n;
public:
matran(void);
~matran(void);
void nhap();
void xuat();
float get(int,int);
void set(float,int,int);
void setn(int);
float det();
float con(int,int);
void nghichdao();
};

Tuesday, February 3, 2015

[C++] Tìm ma trận nghịch đảo của 1 ma trận vuông cấp n tùy ý

[C++] Tìm ma trận nghịch đảo của 1 ma trận vuông cấp n tùy ý

#include<iostream>
#include<iomanip>
using namespace std;
void nhap(float a[][100],int &n);
void xuat(float a[][100],int n);
float det(float a[][100],int n);
float con(float a[][100],int n,int h,int c);
void nghichdao(float a[][100],int n);
void main()
{
float a[100][100];
int n;
nhap(a,n);
xuat(a,n);
cout<<"\n-------------------------------\nma tran nghich dao:\n";
nghichdao(a,n);
system("pause");
}
void nhap(float a[][100],int &n)
{
cout<<"\nnhap N= ";
cin>>n;
for(int i=0;i<n;i++)
{
cout<<"\nnhap hang "<<i+1<<":\n";
for(int j=0;j<n;j++)
cin>>a[i][j];
}
}
void xuat(float a[][100],int n)
{
for(int i=0;i<n;i++)
{
cout<<"\n\n";
for(int j=0;j<n;j++)
cout<<setw(6)<<a[i][j];
}
}
float det(float a[][100],int n)
{
int i,j,k,dem=0,kt;
float b[100],h,kq=1;
for(i=0;i<n-1;i++)
{
if(a[i][i]==0)
{
kt=0;
for(j=i+1;j<n;j++)
{
if(a[i][j]!=0)
{
for(k=0;k<n;k++)
{
float t=a[k][i];
a[k][i]=a[k][j];
a[k][j]=t;
}
dem++;kt++;
break;
}
}
if(kt==0) return 0;
}
b[i]=a[i][i];
for(j=0;j<n;j++) a[i][j]/=b[i];
for(j=i+1;j<n;j++)
{
h=a[j][i];
for(k=0;k<n;k++) a[j][k]=a[j][k]-h*a[i][k];
}
}
b[n-1]=a[n-1][n-1];
for(i=0;i<n;i++) kq*=b[i];
if(dem%2==0) return kq;
return -kq;
}
float con(float a[][100],int n,int h,int c)
{
float b[100][100];
int i,j,x=-1,y;
for(i=0;i<n;i++)
{
if(i==h) continue;
x++;y=-1;
for(j=0;j<n;j++)
{
if(j==c)continue;
y++;
b[x][y]=a[i][j];
}
}
if((h+c)%2==0) return det(b,n-1);
return -det(b,n-1);
}
void nghichdao(float a[][100],int n)
{
float b[100][100];
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
b[i][j]=con(a,n,i,j);
}
}
for(int i=0;i<n-1;i++)
for(int j=i+1;j<n;j++)
{
float t=b[i][j];
b[i][j]=b[j][i];
b[j][i]=t;
}
float k=det(a,n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
b[i][j]/=k;
if(k==0) cout<<"\nkhong co ma tran nghich dao!";
else xuat(b,n);
}

[OOP C++] tính tổng các phân số - lập trình hướng đối tượng

[OOP C++] tính tổng các phân số - lập trình hướng đối tượng

phanso.h

#pragma once
#include<iostream>
#include<stdlib.h>
#include<string.h>
using namespace std;
class phanso
{
private:
int tu,mau;
public:
phanso(void);
~phanso(void);
void settu(int);
void setmau(int);
int gettu();
int getmau();
int rutgon();
void nhapps();
void xuatps();
};


phanso.cpp

#include "phanso.h"


phanso::phanso(void)
{
}


phanso::~phanso(void)
{
}
void phanso::nhapps()
{
char s[100];
int i,j,k,kt,dem;
do{
kt=0;dem=0;k=0;
cout<<"\nnhap phan so dang a/b: ";
fflush(stdin);
gets(s);
for(i=0;i<strlen(s);i++)
if((s[i]>='0' && s[i]<='9') || s[i]=='/')
{
dem++;
if(s[i]=='/') k++;
}
if(dem!=strlen(s) || k!=1)
{
cout<<"\nloi dinh dang! nhap lai!!";
kt=1;
}
}while(kt);
char a[100];
i=0;k=0;
while(s[i]!='/')
a[k++]=s[i++];
a[k]='\0';
tu=atoi(a);
i++;k=0;
while(i<strlen(s)) a[k++]=s[i++];
a[k]='\0';
mau=atoi(a);
}
void phanso::xuatps()
{
cout<<tu<<"/"<<mau;
}
void phanso::settu(int x)
{
tu=x;
}
void phanso::setmau(int x)
{
mau=x;
}
int phanso::gettu()
{
return tu;
}
int phanso::getmau()
{
return mau;
}
int phanso::rutgon()
{
int a=abs(tu),b=abs(mau);
while(a!=b)
if(a>b) a-=b;
else b-=a;
if(a==1) return 0;
tu/=a;
mau/=a;
return 1;
}

mangps.h

#pragma once
#include"phanso.h"
class mangps
{
private:
phanso a[100];
int n;
public:
mangps(void);
~mangps(void);
void nhapmangps();
void xuatmangps();
void tong();
};



mangps.cpp


#include "mangps.h"


mangps::mangps(void)
{
}


mangps::~mangps(void)
{
}
void mangps::nhapmangps()
{
int kt,i=0,dem=0,k;
cout<<"\n *nhap phan so thu "<<i+1<<":";
a[i].nhapps();
i++;
nhap:;
cout<<"\n *nhap phan so thu "<<i+1<<":";
a[i].nhapps();
loop:;
cout<<"\n-----menu-----------";
cout<<"\n| 1. nhap tiep.    |";
cout<<"\n| 0. xong.         |";
cout<<"\n--------------------";
cout<<"\nlua chon cua ban: ";
cin>>k;
if(k!=0 && k!=1)
{
cout<<"\nkhong hop le!!!";
goto loop;
}
if(k==1)
{
i++;
goto nhap;
}
n=i+1;
}
void mangps::xuatmangps()
{
for(int i=0;i<n;i++)
{
if(i>=1) cout<<" + ";
a[i].xuatps();
}
}
void mangps::tong()
{
int i;
phanso x;
x.settu(a[0].gettu());
x.setmau(a[0].getmau());
for(i=1;i<n;i++)
{
x.settu(x.gettu()*a[i].getmau()+ x.getmau()*a[i].gettu());
x.setmau(x.getmau()*a[i].getmau());
}
xuatmangps();cout<<" = ";x.xuatps();
if(i=x.rutgon()) 
{
cout<<" = ";x.xuatps();
}
}

source.cpp

#include"mangps.h"
void main()
{
mangps x;
x.nhapmangps();
cout<<"\ntong cac phan so: \n";
x.tong();
system("pause");
}

Monday, February 2, 2015

[OOP C++] Tính Tổng, Hiệu, Tích, Thương của 2 phân số theo kiểu lập trình hướng đối tượng

[OOP C++] Tính Tổng, Hiệu, Tích, Thương của 2 phân số theo kiểu lập trình hướng đối tượng. có menu lựa chọn, nhập phân số kiểu string thuận tiện.



PHANSO.H
#pragma once
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
class phanso
{
private:
int tu,mau;
public:
phanso(void);
~phanso(void);
int gettu(); //trả về giá trị của tử số.
int getmau(); //trả về giá trị của mẫu số.
void settu(int); //cà đặt giá trị cho tử và mẫu
void setmau(int);
void nhapphanso();
void xuatphanso();
int rutgon();
// các phương thức tính tổng, hiệu, tích, thương của phân số ta đang viết class với phân số khác
//cũng là phân số thuộc đối tượng phanso nhưng nó nằm ngoài phạm vi hoạt động của class ta đang xây dựng nên phải có các phương thức get,set như trên để giao tiếp với nó
void tinhtong(phanso);
void tinhtich(phanso);
void tinhhieu(phanso);
void tinhthuong(phanso);
};




PHANSO.CPP
#include "phanso.h"
phanso::phanso(void) //khởi tạo đối tượng mặ định.
{
//nếu biến trong private là kiểu con trỏ thì cấp phát vùng nhớ khởi tạo cho nó ở đây.
}
phanso::~phanso(void)//kết thúc nội đối tượng
{
//nếu biến trong private là cấp phát động thì delete nó ở đây.
}
void phanso::nhapphanso()
{
char s[100],a[100];
int i,j,k;
do{
k=0;
cout<<"\nnhap vao phan so dang a/b: ";
fflush(stdin); gets(s);
//phân số nhập vào đảm bảo phải chứa 1 dấu '/' và số, nếu sai thì nhập không đúng định dạng yêu cầu nhập lại.
int dem=0,d=0;
for(i=0;i<strlen(s);i++)
{
if((s[i]>='0' && s[i]<='9')|| s[i]=='/') dem++;
if(s[i]=='/') d++; //đếm số dấu '/', nếu có 2 dấu trở lên thì nhập sai.
}
if(dem!=strlen(s) || d!=1) // có nghĩa là đã xuất hiện ký tự không đúng yêu cầu, có thể là chữ, kí hiệu đặc biệt,...
{
cout<<"\nban da nhap khong dung dinh dang! nhap lai!";
k=1; // để lặp lại việc nhập phân số.
}
}while(k);

//lấy tử số là các chữ số nằm trước dấu '/'.
i=0;
while(s[i]!='/')
{
a[i]=s[i];
i++;
}
a[i]='\0';
tu=atoi(a);
k=0;
for(j=i+1;j<strlen(s);j++) a[k++]=s[j];
a[k]='\0';
mau=atoi(a);
}
void phanso::xuatphanso()
{
cout<<tu<<"/"<<mau;
}
int phanso::gettu()
{
return tu;
}
int phanso::getmau()
{
return mau;
}
void phanso::settu(int x)
{
tu=x;
}
 void phanso::setmau(int x)
{
mau=x;
}
int phanso::rutgon()//rút gọn phan số
{
//tìm UCLN rồi lấy tử và mẫu chia cho UCLN để rút gọn phân số.
int a=abs(tu),b=abs(mau);
while(a!=b)
if(a>b)a-=b;
else b-=a;

tu/=a;
mau/=a;
if(a!=1) return 1; //có rút gọn
return 0;//không xảy ra rút gọn
}
void phanso::tinhtong(phanso x)
{
phanso kq;
kq.settu(tu*x.getmau()+mau*x.gettu());// gán giá trị cho tử của phấn số kết quả thông qua phương thức settu đã tạo ở trên. tương tự cho mẫu.
kq.setmau(mau*x.getmau());
//in ket qua
cout<<"\n";xuatphanso();cout<<" + ";x.xuatphanso();cout<<" = ";kq.xuatphanso();
//nếu có rút gọn thì in kết quả đã rút gọn ra
if(kq.rutgon()) 
{
cout<<" = ";kq.xuatphanso();
}
cout<<"\n";
}
void phanso::tinhhieu(phanso x)
{
phanso kq;
kq.settu(tu*x.getmau()-mau*x.gettu());
kq.setmau(mau*x.getmau());
//in ket qua
cout<<"\n";xuatphanso();cout<<" - ";x.xuatphanso();cout<<" = ";kq.xuatphanso();
//nếu có rút gọn thì in kết quả đã rút gọn ra
if(kq.rutgon()) 
{
cout<<" = ";kq.xuatphanso();
}
cout<<"\n";
}
void phanso::tinhtich(phanso x)
{
phanso kq;
kq.settu(tu*x.gettu());
kq.setmau(mau*x.getmau());
//in ket qua
cout<<"\n";xuatphanso();cout<<" x ";x.xuatphanso();cout<<" = ";kq.xuatphanso();
//nếu có rút gọn thì in kết quả đã rút gọn ra
if(kq.rutgon()) 
{
cout<<" = ";kq.xuatphanso();
}
cout<<"\n";
}
void phanso::tinhthuong(phanso x)
{
phanso kq;
kq.settu(tu*x.getmau());
kq.setmau(mau*x.gettu());
//in ket qua
cout<<"\n";xuatphanso();cout<<" : ";x.xuatphanso();cout<<" = ";kq.xuatphanso();
//nếu có rút gọn thì in kết quả đã rút gọn ra
if(kq.rutgon()) 
{
cout<<" = ";kq.xuatphanso();
}
cout<<"\n";

}



SOURCE.CPP
#include"phanso.h"
void main()
{
phanso x,y;
cout<<"\n\t*nhap phan so x*\n";
x.nhapphanso();
cout<<"\n\t*nhap phan so y*\n";
y.nhapphanso();
int k,kt;
do{
do{
kt=0;
cout<<"\n------------------MENU------------------";
cout<<"\n1. tinh TONG 2 phan so x,y.";
cout<<"\n2. tinh HIEU 2 phan so x,y.";
cout<<"\n3. tinh TICH 2 phan so x,y.";
cout<<"\n4. tinh THUONG 2 phan so x,y.";
cout<<"\n0.ket thuc chuong trinh.";
cout<<"\n-----------------------------------------";
cout<<"\n->lua chon cua ban: ";
cin>>k;
//kiểm tra lựa chọn có hợp lý không.
if(k!=0 && k!=1 && k!=2 && k!=3 && k!=4)
{
cout<<"\nlua chon khong hop le! chon lai!!!\n";
kt=1;//để lặp lại việc nhập.
}
}while(kt);
//lựa chọn hợp lý thì tiến hành lựa chọn đó.
if(k==1)
{
cout<<"\n\t*TONG*\n";
x.tinhtong(y);//gọi các phương thúc cần dùng ra.
}
if(k==2)
{
cout<<"\n\t*HIEU*\n";
x.tinhhieu(y);
}
if(k==3)
{
cout<<"\n\t*TICH*\n";
x.tinhtich(y);
}
if(k==4)
{
cout<<"\n\t*THUONG*\n";
x.tinhthuong(y);
}
}while(k!=0);//dừng chương trình khi k=0. lựa chọn kết thúc trong menu ở trên
system("pause");

}