赞
踩
本博文是本文历时3个月,收集各种资料,汇总的C++面试题,欢迎各位博友评价。
C中内存分为5个区:堆(malloc),栈(如:局部变量,函数参数),程序代码区(存放二进制代码),全局/静态存储区(全局变量,static变量)和常量存储区(常量)。
全局变量/static变量会初始化为零,而堆和栈上的变量是随机的,不确定的。
总得来说,堆是C语言和操作系统的术语,是操作系统维护的一块动态分配的内存;自由存储是C++中通过new与delete动态分配和释放的抽象概念,他们并不完全一样。
直接的说:堆用来存放动态分配的对象,通过malloc创建,free释放;而自由存储区是C++中通过new和delete动态分配和释放对象的抽象概念。
通过new来申请的内存区域可称为自由存储区。
1)预处理:对所有的define进行宏替换,处理所有的条件编译#idef等; 处理#include指令;删除注释等。
2)编译:将预处理后的文件进行词法分析,语法分析,语义分析以及优化相应的汇编文件。
3)优化
4)汇编:将汇编文件转化与机器能执行的文件
5)链接:包括地址和空间分配,符号决议和重定位。
用动态存储分配函数动态开辟的空间,使用完毕后未释放,结果导致一直占据该内存单元,即为内存泄露。
采用以下方法:
1)使用的时候要记得指针的长度;
2)malloc的时候得确定在哪里free;
3)对指针赋值的时候应该注意被赋值指针需要不需要释放;
4)动态分配内存的指针最好不要再次赋值;
5)在C++中应该优先考虑使用智能指针。
构造方法:
1)数字分析法;
2)平方取中法;
3)分段叠加法;
4)除留余数法 ;
5)随机数法;
处理冲突的方法:
1)开放地址法;
2)再哈希法;
3)拉链法;
4)建立公共溢出区;
1)定义只读变量,或者常量;
2)修饰函数的参数和函数的返回值;
3)修饰函数的定义体,这里的函数为类的成员函数,被const修饰的成员函数代表不能修改成员变量的值,因此const成员函数只能调用const成员函数。
4)只读对象,只读对象只能调用const成员函数。
在C中不能定义真正意义上的常量,因为C中的const仅仅从编译层来限定,不允许对const变量进行赋值操作,在运行期是无效的,所以并非真正的常量(比如:可以通过指针对const变量进行修改)。但是在C++中是有区别的,C++在编译时会把const常量加入符号表,以后(仍然在编译期)遇到这个变量会从符号中查找,所以C++中是不可能修改到const变量的,是真正意义上的常量。
1)没有任何构造函数时,编译器会自动生成默认构造函数,也就是无参构造函数;当类没有拷贝构造函数时,会生成默认拷贝构造函数。
2)深拷贝是指拷贝后对象的逻辑状态相同,而浅拷贝是指拷贝后对象的物理状态相同,默认拷贝构造函数为浅拷贝。
3)当系统中有成员指代了系统中的资源时,需要深拷贝。比如:指向了动态内存空间,打开了外存中的文件或者使用了系统中的网格接口等。如果不进行深拷贝,比如:动态内存空间,可能会出现多次被释放的问题。是否需要定义拷贝构造函数的原则是:类中是否有成员调用了系统资源,如果定义,那么拷贝构造函数一定是深拷贝;否则,没有意义。
1)C++中的类默认的成员是私有的,struct默认的是公有的;
2)C++中的类可以定义成员函数,struct只能定义成员变量。
1)耗时的操作使用线程,提高应用程序响应;
2)并行操作时使用线程,如:C/S架构的服务器并发线程响应用户的请求;
3)多CPU系统中,使用线程提高CPU的利用率;
4)改善程序结构,一个时长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样程序会利于理解和修改。
区别 | const | define |
---|---|---|
编译方式 | 编译时确定其值 | 预处理时进行替换 |
类型检查 | 有数据类型,编译时进行数据的检查 | 无类型,也不做类型检查 |
内存空间 | 在静态存储区存储,仅此一份 | 在代码段区,每做一次替换就会进行一次拷贝 |
防重复 | 可防止重复定义 | 不行 |
区别 | 指针 | 引用 |
---|---|---|
本质 | 一个变量,存储内容为一个地址 | 已有对象的别名 |
内存空间 | 为实体,分配内存空间 | 别名,不分配内存空间 |
存在多级 | 有多级指针 | 无多级引用 |
自增运行结果 | 不 同 | |
访问类型 | 间接访问 | 直接访问 |
初始化 | 不用初始化 | 需先初始化 |
1)数组对应一块内存,而指针指向一块内存。
2)数组的地址和空间大小在生命周期不会发生改变(内容可能发生改变);指针指向的内存大小可以随时发生改变,当指针指向常量字符串时,它的内容不可以改变。
3)计算容量的区别:用sizeof计算数组的元素个数,无法计算指针所指向内存的大小;
4)数组名是常量指针,指针是变量指针。
5)对数组&和对指针&的意义不同,此时数组名不在当成指向一个元素的常量指针来使用。
函数指针:为指向函数的指针,是指针变量,他与函数名无关,只与参数列表和返回类型有关;
指针函数:本质是函数,返回值为一个指针。
set是一种关联式容器,其特性如下:
1)set以RBTree作为底层窗口;
2)所有元素只有键没有值;
3)不允许出现键值重复;
4)所有的元素都会自动排序;
5)不能通过迭代器改变set的值,因为set的值就是健。
map和set一样是关联式容器,它们的底层容器是红黑树,区别就在于map的值不作为键,键和值是分开的,它的特性如下:
1)map以RBTree作为底层容器;
2)所有的元素都是键+值存在;
3)不允许键重复;
4)所有的元素是通过键进行自动排序的;
5)map的键是不能修改的,但是其键对应的值是可以修改的。
vector拥有一段连续的内存空间,因此支持随机存取,如果需要高效的随机存取,而不在乎插入和删除的效率,使用vector;
list拥有一段不连续的内存空间,因此不支持随机存取,如果需要大量的插入和删除,而不关心随机存取,则应使用。
1)作用域隐藏:当编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性,static可以用作函数和变量的前缀,对函数来讲,static的作用仅限于隐藏。
2)保持变量内容的持久:
3)默认初始化为0(static变量):
4)静态成员函数和静态成员变量是属于类的,所有对象只有一份拷贝。所以,不能将静态函数设置为虚函数。(虚函数是用来实现多态的,静态成员属于类而非对象,没有多态的概念)
1)设计思想上:C++进面向对象的语言,而C是面向过程的结构化编程语言;
2)C++三大特性:C++具有封装,继承和多态三种特性;
3)增加许多类型安全的功能,比如:强制类型转换,C++支持范式编程,比如:模板类,函数模板等。
当基类指针指向一个子类对象,通过这个指针调用子类和基类同名成员函数的时候,基类声明为虚函数就会调子类的这个函数,不声明就会调用基类的。
STL(Standard template libaray,标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据算法的软件框架。STL的容器分为以下几个大类:
顺序容器、关联式容器、容器适配器
三种类型容器特性分别如下:
函数原型:void* malloc(size_t n)返回值类型为void* ,为动态分配得到的内存,但大小是确定的,不允许越界使用。
malloc函数的实质体现在它有一个可以将可用内存块连接成一个长的列表的空闲链表,当调用malloc函数时,它沿着连接表寻找一个大到可以满足用户请求的内存块,将内存一分为二,将分配给用户的那块内存传给用户,剩下的那块返回连接表。
类型 | 内容 |
---|---|
属性 | new为关键字;malloc为库函数,需要头文件支持 |
参数 | 使用new申请内存无需指定内存大小,编译器自行计算;而malloc需要显示给出所需内存的大小 |
返回类型 | new分配成功返回的是对象类型指针;malloc返回的void * |
分配失败 | new分配失败,抛出bad_alloc异常;malloc则返回NULL |
内存区域 | new分配的内存在自由存储区,malloc在堆上分配内存 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。