豪仕知识网--知识就是力量!

微信
手机版
生活常识

程序员面试宝典(第三版)笔记整理、指出了书中一些不足之处/程序员面试笔试宝典pdf

作者 :慕容渊博 2024-01-06 09:07:04 围观 : 评论

程序员面试宝典(第三版)笔记整理、指出了书中一些不足之处/程序员面试笔试宝典pdf

豪士君测试所用平台

●☛█▼▲豪仕知识网◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲

程序员面试宝典(第三版)笔记整理、指出了书中一些不足之处,一起来看看吧,希望能帮助到您,更多请关注豪仕知识网。

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

不怎样的一本书,具体表现为:1)该详细讲解的地方,或者一笔带过或者讲得不全面或者讲些不相关内容;2)该略过的地方,反而详细起来;3)有一部分错误,如sizeof不计算static变量的大小之类的。虽说如此,收获还是有的——知道了在笔试中常见的知识点。这里的笔记就是对我不熟悉或者理解不全面的知识点去Google和查书而来的。

C++的关键字

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

1. 使用extern "C"的理由

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

函数被C编译器编译后不带参数信息,被C++编译器编译后会带上参数信息。这是因为C++支持函数重载。所以函数被C编译器编译和被C++编译器编译是不同的。例如:void Zero(int lin),被C编译后,可能得到_Zero,被C++编译后,可能得到_Zero_int。那如果要在C++中使用被C编译过的库呢?使用extern "C"就可以!它会告诉C++编译器,被它修饰的函数是以C语言的编译方式编译的。

2. const的作用

a. 声明常量 b. 声明函数形参 -> 提高自定义类型的调用效率。注意,如果是内部类型,如int,没必要写成const int&c. 声明函数返回值d. 修饰类成员函数 -> 防止成员函数对成员变量进行修改。注意,const成员函数内只能调用类的其他const成员函数

●☛█▼▲豪仕知识网◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲

备注:如果要在const成员函数修改某个成员变量,那么可以给这个变量的声明加上mutable

3. static的作用

●☛█▼▲豪仕知识网◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲

a. 用于函数内部的局部变量时,能保证函数退出作用域后不回收其空间(即其值保持不变)

●☛█▼▲豪仕知识网◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲

b. 用于全局变量时,使变量的作用域限制在一个文件内

c. 用于函数时,使函数只在一个文件内可见

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

d. 用于类成员变量时,代表该变量属于类的(即所有对象共享这个变量)

e. 用于类成员函数时,代表该函数为整个类所有。注意,该函数不接收this指针,也意味着不能调用一般的成员函数或者变量

4. sizeof操作符

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

a. 作用:返回一个对象或者类型所占的内存

b. sizeof 不计算类/结构体的static成员 -> 因而可将a中提到所占的内存理解为存储某个类型的对象所需要空间

c. 对空类使用sizeof会返回1 ->占用内存为0,无法实例化,所以编译器为了使空类也能实例化,就给其分配了1Byte

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

d. 如果类中有虚函数,那么最终结果要多加4Byte -> 此时多出一个指针,指向虚函数表

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

e.g:

static int a; //sizeof(a) = 4,因为这不是类内/结构体内的

●☛█▼▲豪仕知识网◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲

class Zero {

int a;

static int b;

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

virtual void fun() {}

}; //sizeof(Zero) = 8

class Lin {

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

virtual void fun() {}

}; //sizeof(Lin) = 4,由d可知其为lin至少有4Byte,所以在这个例子中规则c不成立,因而最终结果为4Byte

class Child: public Zero {

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

int a;

virtual void fun() {}

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

}; //sizeof(Child) = 12

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

5. inline

a. inline只是一种建议,建议编译器将指定的函数在被调用点展开,因此编译器是可以忽略inline的(即不展开)

b. inline以代码膨胀(复制)为代价,省去了函数调用的开销,从而提高函数的执行效率c. 每一处inline函数的调用都要复制代码,这将使得程序的总代码量增大,消耗更多的内存空间d. inline必须与函数定义放在一起才能使函数成为内联,仅将inline 放在函数声明前面不起任何作用e. 定义在类声明之中的成员函数将自动地成为内联函数

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

6. explicit

禁止单参数构造函数被用于隐式类型转换

class Zero {

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

public:

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

Zero(int i): lin(i) {}

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

private:

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

int lin;

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲豪仕知识网HtTp://▲▼▲▼▲

};

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

int Fun(Zero z) {} //如果不用explicit的话,可以这样调用Fun(1);

-------------------------------------------------------------------------------------------

http://www.haoz.net●☛█▼▲◐●☛█▼▲◐◐◐◐●☛█▼▲◐豪仕知识网●☛█▼▲豪仕知识网

C++的规则

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

1. 在声明赋值语句中,变量先声明,然后赋值

int i = 1;

http://www.haoz.net●☛█▼▲◐●☛█▼▲◐◐◐◐●☛█▼▲◐豪仕知识网●☛█▼▲豪仕知识网

int main() {

int i = i; //这里声明的i 覆盖了全局变量的i,之后的赋值就是局部变量的i 给自己赋值,因而其值是未定义的

return 0;

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

}

2.从右到左压参数

int main() {

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲豪仕知识网HtTp://▲▼▲▼▲

int i = 1;

printf("%d, %d\n", i, ++i); //VS2010输出2, 2

}

◐◐◐◐●☛█▼▲豪仕知识网http://www.haOz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

其它:

虽然压参数的顺序是固定的,但计算顺序是编译器相关的,因此最后的结果与编译器相关。

3. 写宏时要注意

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

a. 括号的使用

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

b. 不要使用分号

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

e.g: 写一个找出两者中较小的宏

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

#define MIN(a, b) ( (a) < (b) ? (a) : (b) )

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

4. 结构体对齐原则

a. 数据成员对齐规则:结构(struct或union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(e.g: int在32位机为4字节,则要从4的整数倍地址开始存储)b. 结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存(e.g: struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储)c. 结构体的总大小,必须是内部最大成员的整数倍,不足的要补齐

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

备注:设计结构体,最好把占用空间小的类型排在前面,占用空间大的类型排在后面,这样可以相对节约一些对齐空间

struct Zero {

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

char b;

int a; //a的起始位置要按4字节对齐,所以b之后要补3个字节

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

short c;

}; //sizeof(Zero) = 12

struct OreZ {

◐◐◐◐●☛█▼▲豪仕知识网http://www.haOz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

char b;

short c; //c的起始位置要按2字节对齐,所以b之后要补1个字节

◐◐◐◐●☛█▼▲豪仕知识网http://www.haOz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

int a;

} //sizeof(Orez) = 8

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

5. 结构体位制

a. 位段成员的类型仅能够为unsigned或者int, 并且指定的位数不能超过类型的长度

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

b. 存储规则:如果下一个位段能存放在之前的存储单元中(存储后长度不超过类型长度),则存储,否则,存储到新的存储单元中。因为位段不能跨单元存储

struct Zero {

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

unsigned short a : 4;unsigned short b : 5;unsigned short c : 7; //刚好16,符合unsigned short的长度,所以存放在同一单元中}zero;

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲豪仕知识网HtTp://▲▼▲▼▲

int main() {

zero.a = 2;

http://www.haoz.net●☛█▼▲◐●☛█▼▲◐◐◐◐●☛█▼▲◐豪仕知识网●☛█▼▲豪仕知识网

zero.b = 3;

int i = *((short*)&zero);

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

printf("%d", i); //输出50(VS2010测试结果),这说明先声明的变量在低位

return 0;

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

}

6. C++风格类型转换

a. const_cast(varible): 去掉变量的const或volatile属性

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲豪仕知识网HtTp://▲▼▲▼▲

b.static_cast(varible): 类似C的强制转换,但功能上有所限制(如:不能去掉const属性) -> 常用于基本类型转换,void指针与目标指针转换

c. dynamic_cast(varible): 有条件转换,运行时进行类型安全检查(如果失败则返回NULL) -> 用于基类与子类之间的类型转换(必须要有虚函数)

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

d. reinterpret_cast(varible): 仅仅重新解释二进制内容 -> 常用于不同类型的指针转换

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

class Base {

public:

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

virtual void fun() {}

};

class Zero: public Base {

http://www.haoz.net●☛█▼▲◐●☛█▼▲◐◐◐◐●☛█▼▲◐豪仕知识网●☛█▼▲豪仕知识网

public:

virtual void fun() {}

};

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

int main() {

Base *pb = new Base;

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

(dynamic_cast(pb)) -> fun(); //由于实际指向的是基类,所以此转换失败,返回NULL,导致运行时错误

delete pb;

return 0;

◐◐◐◐●☛█▼▲豪仕知识网http://www.haOz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

}

◐◐◐◐●☛█▼▲豪仕知识网http://www.haOz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

7. 指针与引用的差异

a. 初始化:指针可以不初始化;引用必须在定义时初始化

HTTP://WWW.haoz.net豪仕知识网采集不好玩哦◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐撒旦法师打发斯蒂芬

b. 非空性:指针可以为NULL,因而指针可能是无效的;引用不能为空,因而引用总是有效的

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

c. 内存占用:指针要占用内存,引用不占 -> 引用只是一个逻辑概念,通常在编译时就优化掉了

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

d. 可修改性:指针可以重新指向其它变量;引用不可以

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

《Effective C++》:在一般情况下,引用和指针是一样的,但是根据条款23:在返回一个对象时,尽量不要用引用,而是用指针

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

8. 指针与句柄(handle)

指针标记一个内存的地址

句柄是Windows用来标识被应用程序建立或使用的对象(窗口,菜单,内存等)的唯一整数。从构造上看,句柄是一个指针,但其不指向存储对象的内存位置,而是一个包含了对象所在的内存位置的结构(结构的复杂度由所指的对象决定)

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

9. 指针与浅拷贝

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

浅拷贝在复制指针时,只是单纯地将指针指向同一内存,并不对所指向的内容进行复制。因而,当成员变量有指针时,最好考虑是否要写深拷贝函数和赋值函数

class Zero {

public:

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

Zero(): ptr(NULL) {}

~Zero() { if( ptr ) delete[] ptr; }

◐◐◐◐●☛█▼▲豪仕知识网http://www.haOz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

char* ptr;

};

int main() {

HTTP://WWW.haoz.net豪仕知识网采集不好玩哦◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐撒旦法师打发斯蒂芬

Zero z;

z.ptr = new char[100];

◐◐◐◐●☛█▼▲豪仕知识网http://www.haOz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

strcpy(z.ptr, "zero");

vector * vz = new vector();

vz->push_back(z);

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

delete vz;

return 0;

}  //退出main时会出现运行时错误

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

由于Zero没有定义拷贝函数,所以有一个默认的浅拷贝函数。在main函数中,delete vz已经释放过一次ptr指向的内存,然后在离开main的作用域时z的析构函数启动,再次释放该内存

10. 迭代器失效

在容器中增加/删除元素时,可能会使部分或者全部的迭代器失效

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

11. C++编译器默认产生的成员函数

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

构造函数,析构函数,拷贝函数,赋值函数

12. 类中静态成员变量与常量

http://www.haoz.net●☛█▼▲◐●☛█▼▲◐◐◐◐●☛█▼▲◐豪仕知识网●☛█▼▲豪仕知识网

a. 静态成员变量一定要在类外初始化

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

b. 成员常量一定要在初始化列表初始化

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

c. 静态成员常量一定要初始化,初始化时可以直接在声明时写上,也可以像一般的静态成员变量那样写

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

class Zero {

public:

Zero():lin2(1) {}

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

private:

●☛█▼▲豪仕知识网◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲

static int lin;

const int lin2;

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

static const int lin3 = 1;

};

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

int Zero::lin = 0;

http://www.haoz.net●☛█▼▲◐●☛█▼▲◐◐◐◐●☛█▼▲◐豪仕知识网●☛█▼▲豪仕知识网

13. 初始化列表的初始化顺序根据成员变量的声明顺序执行

class Zero { //不要写这样的代码

public:

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

Zero(int i):lin2(i), lin1(lin2) {} //此时先初始化lin1,再初始化lin2,因而最后的结果是lin1的值是随机数,lin2的值是i

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

private:

int lin1;

int lin2;

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

};

14. 构造函数不可以为virtual,析造函数有时必须为virtual

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

虚函数在运行时动态绑定,动态绑定需要知道动态类型才能进行绑定。而一个类的对象在没有运行构造函数前,其动态类型不完整,因而无法进行动态绑定

delete指向子类对象的基类指针时,如果析构函数不是virtual,则只会调用基类的析构函数,从而造成内存泄漏

15. C++编译的程序占用的内存a. stack(栈区): 由OS自动分配释放空间,主要用来存放函数的参数,局部变量等b. heap(堆区): 一般由程序员分配释放空间, 若程序员不释放,程序结束时可能由OS回收c. static(全局/静态区): 存放全局变量和静态变量。值得注意的是,初始化和未初始化的这两种变量是分开存放的。d. 文字常量区: 存放常量字符串e. 程序代码区: 存放函数的二进制代码

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

-------------------------------------------------------------------------------

杂项

1. 不用循环,判断一个数X是否为2的N的次方(N >= 0)

●☛█▼▲豪仕知识网◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲

X & (X - 1) //最后结果为0,则是2的N次方

分析:2,4,8的二进制式为10, 100, 1000,当其与1, 3, 7的二进制式相与时,其结果为0

2. 不用判断语句,找出两个数中的最大值

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

((a + b) + abs(a - b)) / 2

3. 不用中间变量,交换两者的值

a = a ^ b; //得到a与b的哪些位不相同(即一共有多少位不同)

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

b = a ^ b; //去掉b的不同位,换上a的不同位,从而得到a

a = a ^ b;

HTTP://WWW.haoz.net豪仕知识网采集不好玩哦◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐撒旦法师打发斯蒂芬

4. 写一个宏FIND,求结构体struc里某个变量相对struc的偏移量

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

#define FIND(struc, e) (size_t)&(((struc*)0)->e)

解析:(struc*)0将0强制转换为struc*的指针类型,然后再取(struc*)0的成员e的地址,从而得到e离结构体首地址的偏移量

5. 数组名再取地址

●☛█▼▲豪仕知识网◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲

int a[] = {1, 2, 3};

int *ptr = (int*)(&a + 1); //&a相当于得到二维数组指针,因而&a + 1相当于移动一行

◐◐◐◐●☛█▼▲豪仕知识网http://www.haOz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

printf("%d\n", *(ptr - 1)); //输出3

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

6. 指针的移动

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

int main() {

◐◐◐◐●☛█▼▲豪仕知识网http://www.haOz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

int *pi = NULL;

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

pi += 15;

printf("%d\n", pi); //输出60

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

return 0;

HTTP://WWW.haoz.net豪仕知识网采集不好玩哦◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐撒旦法师打发斯蒂芬

}

7. 整数超范围

http://www.haoz.net●☛█▼▲◐●☛█▼▲◐◐◐◐●☛█▼▲◐豪仕知识网●☛█▼▲豪仕知识网

如果是有符号数,那么最大正整数 + 1 等于最小负整数

如果是无符号数,那么最大正整数 + 1 等于零

bool IsOdd(int i) {

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

return(i & 1) == 1; //不要写成(i % 2) == 1,因为这样写判断负数时会出问题

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

}

int main() {

for(int i = 0xFFFFFFFF; i <= 0x7FFFFFFF; ++i) { //这会陷入死循环,因为最大正整数 + 1 等于最小负数

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

cout<<i<<" is "<<IsOdd(i) ? "odd" : "even"<<endl;

}

return 0;

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

}

8. 基类指针与子类指针

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

class Base {

int a;

};

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

class Zero: public Base {

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

int b;

};

int main() {

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

Zero *pz = new Zero();

Base *pb = dynamic_cast(pz);

(pz == pb) ? (cout<<"Yes\n") : (cout<<"No\n"); //VS2010输出"Yes"

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

(int(pz) == int(pb)) ?(cout<<"Yes\n") : (cout<<"No\n"); //VS2010输出"Yes"

return 0;

HTTP://WWW.haoz.net豪仕知识网采集不好玩哦◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐撒旦法师打发斯蒂芬

}

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

9. strcpy的写法

char* strcpy(char* dst, const char* src) { //返回char*是为了方便链式调用

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

assert( (src != NULL) && (dst != NULL) ); //特别注意检查

char* tmp = dst;

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

while( *dst++ = *src++ ); //后缀++优先级高

return tmp;

}

◐◐◐◐●☛█▼▲豪仕知识网http://www.haOz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

10. 概率题

int main() {

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

int cnt = 0;

for(int i = 0; i < 10000; ++i) {

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

int x = rand();

int y = rand();

if( x * x + y * y < RAND_MAX * RAND_MAX ) ++cnt; //实质上是1/4圆与正方形的面积的比较

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

}

printf("%d\n", cnt); //结果约为PI/4 * 10000

}

●☛█▼▲豪仕知识网◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲

11. 以下程序在编译时,哪句会出错

struct Zero {

void Lin() {}

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

};

int main() {

◐◐◐◐●☛█▼▲豪仕知识网http://www.haOz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

Zero z(); //这样写会被编译器认为是声明一个函数,而不是调用构造函数

z.lin(); //这句会出错,因为此时的z被认为是未声明的变量

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

return 0;

}

12.各种排序总结

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

算法稳定性时间复杂度空间复杂度备注选择排序FO(n^2)O(1)插入排序TO(n^2)O(1)当序列有序时,时间复杂度为O(n)冒泡排序TO(n^2)O(1)当序列有序时,时间复杂度为O(n)希尔排序FO(nlogn)O(1)具体的时间复杂度与所选的增量序列有关归并排序TO(nlogn)O(n)堆排序FO(nlogn)O(1)快速排序FO(nlogn)O(logn)当序列有序时,时间复杂度恶化为O(n^2)桶排序TO(n)O(k)

不怎样的一本书,具体表现为:1)该详细讲解的地方,或者一笔带过或者讲得不全面或者讲些不相关内容;2)该略过的地方,反而详细起来;3)有一部分错误,如sizeof不计算static变量的大小之类的。虽说如此,收获还是有的——知道了在笔试中常见的知识点。这里的笔记就是对我不熟悉或者理解不全面的知识点去Google和查书而来的。

●☛█▼▲豪仕知识网◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲

C++的关键字

1. 使用extern "C"的理由

函数被C编译器编译后不带参数信息,被C++编译器编译后会带上参数信息。这是因为C++支持函数重载。所以函数被C编译器编译和被C++编译器编译是不同的。例如:void Zero(int lin),被C编译后,可能得到_Zero,被C++编译后,可能得到_Zero_int。那如果要在C++中使用被C编译过的库呢?使用extern "C"就可以!它会告诉C++编译器,被它修饰的函数是以C语言的编译方式编译的。

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

2. const的作用

a. 声明常量 b. 声明函数形参 -> 提高自定义类型的调用效率。注意,如果是内部类型,如int,没必要写成const int&c. 声明函数返回值d. 修饰类成员函数 -> 防止成员函数对成员变量进行修改。注意,const成员函数内只能调用类的其他const成员函数

http://www.haoz.net●☛█▼▲◐●☛█▼▲◐◐◐◐●☛█▼▲◐豪仕知识网●☛█▼▲豪仕知识网

备注:如果要在const成员函数修改某个成员变量,那么可以给这个变量的声明加上mutable

3. static的作用

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

a. 用于函数内部的局部变量时,能保证函数退出作用域后不回收其空间(即其值保持不变)

b. 用于全局变量时,使变量的作用域限制在一个文件内

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

c. 用于函数时,使函数只在一个文件内可见

d. 用于类成员变量时,代表该变量属于类的(即所有对象共享这个变量)

e. 用于类成员函数时,代表该函数为整个类所有。注意,该函数不接收this指针,也意味着不能调用一般的成员函数或者变量

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

4. sizeof操作符

a. 作用:返回一个对象或者类型所占的内存

b. sizeof 不计算类/结构体的static成员 -> 因而可将a中提到所占的内存理解为存储某个类型的对象所需要空间

◐◐◐◐●☛█▼▲豪仕知识网http://www.haOz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

c. 对空类使用sizeof会返回1 ->占用内存为0,无法实例化,所以编译器为了使空类也能实例化,就给其分配了1Byte

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

d. 如果类中有虚函数,那么最终结果要多加4Byte -> 此时多出一个指针,指向虚函数表

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲豪仕知识网HtTp://▲▼▲▼▲

e.g:

static int a; //sizeof(a) = 4,因为这不是类内/结构体内的

◐◐◐◐●☛█▼▲豪仕知识网http://www.haOz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

class Zero {

int a;

static int b;

◐◐◐◐●☛█▼▲豪仕知识网http://www.haOz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

virtual void fun() {}

}; //sizeof(Zero) = 8

class Lin {

HTTP://WWW.haoz.net豪仕知识网采集不好玩哦◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐撒旦法师打发斯蒂芬

virtual void fun() {}

}; //sizeof(Lin) = 4,由d可知其为lin至少有4Byte,所以在这个例子中规则c不成立,因而最终结果为4Byte

class Child: public Zero {

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

int a;

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

virtual void fun() {}

}; //sizeof(Child) = 12

5. inline

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

a. inline只是一种建议,建议编译器将指定的函数在被调用点展开,因此编译器是可以忽略inline的(即不展开)

b. inline以代码膨胀(复制)为代价,省去了函数调用的开销,从而提高函数的执行效率c. 每一处inline函数的调用都要复制代码,这将使得程序的总代码量增大,消耗更多的内存空间d. inline必须与函数定义放在一起才能使函数成为内联,仅将inline 放在函数声明前面不起任何作用e. 定义在类声明之中的成员函数将自动地成为内联函数

6. explicit

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

禁止单参数构造函数被用于隐式类型转换

class Zero {

public:

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

Zero(int i): lin(i) {}

private:

●☛█▼▲豪仕知识网◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲

int lin;

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

};

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

int Fun(Zero z) {} //如果不用explicit的话,可以这样调用Fun(1);

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

-------------------------------------------------------------------------------------------

C++的规则

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

1. 在声明赋值语句中,变量先声明,然后赋值

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

int i = 1;

int main() {

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

int i = i; //这里声明的i 覆盖了全局变量的i,之后的赋值就是局部变量的i 给自己赋值,因而其值是未定义的

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

return 0;

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

}

2.从右到左压参数

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲豪仕知识网HtTp://▲▼▲▼▲

int main() {

int i = 1;

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

printf("%d, %d\n", i, ++i); //VS2010输出2, 2

}

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

其它:

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

虽然压参数的顺序是固定的,但计算顺序是编译器相关的,因此最后的结果与编译器相关。

3. 写宏时要注意

a. 括号的使用

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

b. 不要使用分号

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

e.g: 写一个找出两者中较小的宏

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

#define MIN(a, b) ( (a) < (b) ? (a) : (b) )

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

4. 结构体对齐原则

a. 数据成员对齐规则:结构(struct或union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(e.g: int在32位机为4字节,则要从4的整数倍地址开始存储)b. 结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存(e.g: struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储)c. 结构体的总大小,必须是内部最大成员的整数倍,不足的要补齐

http://www.haoz.net●☛█▼▲◐●☛█▼▲◐◐◐◐●☛█▼▲◐豪仕知识网●☛█▼▲豪仕知识网

备注:设计结构体,最好把占用空间小的类型排在前面,占用空间大的类型排在后面,这样可以相对节约一些对齐空间

struct Zero {

char b;

◐◐◐◐●☛█▼▲豪仕知识网http://www.haOz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

int a; //a的起始位置要按4字节对齐,所以b之后要补3个字节

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲豪仕知识网HtTp://▲▼▲▼▲

short c;

HTTP://WWW.haoz.net豪仕知识网采集不好玩哦◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐撒旦法师打发斯蒂芬

}; //sizeof(Zero) = 12

struct OreZ {

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

char b;

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

short c; //c的起始位置要按2字节对齐,所以b之后要补1个字节

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

int a;

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

} //sizeof(Orez) = 8

●☛█▼▲豪仕知识网◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲

5. 结构体位制

a. 位段成员的类型仅能够为unsigned或者int, 并且指定的位数不能超过类型的长度

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

b. 存储规则:如果下一个位段能存放在之前的存储单元中(存储后长度不超过类型长度),则存储,否则,存储到新的存储单元中。因为位段不能跨单元存储

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

struct Zero {

unsigned short a : 4;unsigned short b : 5;unsigned short c : 7; //刚好16,符合unsigned short的长度,所以存放在同一单元中}zero;

●☛█▼▲豪仕知识网◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲

int main() {

zero.a = 2;

zero.b = 3;

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

int i = *((short*)&zero);

printf("%d", i); //输出50(VS2010测试结果),这说明先声明的变量在低位

return 0;

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

}

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

6. C++风格类型转换

a. const_cast(varible): 去掉变量的const或volatile属性

b.static_cast(varible): 类似C的强制转换,但功能上有所限制(如:不能去掉const属性) -> 常用于基本类型转换,void指针与目标指针转换

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

c. dynamic_cast(varible): 有条件转换,运行时进行类型安全检查(如果失败则返回NULL) -> 用于基类与子类之间的类型转换(必须要有虚函数)

d. reinterpret_cast(varible): 仅仅重新解释二进制内容 -> 常用于不同类型的指针转换

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

class Base {

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

public:

virtual void fun() {}

};

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

class Zero: public Base {

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

public:

virtual void fun() {}

};

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

int main() {

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

Base *pb = new Base;

http://www.haoz.net●☛█▼▲◐●☛█▼▲◐◐◐◐●☛█▼▲◐豪仕知识网●☛█▼▲豪仕知识网

(dynamic_cast(pb)) -> fun(); //由于实际指向的是基类,所以此转换失败,返回NULL,导致运行时错误

delete pb;

return 0;

●☛█▼▲豪仕知识网◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲

}

7. 指针与引用的差异

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

a. 初始化:指针可以不初始化;引用必须在定义时初始化

b. 非空性:指针可以为NULL,因而指针可能是无效的;引用不能为空,因而引用总是有效的

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲豪仕知识网HtTp://▲▼▲▼▲

c. 内存占用:指针要占用内存,引用不占 -> 引用只是一个逻辑概念,通常在编译时就优化掉了

d. 可修改性:指针可以重新指向其它变量;引用不可以

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

《Effective C++》:在一般情况下,引用和指针是一样的,但是根据条款23:在返回一个对象时,尽量不要用引用,而是用指针

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

8. 指针与句柄(handle)

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

指针标记一个内存的地址

句柄是Windows用来标识被应用程序建立或使用的对象(窗口,菜单,内存等)的唯一整数。从构造上看,句柄是一个指针,但其不指向存储对象的内存位置,而是一个包含了对象所在的内存位置的结构(结构的复杂度由所指的对象决定)

9. 指针与浅拷贝

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

浅拷贝在复制指针时,只是单纯地将指针指向同一内存,并不对所指向的内容进行复制。因而,当成员变量有指针时,最好考虑是否要写深拷贝函数和赋值函数

http://www.haoz.net●☛█▼▲◐●☛█▼▲◐◐◐◐●☛█▼▲◐豪仕知识网●☛█▼▲豪仕知识网

class Zero {

public:

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

Zero(): ptr(NULL) {}

~Zero() { if( ptr ) delete[] ptr; }

char* ptr;

HTTP://WWW.haoz.net豪仕知识网采集不好玩哦◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐撒旦法师打发斯蒂芬

};

int main() {

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲豪仕知识网HtTp://▲▼▲▼▲

Zero z;

z.ptr = new char[100];

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

strcpy(z.ptr, "zero");

vector * vz = new vector();

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

vz->push_back(z);

delete vz;

return 0;

http://www.haoz.net●☛█▼▲◐●☛█▼▲◐◐◐◐●☛█▼▲◐豪仕知识网●☛█▼▲豪仕知识网

}  //退出main时会出现运行时错误

由于Zero没有定义拷贝函数,所以有一个默认的浅拷贝函数。在main函数中,delete vz已经释放过一次ptr指向的内存,然后在离开main的作用域时z的析构函数启动,再次释放该内存

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

10. 迭代器失效

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

在容器中增加/删除元素时,可能会使部分或者全部的迭代器失效

11. C++编译器默认产生的成员函数

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

构造函数,析构函数,拷贝函数,赋值函数

12. 类中静态成员变量与常量

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

a. 静态成员变量一定要在类外初始化

HTTP://WWW.haoz.net豪仕知识网采集不好玩哦◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐撒旦法师打发斯蒂芬

b. 成员常量一定要在初始化列表初始化

c. 静态成员常量一定要初始化,初始化时可以直接在声明时写上,也可以像一般的静态成员变量那样写

HTTP://WWW.haoz.net豪仕知识网采集不好玩哦◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐撒旦法师打发斯蒂芬

class Zero {

public:

Zero():lin2(1) {}

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

private:

static int lin;

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

const int lin2;

static const int lin3 = 1;

http://www.haoz.net●☛█▼▲◐●☛█▼▲◐◐◐◐●☛█▼▲◐豪仕知识网●☛█▼▲豪仕知识网

};

int Zero::lin = 0;

13. 初始化列表的初始化顺序根据成员变量的声明顺序执行

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

class Zero { //不要写这样的代码

public:

Zero(int i):lin2(i), lin1(lin2) {} //此时先初始化lin1,再初始化lin2,因而最后的结果是lin1的值是随机数,lin2的值是i

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

private:

int lin1;

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

int lin2;

};

14. 构造函数不可以为virtual,析造函数有时必须为virtual

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

虚函数在运行时动态绑定,动态绑定需要知道动态类型才能进行绑定。而一个类的对象在没有运行构造函数前,其动态类型不完整,因而无法进行动态绑定

delete指向子类对象的基类指针时,如果析构函数不是virtual,则只会调用基类的析构函数,从而造成内存泄漏

15. C++编译的程序占用的内存a. stack(栈区): 由OS自动分配释放空间,主要用来存放函数的参数,局部变量等b. heap(堆区): 一般由程序员分配释放空间, 若程序员不释放,程序结束时可能由OS回收c. static(全局/静态区): 存放全局变量和静态变量。值得注意的是,初始化和未初始化的这两种变量是分开存放的。d. 文字常量区: 存放常量字符串e. 程序代码区: 存放函数的二进制代码

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

-------------------------------------------------------------------------------

杂项

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

1. 不用循环,判断一个数X是否为2的N的次方(N >= 0)

X & (X - 1) //最后结果为0,则是2的N次方

http://www.haoz.net●☛█▼▲◐●☛█▼▲◐◐◐◐●☛█▼▲◐豪仕知识网●☛█▼▲豪仕知识网

分析:2,4,8的二进制式为10, 100, 1000,当其与1, 3, 7的二进制式相与时,其结果为0

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲豪仕知识网HtTp://▲▼▲▼▲

2. 不用判断语句,找出两个数中的最大值

((a + b) + abs(a - b)) / 2

●☛█▼▲豪仕知识网◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲

3. 不用中间变量,交换两者的值

a = a ^ b; //得到a与b的哪些位不相同(即一共有多少位不同)

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

b = a ^ b; //去掉b的不同位,换上a的不同位,从而得到a

http://www.haoz.net●☛█▼▲◐●☛█▼▲◐◐◐◐●☛█▼▲◐豪仕知识网●☛█▼▲豪仕知识网

a = a ^ b;

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识http://www.Haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

4. 写一个宏FIND,求结构体struc里某个变量相对struc的偏移量

#define FIND(struc, e) (size_t)&(((struc*)0)->e)

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲豪仕知识网HtTp://▲▼▲▼▲

解析:(struc*)0将0强制转换为struc*的指针类型,然后再取(struc*)0的成员e的地址,从而得到e离结构体首地址的偏移量

5. 数组名再取地址

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

int a[] = {1, 2, 3};

int *ptr = (int*)(&a + 1); //&a相当于得到二维数组指针,因而&a + 1相当于移动一行

printf("%d\n", *(ptr - 1)); //输出3

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

6. 指针的移动

int main() {

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

int *pi = NULL;

pi += 15;

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

printf("%d\n", pi); //输出60

return 0;

}

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

7. 整数超范围

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

如果是有符号数,那么最大正整数 + 1 等于最小负整数

如果是无符号数,那么最大正整数 + 1 等于零

bool IsOdd(int i) {

HTTP://WWW.haoz.net豪仕知识网采集不好玩哦◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐撒旦法师打发斯蒂芬

return(i & 1) == 1; //不要写成(i % 2) == 1,因为这样写判断负数时会出问题

}

●☛█▼▲豪仕知识网◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲

int main() {

for(int i = 0xFFFFFFFF; i <= 0x7FFFFFFF; ++i) { //这会陷入死循环,因为最大正整数 + 1 等于最小负数

cout<<i<<" is "<<IsOdd(i) ? "odd" : "even"<<endl;

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

}

return 0;

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲豪仕知识网HtTp://▲▼▲▼▲

}

8. 基类指针与子类指针

class Base {

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

int a;

};

class Zero: public Base {

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

int b;

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

};

int main() {

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

Zero *pz = new Zero();

Base *pb = dynamic_cast(pz);

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

(pz == pb) ? (cout<<"Yes\n") : (cout<<"No\n"); //VS2010输出"Yes"

(int(pz) == int(pb)) ?(cout<<"Yes\n") : (cout<<"No\n"); //VS2010输出"Yes"

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

return 0;

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

}

9. strcpy的写法

char* strcpy(char* dst, const char* src) { //返回char*是为了方便链式调用

http://www.haoz.net●☛█▼▲◐●☛█▼▲◐◐◐◐●☛█▼▲◐豪仕知识网●☛█▼▲豪仕知识网

assert( (src != NULL) && (dst != NULL) ); //特别注意检查

char* tmp = dst;

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

while( *dst++ = *src++ ); //后缀++优先级高

HTTP://WWW.haoz.net◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐豪仕知识网

return tmp;

}

◐◐◐◐●☛█▼▲豪仕知识网███████豪仕知识网HTtp://www.haoZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

10. 概率题

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

int main() {

HTTP://WWW.haoz.net豪仕知识网采集不好玩哦◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐撒旦法师打发斯蒂芬

int cnt = 0;

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

for(int i = 0; i < 10000; ++i) {

int x = rand();

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HTTP://WWW.hAoz.net███████████████████████████东方金报网

int y = rand();

if( x * x + y * y < RAND_MAX * RAND_MAX ) ++cnt; //实质上是1/4圆与正方形的面积的比较

}

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲豪仕知识网HtTp://▲▼▲▼▲

printf("%d\n", cnt); //结果约为PI/4 * 10000

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

}

11. 以下程序在编译时,哪句会出错

struct Zero {

HTTP://WWW.haoz.net豪仕知识网采集不好玩哦◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐撒旦法师打发斯蒂芬

void Lin() {}

};

豪仕知识网http://www.haoz.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

int main() {

Zero z(); //这样写会被编译器认为是声明一个函数,而不是调用构造函数

◐◐◐◐●☛█▼▲豪仕知识网HT●☛█▼▲◐◐◐◐●☛█▼▲

z.lin(); //这句会出错,因为此时的z被认为是未声明的变量

return 0;

}

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲豪仕知识网HtTp://▲▼▲▼▲

12.各种排序总结

算法稳定性时间复杂度空间复杂度备注选择排序FO(n^2)O(1)插入排序TO(n^2)O(1)当序列有序时,时间复杂度为O(n)冒泡排序TO(n^2)O(1)当序列有序时,时间复杂度为O(n)希尔排序FO(nlogn)O(1)具体的时间复杂度与所选的增量序列有关归并排序TO(nlogn)O(n)堆排序FO(nlogn)O(1)快速排序FO(nlogn)O(logn)当序列有序时,时间复杂度恶化为O(n^2)桶排序TO(n)O(k)

◐◐◐◐●☛█▼▲豪仕知识网███████http://www.haOZ.net▼▲▼▲▼▲▼▲▼●●●●●●●▼▲▼▲▼▲

以上的相关游戏回复就是程序员面试宝典(第三版)笔记整理、指出了书中一些不足之处这方面的内容介绍,,字数约36539字,也希望大家能够和我在一起进行分享。豪仕知识网往后会继续推荐程序员面试宝典(第三版)笔记整理、指出了书中一些不足之处相关内容。

◐◐◐◐●☛█▼▲◐◐◐◐●☛█▼▲HtTp://wWW.haoz.net豪仕知识网●●●●●●●●●●●●●●●●●●●●●●●●●●

相关文章