分享

整理之c++笔试

 lhzstudio 2013-05-04

一、 填空题(25小题,共50分) 
(以下每小题1分,共10分)
1. 在C++中,函数的参数有两种传递方式,它们是值传递和 地址或指针或引用传递 。
2. 当一个成员函数被调用时,该成员函数的 this指针 指向调用它的对象。
3. 在基类和派生类中,派生类可以定义其基类中不具备的数据和操作。对两个有相同名字的数据成员进行访问时,如果没有 作用域分隔符限定时 ,对此数据成员的访问将出现歧义。
4. 拷贝构造函数使用 引用 作为参数初始化创建中的对象。
5. 在公有继承的情况下,基类数据成员在派生类中的访问权限 保持不变 。
6. 描述命题”A小于B或小于C”的表达式为 A<B||A<C 。
7. 用new申请某一个类的动态对象数组时,在该类中必须能够匹配到 没有形参的或缺省参数 构造函数,否则应用程序会产生一个编译错误。
8. 静态数据成员在类外进行初始化,且静态数据成员的一个拷贝被类的所有对象 共享 。
9. 为了避免可能出现的歧义,C++对if…else语句配对规则规定为:else总是与 与最近的if 配对。
10. 设”int a=3,b=4,c=5;”,表达式”(a+b)>c&&b==c”的值是 0 。
(以下每小题2分,共20分)
11. 面向对象的程序设计有四大特征,它们是抽象、封装、 继承 、 多态 。
12. 在Visual C++中,定义重载函数时,应至少使重载函数的参数个数或参数类型 不同 ;在基类和派生类中,成员函数的覆盖是指 派生类成员函数与在基类被覆盖的成员函数名、参数个数、参数类型和返回值类型均相同 。
13. 构造函数与析构函数除功能不同外,在定义形式上,它们的区别还包括构造函数名与类名相同,而析构函数名是在类名前加一个~、 析构函数没有参数 、 析构函数可以定义为虚函数 、无返回值、不能被重载、一个类中只有一个析构函数
14. 动态联编要满足两个条件,它们是 被调用的成员函数是虚函数 、 用对象的指针或引用调用成员函数 。
15. 在C++类中,有一种不能定义对象的类,这样的类只能被继承,称之为 抽象类 ,定义该类至少具有一个 纯虚函数 。
16. 在C++类中,const关键字可以修饰对象和成员函数,const对象不能 被修改 ,const成员函数不能 修改类数据成员 。
17. 举出C++中两种用户自定义的数据类型: 类 、 枚举
18. C++中没有字符串类型,字符串是通过 字符数组 来表示的,每一个字符串都有一个结尾字符 /0 。
19. C++中没有输入输出语句,输入输出是通过 输入输出库 实现的, 写出一条打印整型变量n的输出语句:cout<<n;
20. 举出C++中两种代码复用的方式: 继承 、 复用 。
(以下每小题4分,共20分)
21. 下面程序的运行结果是 3 。
#include <stdio.h>
void main()
{
char a=’a',b=’j';
float x;
x=(b-a)/('F’-'A’);
printf(“%d/n”,(int)(3.14*x));
}
22. 下面程序的运行结果是2 5 8 11 14。
#include “iostream.h”
void main( )
{
int i=1;
while (i<=15){
i++;
if (i%3!=2) continue;
else cout <<”i=”<<i<<endl;
}
}
23. 下面程序的运行结果是________。
#include “iostream.h”
class test
{
private:
int num;
float fl;
public:
test( );
int getint( ){return num;}
float getfloat( ){return fl;}
~test( );
};
test::test( )
{
cout << “Initalizing default” << endl;
num=0;fl=0.0;
}
test::~test( )
{
cout << “Desdtructor is active” << endl;
}
void main( )
{
test array[2];
cout << array[1].getint( )<< ” ” << array[1].getfloat( ) <<endl;
}
Initalizing default
Initalizing default
0 0
Desdtructor is active
Desdtructor is active
24. 下面程序的运行结果是________。
#include <iostream.h>
class A
{
public:
A(){cout<<”A::A() called./n”;}
virtual ~A(){cout<<”A::~A() called./n”;}
};
class B:public A
{
public:
B(int i){
cout<<”B::B() called./n”;
buf=new char;}
virtual ~B()
{
delete []buf;
cout<<”B::~B() called./n”;
}
private:
char *buf;
};
void fun(A *a)
{
delete a;
}
void main()
{
A *a=new B(15);
fun(a);
}
A::A() called.
B::B() called.
B::~B() called.
A::~A() called.
25. 下面程序的运行结果是________。
#include <stdio.h>
int a[ ]={1,3,5,7,9};
int *p[ ]={a,a+1,a+2,a+3,a+4};
void main( )
{
printf(“%d/t%d/t%d/n”,a[4],*(a+2),*p[1]);
printf(“%d/t%d/t%d/n”,**(p+1)+a[2],*(p+4)-*(p+0),*(a+3)%a[4]);
}
9 5 3
8 4 7

二、 问答题(每小题5分,共20分)
1 若程序员没有定义拷贝构造函数,则编译器自动生成一个缺省的拷贝构造函数,它可能会产生什么问题?
解答要点:缺省的拷贝构造函数只会拷贝存储区的内容,如果其中有引用的话,它是不拷贝的,就造成了两个类的实例引用了同一个对象,导致运行出错
2简述成员函数、全局函数和友元函数的差别。
解答要点:以下几点必须说清楚:
成员函数:定义类的时候,定义了public访问级的函数,可以访问类的所有数据成员,也可以调用该类的其他成员函数;
全局函数:定义在主函数和类定义之外的函数,在任何地方允许被调用,但是过多的全局函数导致程序臃肿;
友元函数:由于通过类的实例并不能访问到类的私有成员,如果在类定义之内定义友元函数,在类的实例中就可以通过友元函数访问私有成员,该函数需要friend关键字声明
3简述结构化的程序设计、面向对象的程序设计的基本思想。
解答要点:结构化的程序设计将数据和对数据的操作分离,程序是由一个个的函数组成的,面向对象的程序设计将数据和操作封装在一起,程序是由一个个对象组成的,对象之间通过接口进行通信,它能够较好地支持程序代码的复用。
4结构struct和类class有什么异同?
解答要点:struct和class都可以定义类,但是缺省访问权限说明时,struct的成员是公有的,而class的成员是私有的。在C++中,struct可被class代替。
三、找出下面程序(或程序段)中的语法错误,并予以纠正(每小题4分,共8分)
(1)程序功能是倒序输出各给定的字符串。
#include <stdio.h>
void main()
{
char str[5][ ]={“First”,”Second”,”Third”,”Forth”,”Fifth”};
char *cp[ ]={str[4],str[3],str[2],str[1],str[0]};
int i;
while(i<=5)
{
printf(“%c “,*(cp+i));
i++;
}
}
① “char str[5][ ]={“First”,”Second”,”Third”,”Forth”,”Fifth”};”应为
“char str[5][10 ]={“First”,”Second”,”Third”,”Forth”,”Fifth”};”
② “while(i<=5)”应为”while(i<5)”
③ “printf(“%c “,*(cp+i));”应为”printf(“%s”,*(cp+i));”
④ “int i;”应为”int i=0;”
(2)程序功能是将各个平方根值放入数组中。
#include <stdio.h>
void main()
{
int max,a,i;
scanf(“%d%d”,max,a);
double x[max];
for (i=0;i<max;i++)
x=sqrt(a*i);
}
① 增加”#include <math.h>”
② “scanf(“%d%d”,max,a);”应为”scanf(“%d%d”,&max,&a);”
③ “double x[max];”改为:
“double *x=new double[max];”

“delete []x;”
四、(8分)下列shape类是一个表示形状的抽象类,area( )为求图形面积的函数,total( )则是一个通用的用以求不同形状的图形面积总和的函数。请从shape类派生三角形类(triangle)、矩形类(rectangle),并给出具体的求面积函数
class shape{
public:
virtual float area( )=0;
};

float total(shape *s[ ],int n)
{
float sum=0.0;
for(int i=0;i<n;i++)
sum+=s->area( );
return sum;
}
class Triangle:public Shape
{
public:
Triangle(double h,double w){H=h;W=w;}
double Area() const{return H*W*0.5;}
private:
double H,W;
};
class Rectangle:public Shape
{
public:
Rectangle(double h,double w){H=h;W=w;}
double Area()const{return H*W;}
private:
double H,W;
};

五、(6分)完成顺序查找函数f_seq( )。其过程是:从表头开始,根据给定的模式,逐项与表中元素比较。如果找到所需元素,则查找成功,并打印出它在表中的顺序号。如果查找整个表仍未找到所需对象,则查找失败
#include <stdio.h>
void f_seq(char *list[],char *object,int len)
//list 指针数组,指向字符串
//object 模式串
//len 表的长度
{
char **p;
int strcmp(char *s,char *t);
p=list;
while (_____①______) //p<list+len
if (strcmp(*p,object)==0)
break;
else ______②_______; //p++
if (p<list+len)
printf( “Success! **% d/n”,p-list);
else printf(“Unsuccess!/n”);
}
int strcmp(char *s,char *t)
{
for (;*s==*t; s++,t++)
if (*s==’/0′)
return(0);
return(_____③______); //s-t或*s-*t或1
}
六、(8分)完成使链表逆置函数reverse,若有链表:
链表结点的结构如下:
struct node
{
int num;
struct node *next;
}
struct node* reverse(struct node *head)
//head 链表头结点
{
struct node *p,*temp1,*temp2;
if(head==NULL____①____) return head; //||head->next==NULL
p=head->next;head->next=NULL;
while(____②____) //p!=NULL或p
{
temp1=head;
____③____; //head=p;
temp2=p;
p=p->next;
____④____; //temp2->next=temp1;或head->next=temp1;
}//Match while statenment
return head; //返回逆置后的链表的头结点
}
 
 
 
 

一、选择题(50分,每小题2分)
下列各题A)、B)、C)、D)四个选项中,只有一个选项是正确的。
(1)下列有关内联函数的叙述中,正确的是 ( D )
A)内联函数在调用时发生控制转移 B)使用内联函数有利于代码重用
C)必须通过关键字inline来定义 D)是否最后内联由编译器决定
(2)下列情况中,哪一种情况不会调用拷贝构造函数 ( B )
A)用派生类的对象去初始化基类对象时
B)将类的一个对象赋值给该类的另一个对象时
C)函数的形参是类的对象,调用函数进行形参和实参结合时
D)函数的返回值是类的对象,函数执行返回调用者时
(3)以下哪一关键字可用于重载函数的区分( C )
A)extern B)static C)const D)virtual
(4)下列有关数组的叙述中,正确的是( B )
A)C++中数组的存储方式为列优先存储
B)数组名可以作为实参赋值给指针类型的形参
C)数组下标索引从1开始,至数组长度n结束
D)数组指针的语法形式为:类型名 *数组名[下标表达式];
(5)下列有关继承和派生的叙述中,正确的是( C )
A)派生类不能访问通过私有继承的基类的保护成员
B)多继承的虚基类不能够实例化
C)如果基类没有默认构造函数,派生类就应当声明带形参的构造函数
D)基类的析构函数和虚函数都不能够被继承,需要在派生类中重新实现
(6)实现运行时多态的机制是( A )
A)虚函数 B)重载函数 C)静态函数 D)模版函数
(7)下列字符串中,正确的C++标识符是( D )
A)enum B)2b C)foo-9 D)_32
(8)若有下面的函数调用:
fun(a+b, 3, max(n-1, b));
其中实参的个数是( A )
A)3 B)4 C)5 D)6
(9)以下哪个关键字对应的属性破坏了程序的封装性( B )
A)const B)friend C)public D)protected
(10)以下哪个符号(或组合)是作用域限定符( C )
A)-> B). C):: D)[]
(11)下列关于this指针的说法正确的是( B )
A)this指针存在于每个函数之中
B)在类的非静态函数中this指针指向调用该函数的对象
C)this指针是指向虚函数表的指针
D)this指针是指向类的函数成员的指针
(12)在下列关于C++函数的叙述中,正确的是( C )
A)每个函数至少要有一个参数 B)每个函数都必须返回一个值
C)函数在被调用之前必须先声明 D)函数不能自己调用自己
(13)下列运算符中,不能重载的是 ( C )
A)&& B)!= C). D)->
(14)对于类的常成员函数的描述正确的是( A )
A)常成员函数不修改类的数据成员
B)常成员函数可以对类的数据成员进行修改
C)常成员函数只能由常对象调用
D)常成员函数不能访问类的数据成员
(15)使用如setw()的操作符对数据进行格式输出时,应包含的头文件是( D )
A)iostream B)fstream C)stdio D)iomanip
(16)若有以下类定义
class MyClass {
public:
MyClass() { cout << 1; }
};
则执行语句MyClass a,b[2],*p[2];后,程序的输出结果是( B )
A)11 B)111 C)1111 D)11111
(17)下面程序的输出结果是( B )
#include <iostream>
using namespace std;
int i = 0;
int fun(int n)
{
static int a = 2;
a++;
return a+n;
}
void main()
{
int k = 5;
{
int i = 2;
k += fun(i);
}
k += fun(i);
cout << k;
}
A)13 B)14 C)15 D)16

(18)下面程序的输出结果是( A )
#include <iostream >
using namespace std;
void swap1( int &v1, int &v2)
{
int tmp = v2;v2 = v1;v1 = tmp;
}
void swap1( int *v1, int *v2)
{
int tmp= *v2;*v2 = *v1;*v1 = tmp;
}
void main()
{
int i = 10, j = 20; swap1(i,j); swap1(&i,&j);
cout<<i<<”,”<<j<<endl;
}
A)10,20 B)20,10 C)10,10 D)20,20
(19)下面的程序段的运行结果为( D )
char str[] = “job”, *p = str;
cout << *(p+2) << endl;
A)98 B)无输出结果 C)字符’b’的地址 D)字符’b’
(20)下面程序的输出结果是( C )
#include <iostream>
using namespace std;
class A
{
public:
A (int i) { x = i; }
void dispa () { cout << x << “,”; }
private :
int x ;
};
class B : public A
{
public:
B(int i) : A(i+10) { x = i; }
void dispb() { dispa(); cout << x << endl; }
private :
int x ;
};
void main()
{
B b(2);
b.dispb();
}
A)10,2 B)12,10 C)12,2 D)2,2
(21)下面程序的输出结果是( C )
#include <iostream>
using namespace std;
class Base
{
public:
Base(int i) { cout << i; }
~Base () { }
};
class Base1: virtual public Base
{
public:
Base1(int i, int j=0) : Base(j) { cout << i; }
~Base1() {}
};
class Base2: virtual public Base
{
public:
Base2(int i, int j=0) : Base(j) { cout << i; }
~Base2() {}
};
class Derived : public Base2, public Base1
{
public:
Derived(int a, int b, int c, int d) : mem1(a), mem2(b), Base1(c),
Base2(d), Base(a)
{ cout << b; }
private:
Base2 mem2;
Base1 mem1;
};
void main() { Derived objD (1, 2, 3, 4); }
A)134122 B)123412 C)14302012 D)143212
(22)以下程序对一维坐标点类Point进行运算符重载,输出结果是( A )
#include <iostream>
using namespace std;
class Point {
public:
Point (int val) { x = val; }
Point operator ++() { x++; return *this; }
Point operator ++(int) { Point old = *this; ++(*this); return old; }
Point operator +(Point a) { x += a.x; return *this; }
int GetX() const { return x; }
private:
int x;
};
int main()
{
Point a(10);
cout << (++a).GetX();
cout << a++.GetX();
}
A)1111 B)1011 C)1112 D)1010
(23)下面程序的输出结果是( C )
#include <iostream>
using namespace std;
class Base
{
public:
virtual void f() { cout << “f0+”; }
void g() { cout << “g0+”; }
};
class Derived : public Base
{
public:
void f() { cout << “f+”; }
void g() { cout << “g+”; }
};
void main() { Derived d; Base *p = &d; p->f(); p->g(); }
A)f+g+ B)f0+g+ C)f+g0+ D)f0+g0+
(24)下面程序的输出结果是( C )
#include <iostream>
using namespace std;
int countp=0;
class Point
{
int X,Y;
public:
Point(int x=0,int y=0) { X=x; Y=y;}
Point(Point &p){X=p.X;Y=p.Y;countp++;}
friend Point myfun(Point p1 ,Point p2 ,const Point &p3);
};
Point myfun(Point p1,Point p2,const Point &p3)
{
Point tmp(p1.X+p2.X+p3.X,p1.Y+p2.Y+p3.Y);
return tmp;
}
void main()
{
Point pp0,pp1(1,2),pp2(1);
myfun(pp0,pp1,pp2);
std::cout<<countp<<endl;
}
A)0 B)4 C)3 D)6
(25)下面程序的输出结果是( C )
#include <iostream>
using namespace std;
class Sample
{
friend long fun (Sample s)
{
if (s.x < 2) return 1;
return s.x * fun(Sample(s.x-1));
}
public:
Sample (long a) { x = a; }
private:
long x;
};
void main()
{
int sum = 0;
for (int i=0; i<6; i++)
{
sum += fun(Sample(i));
}
cout << sum;
}
A)120 B)16 C)154 D)34

二、填空题(20分,每空2分)
(1)以下程序是用来计算小于16的整数的阶乘,请补充完整。
#include<iostream>
using namespace std;
const int ArSize =16;
void main()
{
double fac[ArSize];
fac[1] =fac[0] =1.0;
for(int i=2;i<ArSize;i++)
fac = i*fac[i-1] ;
}
(2)下面是个Cat类的声明与使用,请补充完整。
#include <iostream>
using namespace std;
class Cat
{
static int count;
public:
Cat() { count++; cout << “Now cat number is” <<count << endl; }
~Cat() { count–; cout << ” Now cat number is ” << count << endl; }
};
int Cat::count =0;
int main()
{
Cat a, b, c;
return 0;
}
(3)将下面的MyPoint类定义补充完整,使得程序的输出结果是(10,10)(5,5)
#include <iostream>
class MyPoint
{
public:
MyPoint(int xx=5, int yy=5)
{ X = xx;
Y = yy;
std::cout<<”(“<<X<<”,”<<Y<<”) “;}
private:
int X, Y;
} ;
void main()
{
MyPoint a(10,10),b;
}
(4)已知文件之间具有以下的包含关系(用#include指令):point.cpp 包含 point.h,point.cpp 包含 line.h,line.h包含 point.h。那么如下的point.h文件缺少什么语句,请补充完整。
// Point类的声明,point.h
#ifndef _POINT_H_
#define _POINT_H_
class Point
{

} ;
#endif
(5)下列函数的功能是判断字符串str是否对称,对称则返回true,否则返回false。请在横线处填上适当内容,实现该函数。
bool fun (char *str)
{
int i=0, j=0;
while (str[j]) j++;
for(j–; i<j && str==str[j]; i++, j–);
return i>=j ;
}
(6)请将下列程序补充完整,使得输出结果为“Destructor Derived Destructor Base”。
#include <iostream>
using namespace std;
class Base
{
public:
virtual ~Base () { cout << “Destructor Base”<< endl; }
};
class Derived : public Base
{
public:
~Derived(){ cout << “Destructor Derived” << endl; }
};
void main ()
{
Base *pBase = new Derived;
delete pBase ;
}
(7)如有下列程序:
#include <iostream>
using namespace std;
class Demo
{
public:
Demo(){cout<<”default constructor\n”;}
Demo(const Demo &x){cout<<”copy constructor\n”;}
};
Demo userCode(Demo b){Demo c(b);return c;}
void main()
{
Demo a,d;
cout<<”calling userCode()\n”;
d = userCode(a);
}
执行上面的程序的过程中,构造函数Demo()和Demo(const Demo &x)被调用的次数分别是 2 和 3 次。

三、程序题(30分,每题10分)
(1)程序改错
每个注释“// ERROR”所在的一行语句存在错误。请改正这些错误,使程序的输出结果为:
00:00:00
01:37:19
注意:只需修改注释“// ERROR”所在的那一行语句,不要改动程序中的其他内容。
#include<iostream>
#include<iomanip>
using namespace std;
class StopWatch //”秒表”类
{
int hours; //小时
int minutes; //分钟
int seconds; //秒
public:
StopWatch():hours(0), minutes (0), seconds(0){}
void reset(){hours=minutes=seconds=0;}
//前进1秒
StopWatch& operator++() // ERROR ①
{
if(seconds==60) // ERROR ②
{
seconds=0;
if(++minutes==60)
{
minutes=0;
++hours;
}
}
return *this;
}

friend void show(StopWatch);
};
void show(StopWatch watch)
{
cout<<setfill(‘*’); // ERROR ③
cout<<setw(2)<<watch.hours<<’:’
<<setw(2)<<watch.minutes<<’:’
<<setw(2)<<watch.seconds<<endl;
}
int main()
{
StopWatch sw;
show(sw);
for(int i=0;i<5839;i++)
sw++;
show(sw);
return 0;
}
解答:
①: StopWatch& operator++(int) (4分)
②: if(++seconds==60) (3分)
③: cout<<setfill(’0′); (3分)
(2)语句填空
下面的程序设计了一个宠物类,请你在空行上填入合适的语句,使程序完整。(每空2分)
#include <iostream>
enum Pets_type{dog,cat,bird,fish};
class Pets
{
private:
char *name;
Pets_type type;
public:
Pets(const char *n=”sonny”,int type1 = 0);
Pets(const Pets &s);
Pets& operator=(const Pets &s);
~Pets();
};
Pets::Pets(const char *n,int type1) //构造函数
{
name = new char[strlen(n) + 1];
strcpy(name,n);
type = Pets_type(type1);
}
Pets::Pets(const Pets &s) //拷贝构造函数
{
name = new char[strlen(s.name) + 1] ;
strcpy(name,s.name);
type = s.type;
}
Pets::~Pets() //析构函数
{
delete[] name ;
}
Pets& Pets::operator =(const Pets &s)
{
if (this==&s) //确保不要向自身赋值
return *this;
delete [] name;
name = new char[strlen(s.name) + 1];
strcpy(name,s.name);
type = s.type;
return *this ;
}
void main()
{
Pets mypet1,mypet2(“John”,1),hispet(“Danny”,2);
Pets youpet(hispet);
mypet1 = youpet;}
3) 编写程序段
补充编制下列程序,其功能是从键盘读取任意长度的文本内容,将文本存放到Doc类的对象myDoc中。然后在显示器输出。
请在//******* begin ******和//******* end *******之间补充程序。
#include<iostream>
#include<iomanip>
#include<cstring>
using namespace std;
class Doc
{
private:
static const int MaxLength; // 可能的最大文本字符串长度
char *str; // 文本字符数组首地址指针
int length; // 文本字符串长度
public:
Doc(const char *s = “”); // 构造函数
~Doc(); // 析构函数
// 重载istream的提取运算符
friend istream& operator>>(istream& is, Doc& doc);
// 重载ostream的插入运算符
friend ostream& operator<<(ostream& os, Doc& doc);
};
const int Doc::MaxLength=256; // 可能的最大文本字符串长度
//重载提取运算符,从输入流is提取字符串,存入参数doc中
istream& operator>>(istream& is, Doc& doc)
{
//提示:使用is.getline函数可以从is流提取字符串,包括空格。
//********************** begin *************************
char buffer[Doc::MaxLength];
is.getline(buffer, Doc::MaxLength);
int inLen = (int)strlen(buffer);
if (inLen > doc.length) {
delete [] doc.str;
doc.str = new char[inLen+1];
}
strcpy(doc.str, buffer);
doc.length = inLen;
return is;
//******************** end *****************************
}
ostream& operator<<(ostream& os, Doc& doc)
{
os << doc.str;
return os;
}
Doc::Doc(const char *s) : length((s!=NULL) ? (int)strlen(s) : 0)
{
str = new char[length + 1];
if (s != NULL)
strcpy(str, s);
else
str[0] = ‘\0′;
}
Doc::~Doc()
{
delete [] str;
}
void main()
{
Doc myDoc(“Initial String”);
cin >> myDoc;
cout<< myDoc;

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多