01.分析以下程序的執行結果
#include<iostream.h>
class Sample
{
int n;
public:
Sample(int i){n=i;}
friend int add(Sample &s1,Sample &s2);
};
int add(Sample &s1,Sample &s2)
{
return s1.n+s2.n;
}
void main()
{
Sample s1(10),s2(20);
cout<<add(s1,s2)<<endl;
}
解:
本題說明了友元函數的使用方法。add()是一個友元函數,它返回兩個引用對象的n值之和。
所以輸出為: 30
注重:友元函數不是類的成元函數
----------------------------------------------------
02.分析以下程序的執行結果
#include<iostream.h>
class B;
class A
{
int i;
public:
int set(B&);
int get(){return i;}
A(int x){i=x;}
};
class B
{
int i;
public:
B(int x){i=x;}
friend A;
};
int A::set(B &b) // 由於使用了類B的定義,故本函數的定義應放在類B定義之後
{
return i=b.i;
}
void main()
{
A a(1);
B b(2);
cout<<a.get()<<",";
a.set(b);
cout<<a.get()<<endl;
}
解:
本題說明友元類的使用方法。這裡將類A設置為類B的友元類,因此,類A的所有成員函數均為類B的友元函數。通過調用a.set(b)將b對象的i值賦給a對象的i值。
所以輸出為:1,2
-------------------------------------------------
03.有一個學生類student,包括學生姓名、成績,設計一個友元函數,比較兩個學生成績的高低,並求出最高分和最低分的學生。
解:
#include<iostream.h>
#include<string.h>
class student
{
char name[10];
int deg;
public:
student(char na[],int d)
{
strcpy(name,na);
deg=d;
}
char *getname(){ return name;}
friend int compare(student &s1,student &s2)
{
if(s1.deg>s2.deg)
return 1;
else if(s1.deg==s2.deg)
return 0;
else return -1;
}
};
void main()
{
student st[]={student("王華",78),student("李明",92),student("張偉",62),student("孫強",88)};
int i,min=0,max=0;
for(i=1;i<4;i++)
{
if(compare(st[max],st[i])==-1)
max=i;
else if(compare(st[i],st[min])==1)
min=i;
}
cout<<"輸出結果:"<<endl;
cout<<" 最高分:"<<st[max].getname()<<endl;
cout<<" 最低分:"<<st[min].getname()<<endl;
}
本程序的執行結果如下:
輸出結果:
最高分者:李明
最低分者:張偉
-------------------------------------------------------------
04.有一個學生類student,包括學生姓名、成績,設計一個友元函數,輸出成績對應的等級:大於等於90:優;80~90:良;70~79:中;60!69:及格;小於60:不及格。
解:
#include<iostream.h>
#include<string.h>
#include<iomanip.h>
class student
{
char name[10];
int deg;
char level[7];
public:
student(char na[],int d)
{
strcpy(name,na);
deg=d;
}
char *getname(){ return name;}
friend void trans(student &s)
{
if(s.deg>=90)
strcpy(s.level,"優");
else if(s.deg>=80)
strcpy(s.level,"良");
else if(s.deg>=70)
strcpy(s.level,"中");
else if(s.deg>=60)
strcpy(s.level,"及格");
else
strcpy(s.level,"不及格");
}
void disp()
{
cout<<setw(10)<<name<<setw(6)<<deg<<setw(8)<<level<<endl;
}
};
void main()
{
student st[]={student("王華",78),student("李明",92),student("張偉",62),student("孫強",88)};
cout<<"輸出結果:"<<endl;
cout<<setw(10)<<"姓名"<<setw(6)<<"成績"<<setw(8)<<"等級"<<endl;
for(int i=0;i<4;i++)
{
trans(st[i]);
st[i].disp();
}
}
本程序執行結果如下:
輸出結果:
姓名 成績 等級
王華 78 中
李明 92 優
張偉 62 及格
孫強 88 良
05.設計一個類Sample,它有兩個私有成員A[]和n(A中元素個數),將對A[]中數據進行各種排序的函數放入到一個友元類process中。
解:
process類不包含任何數據成員,包含的公共成員函數如下:
getdata(Sample &s); 用於獲取對象s的數據
insertsort(Sample &s); 用於進行插入排序
shellsort(Sample &s); 用於進行希爾排序
bubblesort(Sample &s); 用於進行冒泡排序
quicksort(Sample &s); 用於進行快速排序
selectsort(Sample &s); 用於進行選擇排序
disp(Sample &s); 用於輸出數據
本題程序如下:
#include<iostream.h>
#define Max 100
class Sample
{
int A[Max];
int n;
friend class process;
public:
Sample(){n=0;}
};
class process
{
void qsort(Sample &s,int l,int h);
// 私有成員,由quicksort()成員調用
public:
void getdata(Sample &s);
void insertsort(Sample &s);
void shellsort(Sample &s);
void bubblesort(Sample &s);
void quicksort(Sample &s);
void selectsort(Sample &s);
void disp(Sample &s);
};
void process::getdata(Sample &s)
{
int i;
cout<<"元素個數:";
cin>>s.n;
for(i=0;i<s;i++)
{
cout<<"輸入第"<<i+1<<"個數據:";
cin>>s.A[i];
}
}
void process::insertsort(Sample &s) // 插入排序
{
int i,j,temp;
for(i=1;i<s.n;i++)
{
temp=s.A[i];
j=i-1;
while(temp<s.A[j])
{
s.A[j+1]=s.A[j];
j--;
}
s.A[j+1]=temp;
}
}
void process::shellsort(Sample &s) // 希爾排序
{
int i,j,gap,temp;
gap=s.n/2;
while(gap>0)
{
for(i=gap;i<s;i++)
{
j=i-gap;
while(j>=gap)
if(s.A[j]>s.A[j+gap])
{
temp=s.A[j];
s.A[j]=s.A[j+gap];
s.A[j+gap]=temp;
j=j-gap;
}
else j=0;
}
gap=gap/2;
}
}
void process::bubblesort(Sample &s) // 冒泡排序
{
int i,j,temp;
for(i=0;i<s.n;i++)
for(j=s.n-1;j>=i+1;j--)
if(s.A[j]<s.A[j-1])
{
temp=s.A[j];
s.a[j]=s.A[j-1];
s.A[j-1]=temp;
}
}
void process::quicksort(Sample &s) // 快速排序
{
qsort(s,0,s.n-1);
}
void process::qsort(Sample &s,int l,int h)
{
int i=l,j=h,temp;
if(l<h)
{ temp=s.A[l];
do
{
while(j>i&&s.A[j]>=temp)
j--;
if(i<j)
{
s.A[i]=s.A[j];
i++;
}
while(i<j&&s.A[i]<=temp)
i++;
if(i<j)
{
s.A[j]=s.A[i];
j--;
}
}while(i<j);
s.A[i]=temp;
qsort(s,l,j-1);
qsort(s,j+1,h);
}
}
void process::selectsort(Sample &s) // 選擇排序
{
int i,j,k,temp;
for(i=0;i<s.n;i++)
{
k=i;
for(j=i+1;j<=s.n-1;j++)
if(s.A[j]<s.A[k])
k=j;
temp=s.A[i];
s.A[i]=s.A[k];
s.A[k]=temp;
}
}
void process::disp(Sample &s)
{
for(int i=0;i<s.n;i++)
cout<<s.A[i]<<" ";
cout<<endl;
}
void main()
{
int sel;
Sample s;
process p;
p.getdata(s);
cout<<"原來序列:";
p.disp(s);
cout<<"0:插入排序 1:希爾排序 2:冒泡排序 3:快速排序 4:選擇排序 其它退出"<<endl;
cout<<"選擇排序方法:";
cin>>sel;
switch(sel)
{
case 0:
p.insertsort(s);
cout<<"插入排序結果:";
break;
case 1:
p.shellsort(s);
cout<<"希爾排序結果:";
break;
case 2:
p.bubblesort(s);
cout<<"冒泡排序結果:";
break;
case 3:
p.quicksort(s);
cout<<"快速排序結果:";
break;
case 4:
p.selectsort(s);
cout<<"選擇排序結果:";
break;
}
p.disp(s);
}
本程序的執行結果如下:
元素個數:8
輸入第1個數據: 1
輸入第2個數據: 6
輸入第3個數據: 5
輸入第4個數據: 3
輸入第5個數據: 4
輸入第6個數據: 8
輸入第7個數據: 2
輸入第8個數據: 7
原來序列: 1 6 5 3 4 8 2 7
0:插入排序 1:希爾排序 2:冒泡排序 3:快速排序 4:選擇排序 其它退出
選擇排序方法: 1
希爾排序結果: 1 2 3 4 5 6 7 8
題1.分析以下程序的執行結果
#include<iostream.h>
class Sample
{
int n;
public:
Sample(){}
Sample (int m){n=m;}
friend void square(Sample &s)
{
s.n=s.n*s.n;
}
void disp()
{
cout<<"n="<<n<<endl;
}
};
void main()
{
Sample a(10);
square(a);
a.disp();
}
解:
本題應用友元函數修改對象的數據成員。square()是一個友元函數,它將引用對象的n值進行平方計算。
所以輸出為:100
-----------------------------------------------------------
題2.分析以下程序的執行結果
#include<iostream.h>
class B;
class A
{
int i;
friend B;
void disp(){cout<<i<<endl;}
};
class B
{
public:
void set(int n)
{
A a;
a.i=n; // i是對象a的私有數據成員,在友元類可以使用
a.disp(); // disp()是對象a的私有成員函數,在友元類可以使用
}
};
void main()
{
B b;
b.set(2);
}
解:
本題說明友元類的設計方法。這裡將類B設置為類A的友元類,因此,在設計類B時可以直接使用類A的私有數據成員和成員函數。
所以輸出為: 2
-------------------------------------------------------------
題3.分析以下程序的執行結果
#include<iostream.h>
class teacher;
class student
{
char *name;
public:
student(char *s){name=s;}
friend void print(student &,teacher &);
};
class teacher
{
char *name;
public:
teacher(char *s){name=s;}
friend void print(student &,teacher &);
};
void print(student &a,teacher &b)
{
cout<<"the student is:"<<a.name<<endl;
cout<<"the teacher is:"<<b.name<<endl;
}
void main()
{
student s("Li Hu");
teacher t("Wang Ping");
print(s,t);
}
解:
student和teacher類共用一個友元函數的實現。
所以輸出為:
the student is Li Hu
the teacher is Wan Ping
--------------------------------------------------------------
題4.有一個學生類student,包括學生姓名、成績,設計一個友元類,輸出成績大於等於80分以上者。
解:
學生類student的disp()函數設計成友元函數。
本題程序如下:
#include<iostream.h>
#include<string.h>
#include<iomanip.h>
class student
{
char name[10];
int deg;
public:
student(char na[],int d)
{
strcpy(name,na);
deg=d;
}
char *getname(){ return name;}
friend void disp(student &s)
{
if(s.deg>=80)
cout<<setw(10)<<s.name<<setw(6)<<s.deg<<endl;
}
};
void main()
{
student st[]={student("王華",78),student("李明",92),student("張偉",62),student("孫強",88)};
cout<<"輸出結果:"<<endl;
cout<<setw(10)<<"姓名"<<setw(6)<<"成績"<<endl;
for(int i=0;i<4;i++)
disp(st[i]);
}
本程序的執行結果如下:
輸出結果:
姓名 成績
李明 92
孫強 88
--------------------------------------------------------------
題5.有一個向量類Vector,包括一個點的坐標位置x和y,設計兩個友元函數,實現兩個向量的加法和減法的運算
解:
本題程序如下:
#include<iostream.h>
class Vector
{
int x,y;
public:
Vector(){}
Vector(int i,int j){x=i;y=j;}
void disp()
{
cout<<"("<<x<<","<<y<<")";
}
friend Vector add(Vector &v1,Vector &v2)
{
Vector v;
v.x=v1.x+v2.x;
v.y=v1.y+v2.y;
return v;
}
friend Vector sub(Vector &v1,Vector &v2)
{
Vector v;
v.x=v1.x-v2.x;
v.y=v1.y-v2.y;
return v;
}
};
void main()
{
Vector v1(10,20),v2(4,5),v3;
v3=add(v1,v2);
cout<<"輸出結果:"<<endl;
cout<<" "; v1.disp();cout<<"+";v2.disp();
cout<<"="; v3.disp(); cout<<endl;
v3=sub(v1,v2);
cout<<" "; v1.disp(); cout<<"-";v2.disp();
cout<<"=";v3.disp(); cout<<endl;
}
本程序的執行結果如下:
輸出結果:
(10,20)+(4,5)=(14,25)
(10,20)-(4,5)=(6,15)
題6.采用友元函數的方法重新設計“引用<題8>”中的類Point,並求兩個點之間的距離。
解:
將原來求兩個點的距離的普通函數distance()改寫為友元函數即可,可以看到采用友元函數方法使得代碼更簡潔。
本題程序如下:
#include<iostream.h>
#include<math.h>
class Point
{
int x,y;
public:
Point(int i,int j){x=i;y=j;}
friend float distance(Point &p1,Point &p2);
void disp()
{
cout<<"("<<x<<","<<y<<")";
}
};
float distance(Point &p1,Point &p2) // 友元函數的實現
{
float d;
d=sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
return d;
}
void main()
{
Point p1(2,2),p2(5,5);
p1.disp(); cout<<"與"; p2.disp();
cout<<"之間距離="<<distance(p1,p2)<<endl;
}
本程序執行結果如下:
(2,2)與(5,5)之間距離=4.24264
-------------------------------------------------------
題7.設計一個日期類Date,包括日期的年份、月份和日號,編寫一個友元函數,求兩個日期之間相差的天數。
解:
該類中設計有3個友元函數;count_day()函數,它有兩個參數,第2個參數是一個標志,當其值等於1 時,計算一年的開始到某日期的天數;否則計算某日期到年尾的天數。leap()函數用於判定指定的年份是否為閏年。subs()函數用於計算兩個日期之間的天數。
本題程序如下:
#include<iostream.h>
#include<stdio.h>
class Date
{
int year;
int month;
int day;
public:
Date(int y,int m,int d)
{
year=y;month=m;day=d;
}
void disp()
{
printf("%d.%d.%d",year,month,day);
}
friend int count_day(Date &d,int);
friend int leap(int year);
friend int subs(Date &d1,Date &d2);
};
int count_day(Date &d,int flag)
{
static int day_tab[2][12]={{31,28,31,30,31,30,31,31,30,31,30,31},
{31,29,31,30,31,30,31,31,30,31,30,31}};
// 使用二維數組存放各月天數,第一行對應非閏年,第二行對應閏年
int p,i,s;
if(leap(d.year))
p=1;
else p=0;
if(flag)
{
s=d.day;
for(i=1;i<d.month;i++)
s+=day_tab[p][i-1];
}
else
{
s=day_tab[p][d.month]-d.day;
for(i=d.month+1; i<=12; i++)
s+=day_tab[p][i-1];
}
return s;
}
int leap(int year)
{
if(year%4==0&&year%100!=0year%400==0) // 是閏年
return 1;
else // 不是閏年
return 0;
}
int subs(Date &d1,Date &d2)
{
int days,day1,day2,y;
if(d1.year<d2.year)
{
days=count_day(d1,0);
for(y=d1.year+1; y<d2.year ;y++)
if(leap(y))
days+=366L;
else
days+=365L;
days+=count_day(d2,1);
}
else if(d1.year==d2.year)
{
day1=count_day(d1,1);
day2=count_day(d2,1);
days=day2-day1;
}
else
days=-1;
return days;
}
void main()
{
Date d1(2000,1,1),d2(2002,10,1);
int ds=subs(d1,d2);
printf("輸出結果:
");
if(ds>=0)
{
d1.disp(); printf("與");
d2.disp(); printf("之間有%d天
",ds);
}
else
printf("時間錯誤!
");
}
本程序的執行結果如下:
輸出結果:
2000.1.1與2002.10.1之間有1002天
-------------------------------------------------------
題8.編寫一個程序,設計一個Point類,包括學號、姓名和成績等私有數據成員,不含任何成員函數,只將main()設置為該類的友元函數。
解:
main()函數與其它的函數一樣可以設置為類的友元函數,這樣就可以在其中使用類對象的私有數據成員。
本題的程序如下:
#include<iostream.h>
class Person
{
int no;
char name[10];
int deg;
public:
friend void main();
};
void main()
{
Person obj;
cout<<"輸入學號:";
cin>>obj.no;
cout<<"姓名:";
cin>>obj.name;
cout<<"成績:";
cin>>obj.deg;
cout<<"輸出結果"<<endl;
cout<<"學生"<<obj.name<<"(學號"<<obj.no<<")成績為"<<obj.deg<<endl;
}
本程序執行結果如下:
輸入學號: 10
姓名: Zhengming
成績:88
輸出結果
學生Zhengming(學號10)成績為88
-------------------------------------------------------
題9.采用友元類的方式重新編寫“友元第04題“的程序。
解:
將原student類中的disp()成員函數和trans()友元函數作為友元類process的成員函數。其執行結果與第4題的結果完全相同。
本題程序如下:
#include<iostream.h>
#include<string.h>
#include<iomanip.h>
class student
{
char name[10];
int deg;
char level[7];
friend class process; // 說明友元類
public:
student(char na[],int d)
{
strcpy(name,na);
deg=d;
}
};
class process
{
public:
void trans(student &s)
{
if(s.deg>=90)
strcpy(s.level,"優");
else if(s.deg>=80)
strcpy(s.level,"良");
else if(s.deg>=70)
strcpy(s.level,"中");
else if(s.deg>=60)
strcpy(s.level,"及格");
else
strcpy(s.level,"不及格");
}
void disp(student &s)
{
cout<<setw(10)<<s.name<<setw(6)<<s.deg<<setw(8)<<s.level<<endl;
}
};
void main()
{
student st[]={student("王華",78),student("李明",92),student("張偉",62),student("孫強",88)};
process p;
cout<<"輸出結果:"<<"姓名"<<setw(6)<<"成績"<<setw(8)<<"等級"<<endl;
for(int i=0;i<4;i++)
{
p.trans(st[i]);
p.disp(st[i]);
}
}
*本程序執行結果為: