您的位置:首页 > 编程语言 > C语言/C++

C/C++校招笔试面试经典题目总结十

2015-08-07 11:49 531 查看

题目78:如果两段内存重叠,用memcpy函数可能会导致行为未定义。 而memmove函数能够避免这种问题,下面是一种实现方式,请补充代码。

#include <iostream>
using namespace std;
void* memmove(void* str1,const void* str2,size_t n)
{
char* pStr1= (char*) str1;
const char* pStr2=(const char*)str2;
if  ( ) {
for(size_t i=0;i!=n;++i){
*(pStr1++)=*(pStr2++);
}
}
else{
pStr1+=n-1;
pStr2+=n-1;
for(size_t i=0;i!=n;++i){
*(pStr1--)=*(pStr2--);
}
}
return ( );
}
A:pStr1< pStr2 str1

B:pStr1+n < pStr2 str2

C:pStr1+n < pStr2 || pStr2+n<pStr1 str2

D:pStr2+n<pStr1 str1
解析:A


如图:当pstr1<pstr1的时候,如果从后向前拷贝,就会覆盖str2的头部分;当pstr1>pstr2的时候,如果从前向后拷贝,就会丢失str2的尾部数据。因此当pstr1<pstr2时,将字节从前向后拷贝,反之则从后向前拷贝,最后返回pstr1。

题目79:以下程序的输出是:

class Base {
public:
Base(int j): i(j)  {}
virtual~Base() {}
void func1() {
i *= 10;
func2();
}
int getValue() {
return  i;
}
protected:
virtual void func2() {
i++;
}
protected:
int i;
};
class Child: public Base {
public:
Child(int j): Base(j) {}
void func1() {
i *= 100;
func2();
}
protected:
void func2() {
i += 2;
}
};
int main() {
Base * pb = new Child(1);
pb->func1();
cout << pb->getValue() << endl; delete pb; }
A:11 B:101
C:12 D:102
解析:Base * pb = new Child(1), 首先创建子类对象,初始化为1;

func1()不是虚函数,所以pb->func1()执行的是基类的func1函数,i= 10,然后调用func2()函数;

这里的func2是虚函数,要往下派生类寻找,找到后执行派生类中的func2(),此时,i = 12;

最后执行pb->getValue(),结果为12。
用基类的指针指向不同的派生类的对象时,基类指针调用其虚成员函数,则会调用其真正指向对象的成员函数,而不是基类中定义的成员函数(只要派生类改写了该成员函数)。若不是虚函数,则不管基类指针指向的哪个派生类对象,调用时都 会调用基类中定义的那个函数。

题目80:下面代码的输出是什么?

class A
{
public:
A()  {     }
~A() {    cout<<"~A"<<endl;   }
};

class B:public A
{
public:
B(A &a):_a(a)
{

}
~B()
{
cout<<"~B"<<endl;
}
private:
A _a;
};

int main(void)
{
A a;       //很简单,定义a的时候调用了一次构造函数
B b(a);
}
A :~B B:~B ~A C:~B ~A ~A
D :~B ~A ~A ~A

解析:要想搞明白该问题,需要理解基类构造析构函数、子类构造析构函数和子类成员变量构造析构函数的调用顺序。

对于构造函数:基类构造函数 > 子类成员变量构造函数 > 子类构造函数

对于析构函数:子类析构函数 > 子类成员变量析构函数 > 基类析构函数

可以看出构造函数的调用过程和析构函数的调用过程正好相反。
最开始析构b,~B,这个是没有争议的。

接着是析构b的成员变量_a,所以是~A

接着是b的parent class(基类)的~A

最后才是a的析构~A
题目81: 以下程序的结果?
void foo(int *a, int *b)
{
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}
void main()
{
int a = 1, b = 2, c = 3;
foo(&a, &b);
foo(&b, &c);
foo(&c, &a);
printf("%d, %d, %d", a, b, c);
}
A:1,2,3
B:1,3,2 C:2,1,3 D:3,2,1
解析:foo(int *a,int *b)将两个数交换,调用的时候保持这种改变。注意一共进行了三次交换。第一次调用a=2,b=1;第二次a=2,b=3,c=1;第三次a=1,b=3,c=2。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: