[面试经验]C++相关面试题

来源:互联网 发布:苹果4s有4g网络吗 编辑:程序博客网 时间:2024/06/17 02:31

C++内存分配方式?

1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其
操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回
收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的
全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另
一块区域。 - 程序结束后由系统释放。–>分别是data区,bbs区
4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放–>coment区
5、程序代码区—存放函数体的二进制代码。–>code区

new、delete、malloc、free关系

delete会调用对象的析构函数,和new对应free只会释放内存,new调用构造函数。malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。

有哪几种情况只能用intialization list 而不能用assignment?

答案:当类中含有const、reference 成员变量;基类的构造函数都需要初始化表。

请说出const与#define 相比,有何优点?

答案:
const作用:定义常量、修饰函数参数、修饰函数返回值三个作用。被Const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。
1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。
2) 有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。

简述数组与指针的区别?

1、数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任意类型的内存块。
2、数组可以用sizeof计算所有元素占用内存大小,而指针不行。
3、指针和数组在当函数参数传递的时候效果是一样的。

引用与指针有什么区别?

1) 引用必须被初始化,指针不必。
2) 引用初始化以后不能被改变,指针可以改变所指的对象。
3) 不存在指向空值的引用,但是存在指向空值的指针。

const 与 #define 的比较 ,const有什么优点?

(1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误(边际效应) 。
(2) 有些集成化的调试工具可以对 const 常量进行调试,但是不能对宏常量进行调试。

复杂声明

void * ( * (*fp1)(int))[10];float (*(* fp2)(int,int,int))(int);int (* ( * fp3)())[10]();//分别表示什么意思?

1.void * ( * (fp1)(int))[10]; fp1是一个指针,指向一个函数,这个函数的参数为int型,函数的返回值是一个指针,这个指针指向一个数组,这个数组有10个元素,每个元素是一个void型指针。
2.float (( fp2)(int,int,int))(int); fp2是一个指针,指向一个函数,这个函数的参数为3个int型,函数的返回值是一个指针,这个指针指向一个函数,这个函数的参数为int型,函数的返回值是float型。

基类的析构函数不是虚函数,会带来什么问题?

派生类的析构函数用不上,会造成资源的泄漏。

结构体和共同体的区别。

结构体struct:把不同类型的数据组合成一个整体,自定义类型。

共同体union:使几个不同类型的变量共同占用一段内存。

关于重载(overload)、重写(overwrite)、隐藏(overhide)的区别?

Overload(重载):在C++程序中,可以将语义、功能相似的几个函数用同一个名字表示,但参数或返回值不同(包括类型、顺序不同),即函数重载。
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
Override(覆盖):是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
注:重写基类虚函数的时候,会自动转换这个函数为virtual函数,不管有没有加virtual,因此重写的时候不加virtual也是可以的,不过为了易读性,还是加上比较好。
Overwrite(重写):隐藏,是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。

STL中的map和set的区别以及特性?

set的特性:

set以RBTree作为底层容器
所得元素的只有key没有value,value就是key,不允许出现键值重复
所有的元素都会被自动排序
不能通过迭代器来改变set的值,因为set的值就是键
map的特性:
map以RBTree作为底层容器
所有元素都是键+值存在 不允许键重复
所有元素是通过键进行自动排序的
map的键是不能修改的,但是其键对应的值是可以修改的

为何map和set的插入删除效率比用其他序列容器高?

不需要做内存拷贝和内存移动。说对了,确实如此。map和set容器内所有元素都是以红黑树节点(如下)的方式来存储

堆栈溢出的原因?

没有回收垃圾资源
栈溢出:
一般都是由越界访问导致的。例如局部变量数组越界访问或者函数内局部变量使用过多,超出了操作系统为该进程分配的栈的大小。
堆溢出:
由于堆是用户申请的,所以溢出的原因可能是程序员申请了资源但是忘记释放了。

刷新缓冲区方式?

换行刷新缓冲区:printf(“\n”);
程序结束刷新缓冲区:return 0;

编写一个标准strcpy函数

char * strcpy( char *strDest, const char *strSrc )//为了实现链式操作,将目的地址返回,加3分!
{
  assert( (strDest != NULL) &&(strSrc != NULL) );
  char *address = strDest;
  while( (strDest++ = strSrc++) != ‘\0’ );
  return address;
}

C和C++有什么不同?

(1)c是面向过程的,也就是说更偏向逻辑设计;c++是面向对象的,提供了类,偏向类的设计。
(2)c适合要求代码体积小的,效率高的场合,如比如嵌入式。

什么是“野指针”?

野指针指向一个已删除的对象或无意义地址的指针。与空指针不同,野指针无法通过简单地判断是否为 NULL避免,而只能通过养成良好的编程习惯来尽力避免。
造成的主要原因是:指针变量没有被初始化,或者指针p被free或者delete之后,没有置为NULL。

sizeof和strlen()的区别:

① sizeof是运算符,计算数据所占的内存空间;strlen()是一个函数,计算字符数组的字符数;
② sizeof可以用类型作参数;strlen()只能用char*作参数,必须是以‘/0’结束
③ 数组做sizeof的参数不退化,传递给strlen就退化为指针了;
④ sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。该类型保证能容纳实现建立的最大对象的字节大小。

什么是void类型的指针?

void指针可以指向任意类型的数据,即可用任意数据类型的指针对void指针赋值。
http://blog.csdn.net/lee_shuai/article/details/53193436

C++文件编译与执行的四个阶段

第一阶段:预处理阶段。根据文件中的预处理指令来修改源文件的内容。如#include指令,作用是把头文件的内容添加到.cpp文件中。
第二阶段:编译阶段,将其翻译成等价的中间代码或汇编代码。
第三阶段:汇编阶段,把汇编语言翻译成目标机器指令。
第四阶段:是链接,例如,某个源文件中的函数可能引用了另一个源文件中定义的某个函数;在程序中可能调用了某个库文件中的函数。
http://www.cnblogs.com/dongdongweiwu/p/4743709.html(编译阶段介绍)

声明struct x1 { … }; 和typedef struct { … } x2; 有什么不同?

第一种形式声明了一个“结构标签”;
第二种声明了一个“类型定义”。
主要的区别是第一种方式定义结构体变量需要写“struct x1”而引用第一种, 而第二种方式定义结构体变量不需要使用struct 关键字。

拷贝构造函数相关问题,深拷贝,浅拷贝,临时对象等。

深拷贝意味着拷贝了资源和指针,而浅拷贝只是拷贝了指针,没有拷贝资源
这样使得两个指针指向同一份资源,可能造成对同一份析构两次,程序崩溃。而且浪费时间,并且不安全。
临时对象的开销比局部对象小些。

外加100道经典C++面试题链接:http://www.jobui.com/mianshiti/it/cpp/5018/

看完这些面试C++要是还过不了,肯定是人太丑了,怕招你去拉低程序员平均颜值…….

阅读全文
0 0
原创粉丝点击