C++习题与解析-友元

2016-02-19 18:01 94 1 收藏

清醒时做事,糊涂时读书,大怒时睡觉,无聊时关注图老师为大家准备的精彩内容。下面为大家推荐C++习题与解析-友元,无聊中的都看过来。

【 tulaoshi.com - 编程语言 】

01.分析以下程序的执行结果
  #includeiostream.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);
  coutadd(s1,s2)endl;
  }
  
  解:
  本题说明了友元函数的使用方法。add()是一个友元函数,它返回两个引用对象的n值之和。
  所以输出为: 30
  
  注重:友元函数不是类的成元函数
  
  ----------------------------------------------------
  
  02.分析以下程序的执行结果
  #includeiostream.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);
  couta.get()",";
  a.set(b);
  couta.get()endl;
  }
  
  解:
  本题说明友元类的使用方法。这里将类A设置为类B的友元类,因此,类A的所有成员函数均为类B的友元函数。通过调用a.set(b)将b对象的i值赋给a对象的i值。
  所以输出为:1,2
  
  -------------------------------------------------
  
  03.有一个学生类student,包括学生姓名、成绩,设计一个友元函数,比较两个学生成绩的高低,并求出最高分和最低分的学生。
  解:
  #includeiostream.h
  #includestring.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.degs2.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;i4;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:不及格。
  解:
  #includeiostream.h
  #includestring.h
  #includeiomanip.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()
  {
  coutsetw(10)namesetw(6)degsetw(8)levelendl;
  }
  };
  void main()
  {
  student st[]={student("王华",78),student("李明",92),student("张伟",62),student("孙强",88)};
  cout"输出结果:"endl;
  coutsetw(10)"姓名"setw(6)"成绩"setw(8)"等级"endl;
  for(int i=0;i4;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); 用于输出数据
  
  本题程序如下:
  #includeiostream.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"元素个数:";
  cins.n;
  for(i=0;is;i++)
  {
  cout"输入第"i+1"个数据:";
  cins.A[i];
  }
  }
  void process::insertsort(Sample &s) // 插入排序
  {
  int i,j,temp;
  for(i=1;is.n;i++)
  {
  temp=s.A[i];
  j=i-1;
  while(temps.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(gap0)
  {
  for(i=gap;is;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;is.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(lh)
  { temp=s.A[l];
  do
  {
  while(ji&&s.A[j]=temp)
  j--;
  if(ij)
  {
  s.A[i]=s.A[j];
  i++;
  }
  while(ij&&s.A[i]=temp)
  i++;
  if(ij)
  {
  s.A[j]=s.A[i];
  j--;
  }
  }while(ij);
  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;is.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;is.n;i++)
  couts.A[i]" ";
  coutendl;
  }
  void main()
  {
  int sel;
  Sample s;
  process p;
  p.getdata(s);
  cout"原来序列:";
  p.disp(s);
  cout"0:插入排序 1:希尔排序 2:冒泡排序 3:快速排序 4:选择排序 其它退出"endl;
  cout"选择排序方法:";
  cinsel;
  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.分析以下程序的执行结果
  #includeiostream.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="nendl;
  }
  };
  void main()
  {
  Sample a(10);
  square(a);
  a.disp();
  }
  
  解:
  本题应用友元函数修改对象的数据成员。square()是一个友元函数,它将引用对象的n值进行平方计算。
  所以输出为:100
  -----------------------------------------------------------
  
  题2.分析以下程序的执行结果
  #includeiostream.h
  class B;
  class A
  {
  int i;
  friend B;
  void disp(){coutiendl;}
  };
  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.分析以下程序的执行结果
  #includeiostream.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.nameendl;
  cout"the teacher is:"b.nameendl;
  }
  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()函数设计成友元函数。
  本题程序如下:
  #includeiostream.h
  #includestring.h
  #includeiomanip.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)
  coutsetw(10)s.namesetw(6)s.degendl;
  }
  };
  void main()
  {
  student st[]={student("王华",78),student("李明",92),student("张伟",62),student("孙强",88)};
  cout"输出结果:"endl;
  coutsetw(10)"姓名"setw(6)"成绩"endl;
  for(int i=0;i4;i++)
  disp(st[i]);
  }
  
  本程序的执行结果如下:
  输出结果:
  姓名 成绩
  李明 92
  孙强 88
  
  
  --------------------------------------------------------------
  
  题5.有一个向量类Vector,包括一个点的坐标位置x和y,设计两个友元函数,实现两个向量的加法和减法的运算
  解:
  本题程序如下:
  #includeiostream.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(); coutendl;
  v3=sub(v1,v2);
  cout" "; v1.disp(); cout"-";v2.disp();
  cout"=";v3.disp(); coutendl;
  }
  
  本程序的执行结果如下:
  输出结果:
  (10,20)+(4,5)=(14,25)
  (10,20)-(4,5)=(6,15)
  
   题6.采用友元函数的方法重新设计“引用题8”中的类Point,并求两个点之间的距离。
  解:
  将原来求两个点的距离的普通函数distance()改写为友元函数即可,可以看到采用友元函数方法使得代码更简洁。
  本题程序如下:
  #includeiostream.h
  #includemath.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()函数用于计算两个日期之间的天数。
  本题程序如下:
  #includeiostream.h
  #includestdio.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;id.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.yeard2.year)
  {
  days=count_day(d1,0);
  for(y=d1.year+1; yd2.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()函数与其它的函数一样可以设置为类的友元函数,这样就可以在其中使用类对象的私有数据成员。
  本题的程序如下:
  #includeiostream.h
  class Person
  {
  int no;
  char name[10];
  int deg;
  public:
  friend void main();
  };
  void main()
  {
  Person obj;
  cout"输入学号:";
  cinobj.no;
  cout"姓名:";
  cinobj.name;
  cout"成绩:";
  cinobj.deg;
  cout"输出结果"endl;
  cout"学生"obj.name"(学号"obj.no")成绩为"obj.degendl;
  }
  
  本程序执行结果如下:
  输入学号: 10
  姓名: Zhengming
  成绩:88
  输出结果
  学生Zhengming(学号10)成绩为88
  
  -------------------------------------------------------
  
  题9.采用友元类的方式重新编写“友元第04题“的程序。
  解:
  将原student类中的disp()成员函数和trans()友元函数作为友元类process的成员函数。其执行结果与第4题的结果完全相同。
  本题程序如下:
  #includeiostream.h
  #includestring.h
  #includeiomanip.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)
  {
  coutsetw(10)s.namesetw(6)s.degsetw(8)s.levelendl;
  }
  };
  void main()
  {
  student st[]={student("王华",78),student("李明",92),student("张伟",62),student("孙强",88)};
  process p;
  cout"输出结果:""姓名"setw(6)"成绩"setw(8)"等级"endl;
  for(int i=0;i4;i++)
  {
  p.trans(st[i]);
  p.disp(st[i]);
  }
  }
  
  *本程序执行结果为:
  
  

来源:https://www.tulaoshi.com/n/20160219/1616627.html

延伸阅读
C++
/*p129*/#include class CComplex{public: CCpomplex(double r=0,double i=0) { realPart=r; imagePart=i; } void print() { cout /*p129*/#include class CComplex{public: CCpomplex(double r=0,double i=0) { realPart=r; imagePart=i; } void print() { cout
值类型是一种轻量级的C++/CLI类机制,非常适合于小型的数据结构,且从语义的角度来看,与数值(Value)类似。 与之相比,引用类型的实例--包括那些声明在堆栈上的,是由垃圾回收器治理的,而值类型的实例却不是。一般来说,一个值类较好的实现应只有一些数据成员,而不需要继续性,这样,在函数传递及返回值、或是赋值操作时,不...
一、绪论 当微软推出VS.NET7实现了可扩展的托管C++后,C++程序员们反映不一。尽管大部分的程序员对于能够继续使用C++感到很欣慰,但几乎所有的人对于托管C++提供的晦涩语法感到很痛苦。微软明显从反馈中感觉到托管C++不是那么成功。 2003年10月6日,ECMA(欧洲计算机制造商协会)宣布成立专家组,负责结合ISO标准C++与通用语言,开发一个可...
本试题仅用于考查C++/C程序员的基本编程技能。内容限于C++/C常用语法,不涉及数据结构、算法以及深奥的语法。考试成绩能反映出考生的编程质量以及对C++/C的理解程度,但不能反映考生的智力和软件开发能力。 笔试时间90分钟。请考生认真答题,切勿轻视。 一、请填写BOOL , float, 指针变量 与零值比较的 if 语句。(10分) ...
C++中,成员指针是最为复杂的语法结构。但在事件驱动和多线程应用中被广泛用于调用回叫函数。在多线程应用中,每个线程都通过指向成员函数的指针来调用该函数。在这样的应用中,如果不用成员指针,编程是非常困难的。 刚遇到这种语法时也许会让你止步不前。但你会发现,使用恰当的类型定义之后,复杂的语法是可以简化的。本文引导你了解成...

经验教程

473

收藏

31
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部