1.1 int main(int argc, char ** argv)函数中,参数argc和argv分别代表什么意思?
argc是argument count 的缩写,表示传入main函数的参数个数
argv是argument vector 的缩写,表示传入main函数的字符串数组指针
1.2 简述C++有几种传值方式,之间的区别是什么?
传值:形参发生改变,实参不会发生改变
传地址:指针传递是指针变量传递引用,指针传递中的形参和实参指向同一对象。
传引用: 形参发生改变,实参也发生改变
1.3 指针函数与函数指针的区别
英文字面意思理解
pointer to function int (*p)(int a,int b)
function return pointer int* func(int a,int b)
1.4 请说说内存分布模型、堆栈区别
1.堆栈空间分配方式不同。栈由编译器自动分配管理,存放运行函数的局部变量、函数参数等。堆由程序员自己分配释放。堆向上生长,栈向下生长的原因是最大化共用地址空间,如果都栈向上生长,则需要分界线。
2.栈使用一级缓存、堆使用二级缓存,由于栈的后进先出的特性所以不会产生内存碎片、而堆是随机申请空间因此会出现内存碎片的情况。
3.栈的空间大小比较小,不同的系统具有不同的栈大小,M级别,堆的空间大小比较大,G级别。
1.5 谈一谈内存碎片
内存碎片通常分为内部碎片和外部碎片:
1. 内部碎片是由于采用固定大小的内存分区,当一个进程不能完全使用分给它的固定内存区域时就产生了内部碎片,通常内部碎片难以完全避免;
2. 外部碎片是由于某些未分配的连续内存区域太小,以至于不能满足任意进程的内存分配请求,从而不能被进程利用的内存区域。
解决方案
[1] 现在普遍采用的段页式内存分配方式就是将进程的内存区域分为不同的段,然后将每一段由多个固定大小的页组成。通过页表机制,使段内的页可以不必连续处于同一内存区域,从而减少了外部碎片,然而同一页内仍然可能存在少量的内部碎片,只是一页的内存空间本就较小,从而使可能存在的内部碎片也较少。
[2] 内存池也是一种对象池,我们在使用内存对象之前,先申请分配一定数量的内存块留作备用。当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够再继续申请新的内存。当不需要此内存时,重新将此内存放入预分配的内存块中,以待下次利用。这样合理的分配回收内存使得内存分配效率得到提升
1.6 谈一谈new和malloc的区别
1:new是操作符并且可以被重载、malloc是函数。
2:new调用时不用指定申请内存的大小、并且调用构造函数,malloc需要指定申请内存的大小。
3:new发生错误抛出异常、malloc直接返回NULL。
1.7 简述C++从代码到可执行二进制文件的过程
过程:编译预处理->编译->汇编->链接
1.8 知道动态链接与静态链接吗?两者有什么区别?
链接分为静态链接和动态链接。
-
静态链接,是在链接的时候就已经把要调用的函数或者过程链接到了生成的可执行文件中,就算你在去把静态库删除也不会影响可执行程序的执行;生成的静态链接库,Windows下以.lib为后缀,Linux下以.a为后缀。
-
而动态链接,是在链接的时候没有把调用的函数代码链接进去,而是在执行的过程中,再去找要链接的函数,生成的可执行文件中没有函数代码,只包含函数的重定位信息,所以当你删除动态库时,可执行程序就不能运行。生成的动态链接库,Windows下以.dll为后缀,Linux下以.so为后缀。
区别
-
静态链接是将各个模块的obj和库链接成一个完整的可执行程序;而动态链接是程序在运行的时候寻找动态库的函数符号(重定位)
-
静态链接运行快、可独立运行;动态链接运行较慢(事实上,动态库被广泛使用,这个缺点可以忽略)、不可独立运行。
-
静态链接浪费空间,存在多个副本,同一个函数的多次调用会被多次链接进可执行程序,当库和模块修改时,main也需要重编译;动态链接节省空间,相同的函数只有一份,当库和模块修改时,main不需要重编译。
1.9说说const的作用
- const 用于定义常量,告诉编译器此值保持不变
- const int a
- const 修饰指针变量
- 指向常量的指针:指针指向一个常量对象,防止使用该指针修改指向的值 const int *a
- 常量指针:指针本身是一个常量,无法修改指针的指向。 int* const a
- const 修饰参数传递
- 值传递的const修饰传递
- 当const参数为指针时候,可以防止指针被意外篡改
- 自定义类型的参数传递时,需要临时对象赋值参数,对于临时对象的构造,需要调用构造函数,比较浪费时间,因此采用const外加引用的方式传递。
- const 修饰函数返回值
- const 修饰内置类型的返回值
- const 修饰自定义类型的返回值,此时返回值不能当作左值使用,既不能赋值也不能修改。
- const 修饰返回的指针或者引用,是否返回一个指向const的指针
- const修饰成员函数
- const修饰成员函数,其目的是防止成员函数修改被调用对象的值,如果我们不想修改一个调用对象的值,所有的成员函数都应当声明为const成员函数。
1.10 说说static关键字的作用
static具有持久性、隐藏(只能在本源文件中使用)、默认值为0的功能。
- static定义类中的静态成员变量:类中的的static静态数据成员拥有一块单独的存储区,不管创建了多少个该类的对象,所有这些对象的静态数据成员都共享这一块静态存储空间。
- static定义类中的静态成员函数:静态成员函数也是类的一部分,而不是对象的一部分。静态成员函数无法访问非静态成员,因为静态成员函数没有this指针。