C++刷题系列 操作题考试题库_第四五套


前言

做题有些感觉了,话不多说,开始干!


一、第四套 操作题考试题库试题

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ㄒ)/~~,题还有很多,还需要继续努力,加油(ง •_•)ง

猜你喜欢

转载自blog.csdn.net/qq_45252077/article/details/113059169
今日推荐