前言
做题有些感觉了,话不多说,开始干!
一、第四套 操作题考试题库试题
1、基本操作题
修改下列程序的错误,使程序的输出结果为(4,4)。
代码如下(示例):
// proj1.cpp
#include <iostream>
using namespace std;
class Point {
public:
// ERROR ********found********
Point(double x, double y) _x(x), _y(y) {
}
//改为Point(double x, double y): _x(x), _y(y)或者Point(double x, double y) {_x(x), _y(y);}
double GetX() const {
return _x; }
double GetY() const {
return _y; }
// ERROR ********found********
void Move(double xOff, double yOff) const //把const去掉
{
_x += xOff; _y += yOff; }
protected:
double _x, _y;
};
int main()
{
Point pt(1.5, 2.5);
pt.Move(2.5, 1.5);
// ERROR ********found******** 以下语句输出pt成员_x和_y的值
cout << '(' << pt._x << ',' << pt._y << ')' << endl;
//改为cout << '(' << pt._GetX() << ',' << pt._GetY() << ')' << endl;
return 0;
}
解题思路
1、考查构造函数的成员初始化列表的语法,在成员列表之前必须加“:”,C++构造函数成员初始化是一个知其然但不知其所以然的知识点,之前我就在找这方面的资料,明白了但还不是特别清晰,我先不深入的解释,在这道题中,既可以用冒号初始化,也可以用函数体初始化,记住其初始化的写法即可,但两者实际上是有区别的这里先不做区分。
2、成员函数const的使用,看Move函数的函数体:{ _x += xOff; _y += yOff; },可以看到Point类的两个私有成员_x和_y的值都发生了变化,因此Move函数不能使用const,const只能用在函数内不改变类的成员的值时才能使用。
3、这个之前做题也遇到过,私有成员_x和_y不能被类外函数调用,题目要求输出pt成员_x和_y的值,可以通过Point类中的double GetX() const { return _x; } / double GetY() const { return _y; }来得到。
2、简单应用题
如下程序定义了Base1类、Base2类、和Derived类。
Base1类:是一个抽象类,其类体中声明了纯虚函数Show。
Base2类:构造函数负责动态分配一个字符数组,并将形参指向的字符串复制到该数组中,复制功能要求通过调用strcpy函数来实现。
Derived类:以公有继承方式继承Base1类,以私有继承方式继承Base2类。Derived类的构造函数的成员初始化列表中调用Base类的构造函数。
在横线填写合适代码,完成上述所说各个类的功能,此程序的正确输出结果应为:
I’am a derived class
代码如下(示例):
// proj2.cpp
#include <iostream>
#include <cstring>
using namespace std;
class Base1 {
public:
//********found******** 下列语句需要声明纯虚函数Show
__________;//应填virtual void Show() = 0
};
class Base2 {
protected:
char * _p;
Base2(const char *s)
{
_p = new char[strlen(s)+1];
//********found******** 下列语句将形参指向的字符串常量复制到该类的字符数组中
__________;//应填strcpy(_p,s)
}
~Base2() {
delete [] _p; }
};
//********found******** Derived类公有继承Base1,私有继承Base2类
class Derived : __________ //应填publish Base1,private Base2
{
public:
//********found******** 以下构造函数调用Base2类构造函数
Derived(const char *s) : __________//应填Base2(s)
{
}
void Show()
{
cout << _p << endl; }
};
int main()
{
Base1 *pb = new Derived("I'm a derived class.");
pb->Show();
delete pb;
return 0;
}
解题思路
1、题目要求声明纯虚函数Show,因此首先看Base1类的派生类Derived类中Show函数的定义:
void Show()
{ cout << _p << endl; }
根据纯虚函数的声明格式:virtual<类型><函数名>(<参数表>)=0;
只要在void前加上virtual,在()后加上=0;再把函数体去掉就可以了,即 virtual void Show() = 0。注意纯虚函数和虚函数的区别,虚函数不能添加=0。”=0“并不表示函数返回值为0,它只起形式上的作用,告诉编译系统这是纯虚函数。
2、字符串赋值语句,题目要求将形参指向的字符串常量复制到该类的字符数组中。即把s复制给_p,直接使用语句strcpy(_p,s);就可以了,strcpy为系统提供的字符串复制函数。
3、是派生类的声明,题目要求Derived类:以公有继承方式继承Base1类,以私有继承方式继承Base2类。共有继承使用public,保护继承protect,私有继承private,如果一个类同时继承多个基类时,各个基类之间用”,“分开。
4、派生类的构造函数,定义派生类的构造函数时要使用成员列表对基类初始化。基类1:Base1类,没有构造函数,不需要使用参数。基类2:Base2类,有构造函数: Base2(const char *s),因此需要成员列表:Derived(const char *s) : Base2(s)。
三、综合应用题
如下程序,其功能是从文本文件in.dat中读取全部整数,将整数序列存放到intArray类的对象myArray中,然后对整数序列按非递减序列,最后由函数writeToFile选择序列中的部分数据输出到文件out.dat中,in.dat中整数个数不大于300个。
在空区域内,写入程序实现对整数序列按非递减排序,并将结果在屏幕上输出。
代码如下(示例):
// proj3.cpp
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;
class intArray
{
private:
int *array; //整数序列首地址
int length; //序列中的整数个数
public:
//构造函数,从文件中读取数据用于初始化新对象。参数是文件名。
intArray(char *filename);
void sort(); //对整数序列按非递减排序
~intArray();
void writeToFile(char *filename);
};
intArray::intArray(char *filename)
{
ifstream myFile(filename);
int len=300;
array=new int[len];
length=0;
while(myFile>>array[length++]);
length--;
myFile.close();
}
void intArray::sort(){
//*************333***********
for(int i=0;i<length;i++)//遍历整个数组
for(int j=i;j<length;++j) //从i++遍历整个数组
if(array[i]>array[j])//如果array[i]>array[j],把array[i]与array[j]进行交换
{
int temp;定义一个临时变量temp
temp=array[i];//把array[i]值放到变量temp
array[i]=array[j];//把array[j]值赋给array[i]
array[j]=temp;//把变量temp存放在值array[j]中
}
for(int a=0;a<length;++a)//遍历数组,把数组中所有元素打印出来
{
cout<<array[a]<<" ";
}
//**********666*********
}
intArray::~intArray()
{
delete [] array;
}
void intArray::writeToFile(char *filename)
{
int step=0;
ofstream outFile(filename);
for(int i=0; i<length; i=i+step)
{
outFile<<array[i]<<endl;
step++;
}
outFile.close();
}
void main()
{
intArray myArray("in.dat");
myArray.sort();
myArray.writeToFile("out.dat");
}
解题思路
主要考查一个排序函数,注意题上要求是非递减排序,即递增排序,常用的排序算法有冒泡排序、选择排序、插入排序、堆排序等基本思想都是相同的,即先遍历,后比较,再交换。定义两个下标 i 和 j ,按题目非递减,当array[i]比array[j]大时就交换其值,利用中间变量temp来实现。具体排序算法如上:
二、第五套 操作题考试题库试题
1.基本操作题
下列程序中存在错误,找到错误并改正他,使程序的输出结果
NUM=0;
Value=1;
代码如下(示例):
// proj1.cpp
#include <iostream>
using namespace std;
class MyClass {
int _i;
friend void Increment(MyClass& f);
public:
const int NUM;
// ERROR ********found********
MyClass(int i=0) //应改为MyClass(int i=0):NUM(0)
{
NUM = 0;
_i = i;
}
int GetValue() const {
return _i; }
};
// ERROR ********found********
void Increment() {
f._i++; }//应改为void Increment(MyClass& f) { f._i++; }
int main()
{
MyClass obj;
// ERROR ********found********
MyClass::Increment(obj);//应改为Increment(obj);
cout << "NUM = " << obj.NUM << endl
<< "Value = " << obj.GetValue() << endl;
return 0;
}
解题思路
1、主要是看前一句为 const int NUM;使用const修饰说明NUM是常量数据成员。而常量数据成员初始化方法是,常量数据成员的初始化只能通过构造函数的成员初始化列表进行。
2、友元函数的定义与声明要一致,在声明部分该友元函数的声明部分为:
friend void Increment(MyClass& f);返回类型是void ,函数参数为MyClass& f;再比较出错语句void Increment() { f._i++; },错误在于该函数没有参数,应把MyClass& f填在括号内。
3、友元函数的调用,友元函数不属于类,因此调用友元函数时不需要添加类名及作用域,只需要像调用普通函数一样即可。
2.简单应用题
如下程序,定义了Score类,Score是一个用于管理考试成绩的类。其中数据成员_s指向存储成绩的数组,_n表示成绩个数;成员函数Sort使用冒泡排序法将全部成绩进行排列,在横线部分填写合适代码,以实现Score类的成员函数Sort。
代码如下(示例):
// proj2.cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
class Score {
public:
Score(double *s, int n) : _s(s), _n(n) {
}
double GetScore(int i) const {
return _s[i]; }
void Sort();
private:
double *_s;
int _n;
};
void Score::Sort()
{
//********found********
for (int i = 0; i < _n-1; ______)//应该填i++
//********found********
for (int j =_______; j > i; j--)//应该填_n-1
if ( _s[j] < _s[j-1] )
{
// 交换 _s[j] 和 _s[j-1]
double t = _s[j];
//********found********
____________;//应该填_s[j]=_s[j-1]
//********found********
____________;//应该填_s[j-1]=t
}
}
int main()
{
const int NUM = 10;
double s[NUM];
srand(time(0));
for (int i=0; i<NUM; i++)
s[i] = double(rand())/RAND_MAX * 100;
Score ss(s, NUM);
ss.Sort();
for (int j=0; j<NUM; j++)
cout << ss.GetScore(j) << endl;
return 0;
}
解题思路
这道题考查冒泡排序法,这题的关键是根据已知的条件填写未知的,根据已知判断出从高位开始排还是低位开始排。并且根据已知的升序,来判断大小的交换顺序。这道题具体过程我前两天在blink做过一边,就不在做了。
3.综合应用题
如下程序,其中声明了ValArray类,在该类的内部维护一个动态分配的整型数组。ValArray类的复制构造函数应实现对象的深层复制。编写ValArray类的复制构造函数,测试输出结果应该是:
ValArray v1 = {1,2,3,4,5}
ValArray v2 = {2,2,2,2,2}
代码如下(示例):
#include "ValArray.h"
#include<fstream>
ValArray::ValArray(const ValArray& other)
{
//********333********
size=other,size;//把对象数组的大小复制给size
v=new int[other.size];//根据对象数组的大小动态分配数组v
for(int i=0;i<size;++i)
v[i]=other.v[i];//遍历整个对象的数组把值other.v[i]放到数组v中
//********666********
}
int main()
{
const int a[] = {
1, 2, 3, 4, 5 };
ValArray v1(a, 5);
ValArray v2(v1);
for (int i=0; i<5; i++)
v2.setElement(i,2);
cout << "ValArray v1 = ";
v1.print(cout);
cout << endl;
cout << "ValArray v2 = ";
v2.print(cout);
cout << endl;
writeToFile("");
return 0;
}
void writeToFile(const char *path)
{
char filename[30];
strcpy(filename,path);
strcat(filename,"out.dat");
ofstream fout(filename);
const int a[] = {
38, 42, 49, 49, 30, 19, 13, 14, 42, 1, 18, 4, 33, 2, 0};
ValArray v1(a, 15);
ValArray v2(v1);
v2.print(fout);
const int b[] = {
-6, 42, 49, 49, 30, 11, 13, 14, 42, 1, 4, 4, 33, 2, 0};
ValArray v3(b, 15);
ValArray v4(v3);
v4.print(fout);
const int c[] = {
21, 11, 28, 26, 31, 8, 25, 48, 34, 46, 9, 16, 8, 49, 22};
ValArray v5(c, 15);
ValArray v6(v5);
v6.print(fout);
const int d[] = {
-6, 11, 28, 26, 31, 11, 25, 48, 34, 46, 4, 16, 8, 49, 22};
ValArray v7(d, 15);
ValArray v8(v7);
v8.print(fout);
fout.close();
}
解题思路
主要考查是ValArray类,题目要求编写ValArray类的复制构造函数,以实现对类的深层复制。即填写ValArray::ValArray(const ValArray& other) 的函数体,由函数名 (ValArray::ValArray(const ValArray& other)) 知道复制的对象是other,对由ValArray类的成员int* v : int size知道要复制的内容是动态数组v及整型变量size。动态数组要使用new语句分配内存,最后利用for循环语句来完成复制过程。具体代码如上所示:
总结
以上就是今天要刷题的内容,收获了挺多,但做的题越多我才发现,有好多不懂的地方,好多知识都还没有完全学明白/(ㄒoㄒ)/~~,题还有很多,还需要继续努力,加油(ง •_•)ง