题 1.分析以下程序执行的结果
#include<iostream.h>
#include<stdlib.h>
class Sample
{
public:
int x,y;
Sample(){x=y=0;}
Sample(int a,int b){x=a;y=b;}
void disp()
{
cout<<"x="<<x<<",y="<<y<<endl;
}
};
void main()
{
Sample s1(2,3);
s1.disp();
}
解:本题说明了重载构造函数的定义方法。首先定义了一个类Sample,在main()中定义了它的一个对象,定义s1对象时调用其重载构造函数(x=2,y=3),然后,调用其成员函数输出数据成员。所以输出为:x=2,y=3。
注重:构造函数是唯一不能被显式调用的成员函数,它在定义类的对象时自动调用,也称为隐式调用。
--------------------------------------------------------
题 2.分析以下程序的执行结果
#include<iostream.h>
class Sample
{
int x,y;
public:
Sample(){x=y=0;}
Sample(int a,int b){x=a;y=b;}
~Sample()
{
if(x==y)
cout<<"x=y"<<endl;
else
cout<<"x!=y"<<endl;
}
void disp()
{
cout<<"x="<<x<<",y="<<y<<endl;
}
};
void main()
{
Sample s1(2,3);
s1.disp();
}
解:本题说明了析构函数的定义方法。首先定义了一个类Sample,在main()中定义了它的一个对象,定义s1对象时调用其重载构造函数(x=2,y=3),然后,调用其成员函数输出数据成员,最后在退出程序时自动调用析构函数。所以输出为:
x=2,y=3
x!=y
注重:析构函数在对象的作用域结束时被自动隐式调用。
----------------------------------------------------
题 3.分析以下程序的输出结果
#include<iostream.h>
class Sample
{
int x;
public:
Sample(int a)
{
x=a;
cout<<"constrUCting object:x="<<x<<endl;
}
};
void func(int n)
{
static Sample obj(n);
}
void main()
{
func(1);
func(10);
}
解:本题说明静态对象构造函数的调用情况,由于在func()函数中定义的对象obj是静态对象,故只被构造一次,所以输出为:
counstructing object:x=1
注重:静态对象和静态变量一样,只被构造一次。块作用域的静态变量,在首次进入到定义该静态对象的函数时,构造该静态对象,以后进入该函数时不再构造静态对象。
------------------------------------------------------
题 1.4 分析以下程序的执行结果
#include<iostream.h>
class Sample
{
int x,y;
public:
Sample(){x=y=0;}
Sample(int a,int b){x=a;y=b;}
void disp()
{
cout<<"x="<<x<<",y="<<y<<endl;
}
};
void main()
{
Sample s(2,3), *p=&s;
p->disp();
}
解:本题说明了对象指针的使用方法。这里通过指向对象的指针来调用对象的成员函数。对象指针p指向对象s,p->disp()等价于s.disp()。所以输出为: x=2,y=3.
题 1.5 分析以下程序的执行结果
#include<iostream.h>
class Sample
{
public:
int x;
int y;
void disp()
{
cout<<"x="<<x<<",y="<<y<<endl;
}
};
void main()
{
int Sample::*pc;
Sample s;
pc=&Sample::x;
s.*pc=10;
pc=&Sample::y;
s.*pc=20;
s.disp();
}
解:本题说明了类数据成员指针的使用方法。在main()中定义的pc是一个指向Sample类数据成员的指针。执行pc=&Sample::x时,pc指向数据成员x,语句s.*pc=10等价于s.x=10(为了保证该语句正确执行,Sample类中的x必须是公共成员);执行pc=&Sample::y时,pc指向数据成员y,语句s.*pc=20等价于s.y=20(同样,Sample类中的y必须是公共成员)。所以输出为: x=10,y=20。
-----------------------------------------------------
题 1.6 下面是一个类的测试程序,设计出能使用如下测试程序的类。
void main()
{
Test a;
a.init(68,55);
a.print();
}
其执行结果为:
测试结果:68-55=13
解:本题是要设计Test类,其设计方法很多,这里给出一种解法。Test类包含两个私有数据成员x、y,以及两个公共成员函数init()和print(),前者用于给数据成员赋值,后者用于x,y的减法运算和输出相应的结果。
#include<iostream.h>
class Test
{
int x,y;
public:
void init(int,int);
void print();
};
void Test::init(int i,int j)
{
x=i;y=j;
}
void Test::print()
{
cout<<"测试结果:"<<x<<"-"<<y<<"="<<x-y<<endl;
}
注重:类是一个外壳,它包含了类实例化时数据和代码的使用方法,它是一种模板,只有在定义类的对象时,才为对象分配空间,而不会为类分配空间。
------------------------------------------------------
题 1.7 设计一个Bank类,实现银行某账号的资金往来账目治理,包括建账号、存入、取出等。
解:Bank类包括私有数据成员top(当前账指针),date(日期),money(金额),rest(余额)和sum(累计余额)。另有一个构造函数和三个成员函数bankin()(处理存入账),bankout()处理取出账)和disp() (输出明细账)。
本题程序如下:
#include<stdio.h>
#include<string.h>
#define Max 100
class Bank
{
int top;
char date[Max][10]; // 日期
int money[Max]; // 金额
int rest[Max]; // 余额
static int sum; // 累计余额
public:
Bank(){top=0;}
void bankin(char d[],int m)
{
strcpy(date[top],d);
money[top]=m;
sum=sum+m;
rest[top]=sum;
top++;
}
void bankout(char d[],int m)
{
strcpy(date[top],d);
money[top]=-m;
sum=sum-m;
rest[top]=sum;
top++;
}
void disp();
};
int Bank::sum=0;
void Bank::disp()
{
int i;
printf(" 日期存入 取出余额\n");
for(i=0;i<top;i++)
{
printf("%8s",date[i]);
if(money[i]<0)
printf(" %6d",-money[i]);
else
printf("%6d ",money[i]);
printf("%6d\n",rest[i]);
}
}
void main()
{
Bank obj;
obj.bankin("2001.2.5",1000);
obj.bankin("2001.3.2",2000);
obj.bankout("2001.4.1",500);
obj.bankout("2001.4.5",800);
obj.disp();
}
本程序的执行结果如下:
日期 存入 取出 余额
2001.2.5 1000 1000
2001.3.2 2000 3000
2001.4.1 500 2500
2001.4.5 800 1700
题 1 分析以下程序的执行结果
#include<iostream.h>
class Sample
{
int x,y;
public:
Sample(){x=y=0;}
Sample(int a,int b){x=a;y=b;}
void disp()
{
cout<<"x="<<x<<",y="<<y<<endl;
}
};
void main()
{
Sample s1,s2(2,3);
s1.disp();
s2.disp();
}
解:
本题说明了构造函数的调用顺序。首先定义了一个类Sample,在main()中定义了它的两个对象,定义s1对象时调用其默认构造函数(x=0,y=0),定义s2对象时调用其重载构造函数(x=2,y=3),然后,调用各自的成员函数输出各自的数据成员。所以输出为:
x=0,y=0
x=2,y=3
-----------------------------------------------
题 2 分析以下程序执行的结果
#include<iostream.h>
class Sample
{
int x,y;
public:
Sample() {x=y=0;}
Sample(int a,int b) {x=a;y=b;}
~Sample()
{
if(x==y)
cout<<"x=y"<<endl;
else
cout<<"x!=y"<<endl;
}
void disp()
{
cout<<"x="<<x<<",y="<<y<<endl;
}
};
void main()
{
Sample s1(2,3);
s1.disp();
s1.~Sample();
}
解:
本题说明了可以显式调用析构函数。首先定义了一个类Sample,在main()中定义了它的一个对象,定义s1对象时调用其重载构造函数(x=2,y=3),然后,调用其成员函数输出数据成员,然后调用一次析构函数,最后在退出程序时又自动调用析构函数,所以输出为:
x=2,y=3
x!=y
x!=y
注重:析构函数不同于构造函数,析构函数既能被显式调用,也能被隐式调用。
----------------------------------------------------
题 3 分析以下程序的执行结果
#include<iostream.h>
class Sample
{
int x,y;
public:
Sample() {x=y=0;}
Sample(int a,int b) {x=a;y=b;}
~Sample()
{
if(x==y)
cout<<"x=y"<<endl;
else
cout<<"x!=y"<<endl;
}
void disp()
{
cout<<"x="<<x<<",y="<<y<<endl;
}
};
void main()
{
Sample s1,s2(2,3);
s1.disp();
s2.disp();
}
解:
本题说明了析构函数的调用顺序,这里定义了两个对象,先顺序调用s1和s2对象的构造函数,再调用各自的成员函数disp(),最后顺序调用s2和s1的析构函数。所以输出为:
x=0,y=0
x=2,y=3
x!=y
x=y
题4.分析以下程序的执行结果
#include<iostream.h>
#include<stdlib.h>
class Sample
{
public:
int x,y;
Sample(){x=y=0;}
Sample(int a,int b){x=a;y=b;}
void disp()
{
cout<<"x="<<x<<",y="<<y<<endl;
}
~Sample()
{
if(x==y)
cout<<"x=y"<<endl;
else
cout<<"x!=y"<<endl;
}
};
void main()
{
Sample s1(2,3);
s1.disp();
if(s1.x==2)
exit(0);
}
解:
本题说明了非正常退出程序时析构函数调用的情况。定义了一个类Sample,在main()中定义了它的一个对象,定义s1对象时调用其重载构造函数(x=2,y=3),然后,调用其成员函数输出数据成员,由于if条件成立,执行exit非正常退出,不会隐式调用析构函数,所以输出为:
x=2,y=3
注重:假如程序使用exit、abort非正常退出,不会隐式调用析构函数,这样造成对象申请资源无法回收,从而导致操作系统的资源紧张而使应用程序无法运行。因此在通常情况下,应使用return语句正常退出。
-----------------------------------------------
题5.分析以下程序的执行结果
#include<iostream.h>
class Sample
{
int x,y;
public:
Sample(){x=y=0;}
Sample(int a,int b){x=a,y=b;}
~Sample()
{
if(x==y)
cout<<"x=y"<<endl;
else
cout<<"x!=y"<<endl;
}
void disp()
{
cout<<"x="<<x<<",y="<<y<<endl;
}
};
void main()
{
Sample(2,3);
}
解:
本题说明了常量对象的构造函数和析构函数的调用情况。在main()中定义了一个常量对象,常量对象在构造之后立即析构。所以输出为:
x!=y
注重:常量对象的作用域不是整个main()函数,而是仅限于包含该常量的值表达式,表达式一旦计算完成,其中的对象就按构造的逆序析构。
--------------------------------------------------------
题6.分析以下程序的执行结果
#include<iostream.h>
class Sample
{
public:
Sample();
Sample(int);
~Sample();
void display();
protected:
int x;
};
Sample::Sample()
{
x=0;
cout<<"constructing normally\n";
}
Sample::Sample(int m)
{
x=m;
cout<<"constructing with a number:"<<x<<endl;
}
void Sample::display()
{
cout<<"display a number:"<<x<<endl;
}
Sample::~Sample()
{
cout<<"destructing\n";
}
void main()
{
Sample obj1;
Sample obj2(20);
obj1.display();
obj2.display();
}
解:
本题构造函数与析构函数的调用顺序。这里定义了两个对象,先顺序调用obj1和obj2对象的构造函数,再调用各自的成员函数disp(),最后顺序调用obj2和obj1的析构函数。所以输出为:
constructing nomally
constructing with a number:20
display a number:0
display a number:20
destructing
destructing
--------------------------------------------------------
题7.分析以下程序的执行结果
#include<iostream.h>
class Sample
{
int n;
static int sum;
public:
Sample(int x){n=x;}
void add(){sum+=n;}
void disp()
{
cout<<"n="<<n<<",sum="<<sum<<endl;
}
};
int Sample::sum=0; // 静态数据成员赋初值
void main()
{
Sample a(2),b(3),c(5);
a.add();
a.disp();
b.add();
b.disp();
c.add();
c.disp();
}
解:
本题说明静态数据成员的使用方法。在类中定义了一个静态数据成员sum,在main()之前给它赋初值0,然后在main()中定义了三个对象,并执行各自的add()和disp()方法。所以输出为:
n=2,sum=2
n=3,sum=5
n=5,sum=10
注重:静态数据成员脱离具体的对象独立存在,其存储单元不是任何对象存储空间的一部分,但逻辑上所有对象都共享这一存储单元,对静态数据成员的任何操作都会访问这一存储单元,从而影响这一存储单元的所有对象。所以说静态数据成员不是对象成员,在引用时不需要用对象名。
题8.分析以下程序执行的结果
#include<iostream.h>
class Sample
{
int A;
static int B;
public:
Sample(int a){A=a,B+=a;}
static void func(Sample s);
};
void Sample::func(Sample s)
{
cout<<"A="<<s.A<<",B="<<B<<endl;
}
int Sample::B=0;
void main()
{
Sample s1(2),s2(5);
Sample::func(s1);
Sample::func(s2);
}
解:
本题说明了静态成员函数的使用方法。其中的数据成员B是静态数据成员,求B之值是在构造函数中进行的。所以输出为:
A=2,B=7
A=5,B=7
注重:静态成员函数与静态数据成员一样,也不是对象成员。静态成员函数的调用不同于普通的成员函数。在静态成员函数的实现中,引用类的非静态数据成员是通过对象进行的,如本题中s.A,引用类的静态数据成员是直接进行的,如本题中的B。
-----------------------------------------------------------
题9.分析以下程序的执行结果
#include<iostream.h>
class Sample
{
char c1,c2;
public:
Sample(char a){c2=(c1=a)-32;}
void disp()
{
cout<<c1<<"转换为"<<c2<<endl;
}
};
void main()
{
Sample a('a'),b('b');
a.disp();
b.disp();
}
解:
本题说明了构造函数的调用方法。对于对象定义<对象名>(c),构造函数执行c1=c,c2=c-32(小写转大写)。所以输出为:
a转换为A
b转换为B
------------------------------------------------------------
题10.分析以下程序执行的结果
#include<iostream.h>
class Sample
{
int x,y;
public:
Sample(){x=y=0;}
Sample(int a,int b){x=a;y=b;}
void disp()
{
cout<<"x="<<x<<",y="<<y<<endl;
}
};
void main()
{
Sample s1,s2(1,2),s3(10,20);
Sample *pa[3]={&s1,&s2,&s3};
for(int i=0;i<3;i++)
pa[i]->disp();
}
解:
本题说明对象指针数组赋初值方法。定义三个对象和一个对象指针数组,通过赋初值使后者的元素分别指向前面三个对象,然后使用for语句循环调用各个对象的disp()成员函数。所以输出为:
x=0,y=0
x=1,y=2
x=10,y=20
----------------------------------------------------------
题11. 分析以下程序的执行结果
#include<iostream.h>
class Sample
{
int x,y;
public:
Sample(){x=y=0;}
Sample(int a,int b){x=a,y=b;}
void disp()
{
cout<<"x="<<x<<",y="<<y<<endl;
}
};
void main()
{
Sample s1,s2(1,2),s3(10,20);
Sample *Pa[3];
Pa[0]=&s1;
Pa[1]=&s2;
Pa[2]=&s3;
for(int i=0;i<3;i++)
Pa[i]->disp();
}
解:
本题说明对象指针数组的赋值方法。定义三个对象和一个对象指针数组,通过赋值语句使后者的元素分别指向前面的三个对象(而不是采用上题的赋初值方法),然后使用for语句循环调用各个对象的disp()成员函数。所以输出为:
x=0,y=0
x=1,y=2
x=10,y=20
题12. 分析以下程序的执行结果
#include<iostream.h>
class Sample
{
public:
int x;
int y;
void disp()
{
cout<<"x="<<x<<",y="<<y<<endl;
}
};
void main()
{
int Sample::*pc;
Sample s,*p=&s;
pc=&Sample::x;
p->*pc=10;
pc=&Sample::y;
p->*pc=20;
p->disp();
}
解:
本题说明了类数据成员指针的使用方法。这里通过指向对象的指针来给类数据成员赋值,其原理与上题相似。输出为:
x=10,y=20
------------------------------------------------------
题13.分析以下程序的执行结果
#include<iostream.h>
class Sample
{
int x;
int y;
public:
Sample(int a,int b)
{
x=a;y=b;
}
int getx(){return x;}
int gety(){return y;}
};
void main()
{
int (Sample::*fp)();
fp=&Sample::getx;
Sample s(2,7);
int v=(s.*fp)();
fp=&Sample::gety;
int t=(s.*fp)();
cout<<"v="<<v<<",t="<<t<<endl;
}
解:
本题说明了类成员函数指针的使用方法。在main()中定义的fp是一个指向Sample类成员函数的指针。执行fp=Sample::getx后。fp指向成员函数getx(),int v=(s.*fp)()语句等价于int v.getx(),v=x=2;执行fp=Sample::gety之后,fp指向成员函数gety(),int t=(s.*fp)()语句等价于int t=s.gety(),t=x=7。所以输出为:
v=2,t=7
------------------------------------------------------
题14 .分析以下程序的执行结果
#include<iostream.h>
class Sample
{
int x;
int y;
public:
Sample(int a,int b)
{
x=a;y=b;
}
int getx(){return x;}
int gety(){return y;}
};
void main()
{
int (Sample::*fp)();
fp=&Sample::getx;
Sample s(2,7),*p=&s;
int v=(p->*fp)();
fp=&Sample::gety;
int t=(p->*fp)();
cout<<"v="<<v<<",t="<<t<<endl;
}
解:
本题说明了类成员函数指针的使用方法。这里通过指向对象的指针来调用指向类成员函数的指针,其原理与上题相似。输出仍为:
v=2,t=7
-----------------------------------------------------
题15.设计一个立方体类Box,它能计算并输出立方体的体积和表面积。
解:
Box类包含三个私有数据成员a(立方体边长)、volume(体积)和area(表面积),另有两个构造函数以及seta()(设置立方体边长)、getvolume()(计算体积)、getarea()(计算表面积)和disp()(输出结果)。
本题程序如下:
#include<iostream.h>
class Box
{
float a;
float volume;
float area;
public:
Box(){}
Box(float r){a=r;}
void seta(float r){a=r;}
void getvolume(){volume=a*a*a;}
void getarea(){area=6*a*a;}
void disp()
{
cout<<"体积:"<<volume<<",表面积:"<<area<<endl;
}
};
void main()
{
Box obj1(4.5),obj2;
obj2.seta(6.4);
obj1.getvolume();
obj1.getarea();
cout<<"obj1=>";
obj1.disp();
obj2.getvolume();
obj2.getarea();
cout<<"obj2=>";
obj2.disp();
}
本程序的执行结果如下:
obj1=>体积:91.125, 表面积:121.5
obj2=>体积:262.144,表面积:245.76
题16.创建一个employee类,该类中有字符数组,表示姓名、街道地址、市、省和邮政编码。把表示构造函数、changname()、display()的函数的原型放在类定义中,构造函数初始化每个成员,display()函数把完整的对象数据打印出来。其中的数据成员是保护的,函数是公共的。
解:
#include<iostream.h>
#include<string.h>
class employee
{
protected:
char name[10]; // 姓名
char street[20]; // 街道地址
char city[10]; // 市
char prov[10]; // 省
char post[7]; // 邮政编码
int no; // 记录序号
public:
employee(char [],char [],char [],char [],char [],int);
void changename(char str[]);
void display();
};
employee::employee(char n[],char s[],char c[],char p1[],char p2[],int num)
{
strcpy(name,n);
strcpy(street,s);
strcpy(city,c);
strcpy(prov,p1);
strcpy(post,p2);
no=num;
}
void employee::changename(char n[])
{
strcpy(name,n);
}
void employee::display()
{
cout<<"输出记录 "<<no<<endl;
cout<<" 姓名:"<<name<<endl;
cout<<"街道地址:"<<street<<endl;
cout<<" 市:"<<city<<endl;
cout<<" 省:"<<prov<<endl;
cout<<"邮政编码"<<post<<endl;
}
void main()
{
employee obj1("王华","中华路15号","武汉市","湖北省","430070",1);
employee obj2("杨丽","天津路30号","南京市","江苏市","210020",2);
obj1.display();
obj2.display();
}
本程序的执行结果如下:
输出记录1
姓名:王华
街道地址:中华路15号
市:武汉市
省:湖北省
邮政编码:430070
输出记录2
姓名:杨丽
街道地址:天津路30号
市:南京市
省:江苏省
邮政编码:210020
-------------------------------------------------------------
题17.修改前一题的类,将姓名构成类name,其名和姓在该类中为保护数据成员,其构造函数为接收一个指向完整姓名字符串的指针,其display()函数输出姓名。然后将employee类中的姓名成员(字符数组)换成name类对象。编制主函数如下:
void main()
{
employee obj("王华","中华路15号"."武汉市","湖北省","430070",1);
obj.display();
obj.changename("王国强");
obj.display();
}
解:
#include<iostream.h>
#include<string.h>
class name
{
protected:
char fname[4]; // 姓
char sname[6]; // 名
public:
name(){}
name(char *);
void changename(char *);
void display();
};
class employee
{
protected:
name na; // 姓名
char street[20]; // 街道地址
char city[10]; // 市
char prov[10]; // 省
char post[7]; // 邮政编码
int no; // 记录序号
public:
employee(char [],char [],char [],char [],char [],int);
void changename(char str[]);
void display();
};
name::name(char *p)
{
int i=0;
while(*p!=' ')
fname[i++]=*p++;
fname[i]='\0';
i=0;
p++;
while(*p!='\0')
sname[i++]=*p++;
sname[i]='\0';
}
void name::changename(char *p)
{
int i=0;
while(*p!=' ')
fname[i++]=*p++;
fname[i]='\0';
i=0;
p++;
while(*p!='\0')
sname[i++]=*p++;
sname[i]='\0';
}
void name::display()
{
cout<<fname<<sname;
}
employee::employee(char n[],char s[],char c[],char p1[],char p2[],int num)
{
changename(n);
strcpy(street,s);
strcpy(city,c);
strcpy(prov,p1);
strcpy(post,p2);
no=num;
}
void employee::changename(char n[])
{
na.changename(n);
}
void employee::display()
{
cout<<post<<"\n\n";
cout<<"\t"<<prov<<city<<street<<"\n\n";
cout<<"\t\t";
na.display();
cout<<"(收)"<<"\n\n";
}
void main()
{
employee obj("王华","中华路15号","武汉市","湖北省","430070",1);
obj.display();
obj.changename("王国强");
obj.display();
}
本程序的执行结果如下:
430070
湖北省武汉市中华路15号
王 华(收)
430070
湖北省武汉市中华路15号
王国强(收)
---------------------------------------------------------
题18.编写一个程序,在已设置好若干个用户名/口令后,通过输入用户名,查找对应的口令,连续执行这一过程直到用户输入结束标记(“end“)为止。
解:
设计一个User类,数据成员有User和pass两个字符数组,存储用户名和口令,另有一个构造函数和getuaer()、getpass()两个成员函数,用于获取用户名和口令。在main()中设计一个对象数组ua,当用户输入一个用户名后,在ua中查找,找到后输出对应的口令,找不到时输出相应的提示信息。
本题程序如下:
#include<iostream.h>
#include<string.h>
class User
{
char user[10];
char pass[7];
public:
User(char [],char []);
char *getuser();
char *getpass();
};
User::User(char u[],char p[])
{
strcpy(user,u);
strcpy(pass,p);
}
char *User::getuser()
{
return user;
}
char *User::getpass()
{
return pass;
}
void main()
{
User ua[]={User("Li","123456"),User("wang","654321"),
User("Chen","213412"),User("Xu","878616"),
User("Ma","876574"),User("Song","666666")};
char name[10];
while(1)
{
cout<<"输入用户名:";
cin>>name;
if(strcmp(name,"end")==0)
break;
for(int i=0;i<6;i++)
if(strcmp(name,ua[i].getuser())==0)
{
cout<<" 用户口令:"<<ua[i].getpass()<<endl;
break;
}
if(i==6)
cout<<" 用户名不存在"<<endl;
}
}
本程序的执行结果如下:
输入用户名: Li
用户口令:123456
输入用户名:Wang
用户口令:654321
输入用户名:He
用户名不存在
输入用户名:end
题19.编写一个程序,输入N个学生数据,包括学号、姓名、成绩,要求输出这些学生数据并计算平均分。
解:
设计一个学生类Stud,除了包括no(学号)、name(姓名)和deg(成绩)数据成员外,有两个静态变量sum和num,分别存放总分和人数,另有两个普通成员函数setdata()和disp(),分别用于给数据成员赋值和输出数据成员的值,另有一个静态成员函数avg(),它用于计算平均分。在main()函数中定义了一个对象数组用于存储输入的学生数据。
本题程序如下:
#include<stdio.h>
#include<string.h>
#define N 3
class Stud
{
int no;
char name[10];
int deg;
static int num;
static int sum;
public:
void setdata(int n,char na[],int d)
{
no=n; deg=d;
strcpy(name,na);
sum+=d;
num++;
}
static double avg()
{
return sum/num;
}
void disp()
{
printf(" %-5d%-8s%3d\n",no,name,deg);
}
};
int Stud::sum=0;
int Stud::num=0;
void main()
{
Stud st[N];
int i,n,d;
char na[10];
for(i=0;i<N;i++)
{
printf("输入学号 姓名 成绩:");
scanf("%d%s%d",&n,na,&d);
st[i].setdata(n,na,d);
}
printf("输出数据\n");
printf(" 学号 姓名 成绩\n");
for(i=0;i<N;i++)
st[i].disp();
printf(" 平均分=%g\n\n",Stud::avg());
}
本程序的执行结果如下:
输入学号 姓名 成绩: 1 stud1 89
输入学号 姓名 成绩: 2 stud2 78
输入学号 姓名 成绩: 3 stud 84
输出数据
学号 姓名 成绩
1 stud1 89
2 stud2 78
3 stud3 84
平均分=83
-------------------------------------------------------
题20.编写一个程序,已有若干个学生数据,这些数据包括学号、姓名、语文成绩、数学成绩和英语成绩,求各门功课的平均分。要求设计不同的成员函数求各门课程的平均分,并使用成员函数指针调用它们。
解:
设计一个学生类student,包括no(学号)、name(姓名)、deg1(语文成绩)、deg2(数学成绩)、deg3(英语成绩)数据成员和三个静态数据成员sum1(累计语文总分)、sum2(累计数学部分)、sum3(累计英语总分);另外有一个构造函数和三个求平均分的成员函数和一个disp()成员函数。
本题程序如下:
#include<stdio.h>
#include<string.h>
#define N 4
class student
{
int no;
char name[10];
int deg1; // 语文成绩
int deg2; // 数学成绩
int deg3; // 英语成绩
static int sum1; // 语文总分
static int sum2; // 数学总分
static int sum3; // 英语总分
public:
student(int n,char na[],int d1,int d2,int d3)
{
no=n;
strcpy(name,na);
deg1=d1;deg2=d2;deg3=d3;
sum1+=deg1;sum2+=deg2;sum3+=deg3;
}
double avg1(){return (sum1*1.0)/N;}
double avg2(){return (sum2*1.0)/N;}
double avg3(){return (sum3*1.0)/N;}
void disp()
{
printf(" %4d%10s%6d%6d%6d\n",no,name,deg1,deg2,deg3);
}
};
int student::sum1=0;
int student::sum2=0;
int student::sum3=0;
void main()
{
double (student::*fp)(); // 定义成员函数指针
student s1(1,"Li",67,89,90);
student s2(2,"Ma",67,89,90);
student s3(3,"Zheng",67,89,90);
student s4(4,"Chen",67,89,90);
printf("输出结果\n");
s1.disp();
s2.disp();
s3.disp();
s4.disp();
fp=student::avg1;
printf(" 语文平均分:%g\n",(s1.*fp)());
fp=student::avg2;
printf(" 数学平均分:%g\n",(s1.*fp)());
fp=student::avg3;
printf(" 英语平均分:%g\n",(s1.*fp)());
}
本程序的执行结果如下:
输出结果
1 Li 67 89 90
2 M 89 89 90
3 Zheng 67 89 90
4 Chen 67 89 90
语文平均分:67
数学平均分:89
英语平均分:90
--------------------------------------------------------
题21.编写一个程序,输入N个学生数据,包括学号、姓名、成绩,要求只输出成绩在80~89分的学生数据。
解:
设计一个学生类Stud,包括no(学号)、name(姓名)和deg(成绩)数据成员,另有两个普通成员函数setdata()和disp(),前者用于设置对象数据,后者用于只输出成绩在80~89分数段的学生数据。在main()函数中定义了一个对象数组,用于存储输入的学生数据。
本题程序如下:
#include<stdio.h>
#include<string.h>
#define N 3
class Stud
{
int no;
char name[10];
int deg;
public:
void setdata(int n,char na[],int d)
{
no=n; deg=d;
strcpy(name,na);
}
void disp()
{
if(deg>=80&°<=89)
printf(" %-5d%-8s%3d\n",no,name,deg);
}
};
void main()
{
Stud st[N];
int i,n,d;
char na[10];
for(i=0;i<N;i++)
{
printf("输入学号 姓名 成绩:");
scanf("%d%s%d",&n,na,&d);
st[i].setdata(n,na,d);
}
printf("输出数据\n");
printf(" 学号 姓名 成绩\n");
for(i=0;i<N;i++)
st[i].disp();
}
本程序执行结果如下:
输入学号 姓名 成绩: 1 stud1 78
输入学号 姓名 成绩: 2 stud2 85
输入学号 姓名 成绩: 3 stud3 89
输出数据
学号 姓名 成绩
2 stud2 85
3 stud3 89