考试题目

来源:互联网 发布:php达内项目经理面试题 编辑:程序博客网 时间:2024/04/29 18:51

结业考试试题(三)――C/C++

(考试时间 180分钟)

 

一、单项选择题(每题1分,总计30分)

1. 数组原来的初始值 如下,

int a[] = {10, 11, 12};

    int *pi = &a[0];

    int &b =a[1];

   

    b++;

    *(pi++)+=1;

    *(pi+1)+=2;

    执行了上述语句后,数组a内各个元素的数值分别为(  B     )

    A,{11,11,14}  B,{11,12,14} C,{10,13,14} D,{10,15,12}

 

2.  对栈内存、堆内存、静态内存的正确描述是(   B      )

       A, 全局变量的存储是在静态内存中,局部变量的存储是在堆内存,调用中函数参数的存储是在栈内存中;

       B, 使用栈内存是不需要程序员申请和释放的,使用堆内存需要程序员申请和释放的,使用静态内存不需要程序员申请和释放的;

       C, new和malloc分配的内存是从栈内存分配的,static类型变量的存储是在静态存储区中;

       D, 指针只能指向栈内存、堆内存,不能指向静态内存;

 

3. a,b,c分别是逻辑变量,a为真的概率为0.6; b为真的概率为0.8; c为真的概率为0.4;下面功能等效的表达式中,哪个表达式更合理、更有效率(       D   )

    A, ((a||b)&& c )

       B, ((b||a)&& c )

       C, ( c&& (a||b))

       D, ( c&& (b||a))

 

4. 如果有下面语句:

       typedefstruct

       {   int no;

           charname[20];

       }workor_t;

 workor_t worker1,*pworker;

pworker = &worker1;

       则以下语句不正确的是(  D   )

 

    A, worker1.no= 1234;           B, (*pworker).no = 1234;   

    C,pworker->name[0] =‘J’;      D,  pworker ->name =“Jone”;

 

    5. 执行下面语句后,

       int a;

       #defineM(x,y)    (x/y)

       a = M(4+2,3);

a的数值等于(   B   )

       A, 2       B,4       C, 5          D,以上都不对

      

6. 函数

   void func(intnum[5])

   {

       int iSize =sizeof(num);

       …………

   }

    则函数中iSize等于( A   )

       A, 4          B,5          C, 20      D, 以上都不对

   

7. 设char s[4]= {‘N’,’a’,’v’,’i’},则strlen(s)等于(D       )

   A, 1          B, 4          C,5       D, 不确定

 

8. 请正确指出下列指针的最确切的含义,int (*ptr)[4]、int *(*ptr)[3]、

void* (*ptr)(void*)(B   )

 

A, 一个指针数组,数组元素的个数为4个; 一个指向3个元素数组的指针、数组的每个元素是一个指针;一个函数的指针,这个函数的返回值还是个指针;

B, 一个指向4个元素数组的指针; 一个指针数组、数组的每个元素是一个指针;一个函数的指针,这个函数的返回值还是个指针;

C, 一个指针数组,数组元素的个数为4个; 一个指针数组、数组的每个元素是一个指针;一个函数的指针,这个函数的返回值还是个指针;

D, 一个指向4个元素数组的指针; 一个指向3个元素数组的指针、数组的每个元素是一个指针;一个函数的指针,这个函数的返回值还是个指针;

 

9. 设8位(7~0)二进制数x,若想通过位运算是x中的第三位不变,其它位为0,则下面可以   实现此功能的是(        D   )

A, x = x|0x08

B, x = x&0x80

C, x = x|0xf0

D, x = x&0x08

 

10. 下面的程序输出的结果是(   D   )

    char *s[] = {“program”,”lang”,”java2”,”vcVC”};

    printf(“%d %s”,sizeof(s)/sizeof(char*),*(s+2)+1);

       A, 5   pgram             B, 20  ava2

    C, 16  pgram             D, 4   ava2

 

11. 某C编译程序规定,int型数据在存储器中占四个字节,则以下类型数据在存储器中占的字节数为( C   )

    #pragma pack (2)
       struct test   {

       int        x; //4
           float      y; //4
           char       z[3];//3
       };                      //对齐之后变成12;

    A, 10     B,11       C,12       D,13

      

12. 请问下面哪段代码对指针的操作是正确的(C)

A,

           intfunc( )

{

              char *a, *b;

a =malloc(sizeof(char)*10);

               free(a);

              b = a;

              *b=0;

                …

              return0;

            }

B,

int func( )

{

              char *a , *b;

               a = malloc(sizeof(char)*10);

              b= a + 20;

                  …

              return0;

     }

C,

int func( )

{

              char *a , *b;

               a = malloc(sizeof(char)*10);;

              b= a;

                  …

              free(a);

              a=NULL;

b = NULL;

                 …             

return 0;

     }

D,

int func( )

{

              char *a , *b;

               a = malloc(sizeof(char)*10);;

               a++;

                  …

              free(a);

                 …

              return0;

     }

 

13.如下代码

     typedef struct ptrblock {

         char*ptr;

        char  name[10];

     }Node_t;

 

     main()

     {

         Node_t*p;

         p =(PB *)malloc(sizeof(Node_t));

         p->ptr = malloc(10);

         …

         [内存释放语句]

     }

请问下面哪段代码正确完成了内存释放(    B)

    A,

free(p);

      free(p->ptr);

B,

free(p->ptr);

         free(p);

 

       C,

free(p->ptr);

free(p->name);

         free(p);

       D,

        free(p);

free(p->ptr);

free(p->name);

 

          

14. 读下列代码

 char a = 100;

 char b = 150;

     

        unsigned char c ;

         c =(a < b)? a:b;

        请问c的值为(B)

       A, 100 ;  B, 150;    C, -106;   D, 204

 

15. 读下面的程序为(    B)

int x=0, y=0;

void func1(int x, int y)

{

       int a,b;

       a = x;

       b = y;

       a+=10;

        b+=10;

}

 

void func2( )

{

        x+=12, y+=13;

}

 

void main( void )

{

func1(x, y);

printf(“%d, %d”, x, y) ;

func2( );

printf(“%d,%d”, x,y) ;

}

运行结果为

A,  10,10,12,13   B, 0, 0, 12, 13      C,10, 10, 22, 23   D,0, 0, 22, 23

 

16.现有类定义如下:

class X

{

public:

            X();

            ~X();

private:

            long m_lID;

};

下面的表达式中, 没有调用到类X的构造函数的是(   )

A. X x;

B.  foo( X()); ( foo原型为 void foo( X& ); )

C.  X y = x; (x是a中的定义)

D.X* pax = new X[10];

 

17.类X的定义同第16题, 下面的表达式中, 没有调用到类X的析构函数的是(    )

A.  { X x; }

B. X* px = new X; delete px;

C. X* pax = new X[10]; deletepax;

D.  { X* px = new X; }

 

    18.下面的函数定义不构成重载的是(    )

A.  long hoo( long m, long n = 0 );

longhoo( const long m );

 

B.  long hoo(long m );

long hoo( const long m );

 

C.  long hoo( const long m );

double hoo( const longm);

 

D.  long hoo( long m = 0, long n = 0 );

long hoo( long m = 0 );

   

19.下面哪句话是正确的(    )

A. 一个class必须供应至少一个constructor.

B. 所谓的default constructor 是指其参数列表中没有参数.

C. 一个class对象被构造时, 不一定就会调用其constructor.

D. 如果class定义中不显示供应一个default constructor, 则编译器会自动生成一个, 用以为每个data member设定默认值.

 

20. 已知下面的基类和子类,

class CBase

{

public:

            char foo( int );

protected:

            int m_bar;

            double m_foo_bar;

};

class CDerived : public CBase

{

public:

            char foo( string );

            bool bar( CBase* pb );

            void foobar();

protected:

            string m_bar;

};

下面的代码, 正确的是(    )

A, CDerived d; d.foo( 1024 );

B, void CDerived::foobar() { m_bar = 1024; }

C, bool CDerived::bar( CBase* pb ) { return m_foo_bar ==pb->m_foo_bar; }

D, void CDerived::foobar(){ CBase::m_foo_bar = 2048; }

 

21. 已知如下的类层次结构. 其中每一个类都定义了一个default constructor和一个virtualdestructor:

class X { };

class A { };

class B : public A { };

class C : public B { };

class D : public X, public C { };

下面哪一个dynamic_cast 会失败(    )

A, D* pd = new D;

A* pa = dynamic_cast<A*>( pd );

B, A* pa = new C;

C* pc = dynamic_cast<C*>( pa );

C, B* pb = new B;

D* pd = dynamic_cast<D*>( pb );

D, A* pa = new D;

 

 

22. 关于VC的调试工具,下面说法错误的是( D )

A, 当程序Break后,通过CallStack工具可以了解发生break函数的层次调用关系,从而获得必要的出错信息(Break的分支、参数传递等);

B, 通过 Memory工具可以指定地址,了解一处(段)内存区域内存储的内容;存储内容的变更会及时更新;

C, 通过Watch工具可以了解变量的值或者(指定类型的)地址区域内的存储值;

D, 通过Variable工具可以修改变量的值和(指定类型的)地址区域内的存储值;

 

23. 编译并运行下面的代码:

#include"stdio.h"

 

int sub()

{

       printf("Hello World");

       return 0;

}

int   main()

{

       sub;

       return 0;

}

              结果是:(C)

A, 编译通不过,不能运行;

B, 编译通过,正常运行后输出Hello World;

C, 编译通过,正常运行后没有输出;

D, 编译通过,运行出错;  

 

24.以下哪段代码没有错误(D)

A,

char hello[5] = "Hello";

B,

char ChArray[5] = {'A', 'B', 'C', 'D', 'E',};

C,

typedef enum tagDayEnum{

Sunday,

    Monday,

Tuesday,

Saturday,

} DayEnum;

D,

char hello[5] = {0};

 

25. 快速排序的时间复杂度(A)

A, O(n*log(n));  B,O(n*n);  C,O(n*n/2);   D,O(log(n));

 

26. 若某链表最常用的操作时在最后一个元素之后插入一个节点和删除最后一个节点,则采用(D)存储方式节省时间。

   A,单链表         B,双链表      C,单循环链表   D,带头节点的双循环链表

 

27. 用数组表示链表的优点是(C)

   A,节省内存   B,便于随机存取   C,减少内存碎片 D,插入和删除速度快

 

28. 对线性表进行二分法查找,其前提条件是(A)

   A,线性表以顺序方式存储,并且按关键码值排好序

     B,线性表以顺序方式存储,并且按关键码值的检索频率排好序

     C,线性表以链接方式存储,并且按关键码值排好序

D,线性表以链接方式存储,并且按关键码值的检索频率排好序

 

29. 以下哪种数据结构适合查找操作(D)

A,单向链表     B, 双向链表        C,二叉树      D,平衡二叉树

 

30. 当一个需要排序的数列基本有序的时候,最好选择那种排序方式(D

     A,选择排序    B,插入排序     C,快速排序     D,冒泡排序

 

二、读程序并完成填空(总计20分,每空2分)

1.从键盘上输入一个正整数,然后把它转换成的二进制数的每一位存放到一维数组中,最后输出该二进制数。注意二进制数的存放是按照从低位到高位的次序进行的。

      #include <stdio.h>

       voidmain()

       {

           int x;

          int a[20],k=0,r;

 

          printf("输入一个整数:");

          scanf(“%d”, &x);

          

           do{

              r=x%2;

              a[k++]=r;

              x=___【1】_x/2__;

           } while(___【2】_x==0__);

          for(--k;k>=0;k--)

___printf(“%d”,a[k])【3】___;

          printf("\n");

       }

 

2. 已知下面的类层次结构, 其中含有虚函数:

class Base

{

public:

    virtual~Base();

    virtualvoid debug();

    virtualvoid readon();

    virtualvoid writeon();

    virtualvoid log();

};

 

class Derived1 : virtual public Base

{

public:

    virtual~Derived1();

    virtualvoid writeon();

};

 

class Derived2 : virtual public Base

{

public:

    virtual~Derived2();

    virtualvoid readon();

    virtualvoid log( int a = 0 );

};

 

class MI : public Derived1, public Derived2

{

public:

    virtual~MI();

    virtualvoid debug();

};

 

定义如下的对象:

Base* pb = new MI;

Derived1* pd1 = new MI;

MI obj;

Derived2 d2 = obj;

 

用示例的方式填空:

【例】: obj.debug(); 调用的是 MI::debug();

 

(1) pb->debug();         调用的是: __【4】__

(2) pb->readon();        调用的是: __【5】__

(3) pb->writeon();       调用的是: __【6】__

 

 

       

3.已知一个利用数组实现栈的类定义如下:

const int ARRAY_SIZE = 10;

int elem[ARRAY_SIZE];            //用于保存堆栈元素的数组

int top;                        //指明栈顶元素位置的指针

 

void Init() {top=-1;}        //初始化栈为空

void Push(int elm);        //向栈中压入一个元素

int Pop();                   //从栈顶弹出一个元素

void Print();                             //按照后进先出原则依次输出栈中每个元素,直到栈空为止

bool Empty()

{  //判栈空

   if(top==-1)

returntrue;

else

returnfalse;

}

int Depth() {returntop+1;}  //返回栈的深度

 

Push 、Pop、Print函数的实现分别如下;请填空完成相应功能。

void Push(int elm)

{

    if (__【7】__ )

{   cout<<"栈满!"<<endl;

    exit(1); //中止运行

}

 

__【8】__;

}

int Pop()

{

if(top== -1)

{

       cout<<"栈空!"<<endl;

       exit(1);  //中止运行

    }

    return__【9】__;

}

 

void Print()

{

   while(!Empty())

       cout<<__【10】__; <<' ';

}

 

 

三、读程序并指出程序中错误(总计18分)

1.程序的功能:将申请内存的函数封装MyNew,主函数通过自己的MyNew来申请内存,然后取得一个的名字,将名字拷贝到自己动态申请的内存里.

要求:请阅读程序,请找出其中的错误并进行修正(有若干个错误),进行修正。(找错扣分)

    程序见答题纸。

 

    2 找出程序错误(有多个)(重载拷贝构造中的内存泄漏).

要求:请阅读程序,请找出其中的错误并进行修正(有若干个错误),进行修正。(找错扣分)

    程序见答题纸。

 

四、写出程序运行结果(总计12分)

1.阅读下面代码,写出运行结果。
#include "stdio.h"
struct student
{

    int no;
    char name;
};

void   ModifyStudent(structstudent b)
{
    b.no=20;
    b.name='y';
}
main()
{

    student a;

    a.no=3;
    a.name='a';
    ModifyStudent (a);
    printf("%d,%c",a.no,a.name);
}
在控制台显示: __【1】3,a__

 

 

2. 阅读下面代码,写出运行结果。

#include   <stdio.h>

void main()

{    int s;

 

for (inti=1,s=0;i<20;i++)

{

        if(i%2==0 || i%3==0)

continue;

        printf(“%d”, i);

        s+=i;

      }

     

printf(“%d”, s);

}

在控制台显示: __【2】1571113171973_

 

3.阅读下面代码,写出运行结果。

#include <stdio.h>

        voidf2(int& x, int& y)

        {

            int z=x;

x=y;

y=z;

        }

        voidf3(int* x, int* y)

        {

           int z=*x;

*x=*y;

*y=z;

        }

        voidmain()

        {

            int x=10,y=26;

           printf("x,y=%d%d", x, y);

            f2(x,y);

           printf("x,y=%d%d", x, y);

           f3(&x,&y);

           printf("x,y=%d%d", x, y);

x++;

y--;

            f2(y,x);

           printf("x,y=%d%d", x, y);

        }

}
运行结果:__【3】x,y=1026x,y=2610x,y=1026x,y=2511__

 

 

 

五、编程题(一共2小题,第一小题满分10分,第二小题满分10分,总计20分;有卷面分数,卷面分数包含在每题分数中,如卷面差,每个题可以最多扣除2分)

 

程序要求:要有容错处理、讲求效率、程序结构清晰、要有必要注释。

 

1. 已知某链表节点结构为

struct node {

    struct node* next;

    int data;

};

链表头指针为

struct node* node_head =NULL;

 

请写出追加、删除一个节点的c语言代码,完成下面函数

int add_node(structnode** phead, int data)

int del_node(structnode**phead, int data)

其中*phead是链表头指针。要求追加函数要求在链表头追加新节点。删除函数要求删除第一个满足条件的节点即返回。函数成功返回1,否则返回0。如果有内存申请,释放请使用标准C函数

 

 

 

 

2. 小王最近在学习C++的编程和设计方法, 他做了一些类的设计,图示如下:

显然, 这是一个关于标准几何图形的类结构, 其中基类CGraphic定义了取得几何图形面积的方法( CalcArea )和取得几何图形周长的方法(CalcPerimeter ). 每个子类( CCircle, CRect, CTriangle )都要override这两个方法来给出具体实现过程.

小王对上述四个类的定义写了如下代码:

class CGraphic

{

public:

    CGraphic();

    ~CGraphic();

    double CalcArea();

    double CalcPerimeter();

};

 

 

class CCircle : publicCGraphic

{

public:

    CCircle( double lRadius, POINT stCenterPos );

    ~CCircle();

    double CalcArea();

    double CalcPerimeter();

    double GetRadius();

    POINT GetCenterPoint();

 

private:

    double m_lRadius;

    POINT m_stCenter;

};

 

class CRect : public CGraphic

{

public:

    CRect( POINT stLeftTop, POINT stRightBottom );

    ~CRect();

    double CalcArea();

    double CalcPerimeter();

   

private:

    POINT m_stLeftTop;

    POINT m_stRightBottom;

};

 

class CTriangle : publicCGraphic

{

public:

    CTriangle( POINT first, POINT second, POINT third );

    ~CTriangle();

    double CalcArea();

    double CalcPerimeter();

   

private:

    POINT m_st1stVertex;

    POINT m_st2ndVertex;

    POINT m_st3rdVertex;

};

 

小王给出了每个类的函数的具体实现. 其中对计算面积的CalcArea函数的实现如下:

对类CGraphic的CalcArea给出一个默认实现.

double CGraphic:: CalcArea()

{

    return 0;

}

 

对于类CCircle, 计算圆的面积.

double CCircle::CalcArea()

{

    return PI * m_lRadius * m_lRadius;

}

PI是一个常量,定义如下:

const double PI = 3.14;

 

对于类CRect, 计算矩形的面积.

double CRect:: CalcArea()

{

    double lWidth = labs(m_stRightBottom.x – m_stLeftTop.x);

    double lHeight = labs(m_stRightBottom.y – m_stLeftTop.y);

    return lWidth * lHeight;

}

 

其中, labs函数的功能取得一个整数的绝对值.

对于类CTriangle, 则利用海伦公式来计算三角形面积,这里代码省略.

 

随后小王又设计了一个全局函数, 原型和实现如下:

double GetGraphicArea(CGraphic clGraphic )

{

    return clGraphic.CalcArea();

}

 

小王的用意很明确, 就是无论创建多少个子类CCircle,CRect, CTriangle的对象, 都可以利用一个函数GetGraphicArea来取得该对象所代表的图形的面积. 为此, 小王写下了如下的测试代码.

void Test()

{

    POINT stPos;

    stPos.x = 0.0;

    stPos.y = 0.0;

    // define a circle

    CCircle clObj1( 1.0, stPos );

 

    POINT stPos2

stPos2.x = 10.0;

stPos2.y = 10.0;;

// define a rectangle

    CRect clObj2( stPos, stPos2 );

 

    double lArea = GetGraphicArea( clObj1 );

    cout << “Obj1’s area is: ” << lArea << endl;

    lArea = GetGraphicArea( clObj2 );

    cout << “Obj2’s area is:” << lArea << endl;

}

 

但是很遗憾, 测试函数Test并没有象小王期待的那样正确的显示了计算结果.现在请你帮小王分析分析, 他的问题出现在哪里? 什么原因? 怎样改正?

A, 小王在类的设计上出了哪些问题? 简单分析一下原因.(5分)

B, 如果达到小王设计的目的, 该如何修改他的类设计(包括类定义,类之间关系, 全局函数, 测试函数等).(5分)