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。
相关文章推荐
- C++ 静态全局变量与普通全局变量
- 二分查找(c & c++)
- 字典树的基本知识及使用C语言的相关实现
- 利用ffmpeg将H264流 解码为RGB 分类: VC++ ffmpeg-SDL-VLC-Live555 2015-08-07 11:39 155人阅读 评论(0) 收藏
- 双缓冲解决VC++绘图时屏幕闪烁
- C++:overload, override和overwrite
- 详解次小生成树以及相关的C++求解方法
- c语言》查找法-数组下标
- 面试笔试(C++部分)
- C++_Switch Statement
- Sublime 在win上搭建C++环境
- C++抽象机制之二:运算符重载
- HDOJ 2024 C语言合法标识符(水)
- C++ Vector
- C++ AMP 介绍(两)
- c++ STL中的set容器
- C++模板元编程
- c++子类和父类成员函数重名
- c语言》排序法
- #编码风格#C++ Programming Style Guidelines