题 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
|