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

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

#include 
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 D:pStr2+n
解析:A

如图:当pstr1pstr2的时候,如果从前向后拷贝,就会丢失str2的尾部数据。因此当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"<
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。

你可能感兴趣的:(C++)