程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++習題與解析-友元

C++習題與解析-友元

編輯:C++入門知識
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]);
  }
  }
  
  *本程序執行結果為:
  
  
 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved