程序员面试宝典笔记

上传人:xzh****18 文档编号:36573787 上传时间:2018-03-30 格式:DOC 页数:15 大小:5.42MB
返回 下载 相关 举报
程序员面试宝典笔记_第1页
第1页 / 共15页
程序员面试宝典笔记_第2页
第2页 / 共15页
程序员面试宝典笔记_第3页
第3页 / 共15页
程序员面试宝典笔记_第4页
第4页 / 共15页
程序员面试宝典笔记_第5页
第5页 / 共15页
点击查看更多>>
资源描述

《程序员面试宝典笔记》由会员分享,可在线阅读,更多相关《程序员面试宝典笔记(15页珍藏版)》请在金锄头文库上搜索。

1、1)答案为: A NOTE1:求值顺序是自右至左;输出顺序还是从左至右. NOTE2: 如果把 printf(“%d %dn”, *ptr, *(+ptr) );换成 printf(“%d %dn”, *ptr, *(ptr+) );结 果为 C,虽然求值是从右向左的,但是表达式中的但是表达式中的*ptr 与与*(ptr+)不是两个语句,所以不是两个语句,所以 ptr 的值相同的值相同2)(int void main() float a = 1.0f;cout 0 float b = 0.0f;cout 1 NOTE1: (int b=ab; a=ab; /无需担心越界问题6)C 语言不支持函

2、数重载7)宏中的参数要注意加括号答案:#define MIN(A,B) ( (A)的优先级大于(type)的优先级,所以要 ( (struc*)0 ) - eNOTE:A.指针是什么呢?一句话,指针其实就是地址。只要有了一个地址,就可以访问到特定 的内存。这就是指针。因为用途不同(可能指向一个 int 啊,也可能指向一个 double 啊) ,所以指针也分很多种。这些指针本质上都是一样的(都是内存的地址嘛)这些指针本质上都是一样的(都是内存的地址嘛) ,如果,如果 指向一个地方,那么值也是一样的(同一个地方的地址自然只有一个咯)指向一个地方,那么值也是一样的(同一个地方的地址自然只有一个咯)

3、。可以通过强 制转换将一块内存转换成各种类型的指针 B.如何将一个指针强制转化为指向数组的指针typedef int (*p)3; int(*ap)3=(p)ip; /这样 int(*ap)3=(int(*)3)ip;/或这样typedef int (*p)3; int(*ap)3; ap=(p)ip; /这样ap=(int(*)3)ip;/或这样 C.指针强制转换后的结果是临时变量,不能作为左值17)malloc/free 与 new/delete 的区别18)智能指针答案: B E NOTE: B,C 格式不对, D 是错的,因为 auto_ptr 放在 vector 中是不合理的,19)

4、深拷贝与浅拷问题解析解析: A.vector *a1=new vector();a1-push_back(d1); /会调用 CDemo 的默认拷贝构造函数,传值调用时会调用拷贝构造 函数进行形参与实参的赋值 B.delete a1; /释放 vector 对象,vector 所包含的所有元素也同时被释放 C.局部变量 CDemo d1 在 main 函数退出时,也会释放所占的内存空间 D.这样 str 所指向的内存空间就会被释放两次了,引起内存错误 E.采用深拷贝可以解决问题20)泛型编程 1 template 21)泛型编程 2 函数指针方法方法 1:使用函数指针:使用函数指针方法方法 2

5、:使用静态模板类:使用静态模板类22)STL 常用数据结构总结-23)默认构造函数默认构造函数NOTE1: A.如果类提供了其他的构造函数,则编译器不会提供默认构造函数了,此时需要自己 定义默认构造函数(无参或是默认参数) B.只有当一个类没有定义构造函数的时候,编译器才会自动生成一个默认构造函数 C.没有默认构造函数的类不能用作动态分配数组的元素类型 D.没有默认构造函数的类的静态分配数组必须为每一个元素提供一个显示的初始化式 E.对象的数组和使用容器时可能会用到缺省的构造函数(动态分配数组时,(动态分配数组时, 如果数如果数 组元素具有类类型,组元素具有类类型, 将使用该类的默认构造函数将

6、使用该类的默认构造函数 ) NOTE2: 非堆数组可以,但是,定义了几个元素就要在初始化值集中写几个 CLS a3 =CLS(para), CLS(para), CLS(para);堆数组不可以 NOTE3: A.动态分配数组时,如果数组元素具有类类型,将使用该类的默认构造函数实现初 始化;如果数组元素是内置类型,则无初始化。 string *psa=new string 10; int *pia=new int 10;这两个 new 表达式都分配了 10 个对象的数组,第一个数组是 string 类型,分配了 存储对象的空间后,会调用 string 类型的默认构造函数依次初始化数组中的每个元

7、 素。第二个数组为内置类型,分配了存储 10 个 int 对象的内从空间,并没初始化 B.可以跟在数组后面加一对空圆括号,对数组元素进行初始化。 int *pia2=new int 10();C.圆括号要求编译器对数组初始化,这里把数组元素都设置为 0。对于动态分配数组, 其元素只能初始化为元素类型的默认值,而不能像数组变量一样,用初始化列表 为数组元素提供各不相同的初值。 NOTE4: 如果 vector 保存的是含构造函数的类类型的元素,则将使用该类型的默认构造函数进 行初始化,例如 vector svec; /10 elements, each an empty string24)con

8、st 数据成员的初始化NOTE: A.const 数据成员 只在某个对象生存期内是常量,而对于整个类而言却是可变的。因 为类可以创建多个对象,不同的对象其 const 数据成员的值可以不同。 B.不能在类的声明中初始化 const 数据成员,因为类的对象没被创建时,编译器不知 道 const 数据成员的值是什么。const 数据成员的初始化只能在类的构造函数的初 始化列表中(区分初始化与赋值)进行。 C.要想建立在整个类中都恒定的常量,应该用类中的枚举常量来实现,或者 static const。25)拷贝构造函数与赋值函数 class String public:String(const ch

9、ar* str=NULL); /默认构造函数 String(const String /拷贝构造函数 String /赋值操作符 private: char* m_data; String(const char* str) If(str=NULL) m_data=new char1; *m_data=n; Else Int length=strlen(str)+1; m_data=new charlength; strcpy(m_data, str); /拷贝构造函数的调用情况是在对象初始化时, /此时 m_data 还没分配内存,所以不需要考虑释放内存 String(String m_dat

10、a=new charlength; strcpy(m_data, other.m_data); A.函数返回的临时对象一般都是 const 对象 String s1(“hello”); String s2(“world”);String s3=s1+s2; 其中 s1+s2 产生一个临时变量 这也是为什么 operator+ 重载时返回值为 const 的原因 B.非 const 引用只能绑定到与该引用同类型的对象。 const 引用则可以绑定到不同但相关的类型的对象或绑定到右值。 (隐式转化常常返回临时变量,而临时变量是 const 类型的) 所以, float j = 2, int /证同

11、测试 char* pOld=m_data; int length=strlen(other.m_data)+1; m_data=new charlength; strcpy(m_data, other.m_data); delete pOld;return *this; /千万别忘了 26)拷贝构造函数NOTE:这种说法是正确的,因为 string 对象与 vector 对象的类都有合适的赋值操作27)模板类的友元重载模板类的友元重载28)覆盖问题覆盖问题 129)覆盖问题覆盖问题 2#include using namespace std;class Aprotected:int m_dat

12、a;public:A(int data = 0)m_data = data; int GetData()return doGetData();virtual int doGetData() return m_data;/*m_data 0 */;class B:public Aprotected:int m_data;public:B(int data = 1)m_data = data; /这里 A 中的 m_data = 0 ,B 中的 m_data = 1int doGetData() return m_data ;/*m_data 1 */ /实现接口实现接口;class C:publ

13、ic B /C 继承了 AB 类的方法属性,且未从新定义接口,故接口还是 B 类中定义的protected:int m_data;public:C(int data = 2)m_data = data; /这里 A 中的 m_data = 0 ,B 中的 m_data = 1,C 类中的 m_data = 2;int main()C c(10);coutdoGetData()函数E.看 A 的声明,doGetData()函数为虚函数,无法一次确定执行的函数的地址,而是通过 C 类的类的虚函数表,由于 this 指针实际指向了 main 中的 c 对象,即虚函数表中的 doGetData()函数

14、被覆盖,于是执行了 B:doGetData()c.GetData(): C 的对象调用从基类继承下来的成员函数 GetData(),此刻的 GetData()还是属于 A 的,为什么呢?因为,类的一般的成员函数,只有一份,系统只维护一份。接着这个 GetData()函数里面又去调用另外一个方法,而这个方法是虚方法,问题就来了-到底调用哪个虚方法呢?这就是多态,此时,对象 c,会去根据这个对象的 vptr,遍历 C 类的虚函数表,找到个虚方法(虚方法都放在虚函数表中) 。所以,调用的是 B 类的虚方法,因为 C 继承自 B,而 C 类中未改写 B 类的这个虚方法,所以是 B 的虚方法。c.A:G

15、etData():这个动作,编译的时候静态绑定调用的是 A:GetData(),明确说了,是 A 的成员函数,但里面调用的却是一个虚方法,需要动态绑定。最终:结果和上面分析的一样。c.B:GetData(),c.C:GetData():情形都和上面的一样。c.DoGetData():这个动作,直接调用虚方法。对象 c 根据自己的 vptr,去 vtbl 中找到这个虚方法来,调用它,就 OK。 (在派生类的对象中对基类的成员进行操作)c.A:DoGetData():这个动作,是在编译的时候,就静态绑定了,调用哪一个虚函数c.B:DoGetData(),c.C:DoGetData():情形和上面的一样。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号