c++面试题整理(含答案)

知乎链接:

https://www.zhihu.com/question/34574154/answer/253165162?utm_source=com.tencent.tim&utm_medium=social&utm_oi=804337922299031552

 

校招主要考察基础和思维,主要涉及C++语言基础,数据结构与算法,TCP/IP协议,网络编程,Linux。

C和C++语言基础

参考书籍:《C++ primer》,《effective C++》,《STL源码解析》,《深度搜索C++对象模型》

  • extern关键字作用
  • 1当它与"C"一起连用时,如: extern "C" void fun(int a, int b);则告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数
  • 2它的作用就是声明函数或全局变量的作用范围的关键字,其声明的函数和变量可以在本模块活其他模块中使用

static关键字作用

1 它的第一条也是最重要的一条:隐藏。(static函数,static变量均可)

当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。

2 static的第二个作用是保持变量内容的持久。(static变量中的记忆功能和全局生存期)

3.static的第三个作用是默认初始化为0(static变量)

4.static的第四个作用:C++中的类成员声明static(有些地方与以上作用重叠)

 

volatile是干啥的:

const的作用:

1. const仅仅用来修饰右边的变量(基本数据变量p,指针变量*p)
2. 被const修饰的变量是只读的。

new与malloc区别

0.  属性 :new/delete是C++关键字,需要编译器支持。malloc/free是库函数,需要头文件支持。

1. 参数

使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸。

2.  返回类型

new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。

3.  分配失败

new内存分配失败时,会抛出bac_alloc异常。malloc分配内存失败时返回NULL。

4. 自定义类型

 new会先调用operator new函数,申请足够的内存(通常底层使用malloc实现)。然后调用类型的构造函数,初始化成员变量,最后返回自定义类型指针。delete先调用析构函数,然后调用operator delete函数释放内存(通常底层使用free实现)。

         malloc/free是库函数,只能动态的申请和释放内存,无法强制要求其做自定义类型对象构造和析构工作。

5. 重载

C++允许重载new/delete操作符,特别的,布局new的就不需要为对象分配内存,而是指定了一个地址作为内存起始区域,new在这段内存上为对象调用构造函数完成初始化工作,并返回此地址。而malloc不允许重载。

6.  内存区域

new操作符从自由存储区(free store)上为对象动态分配内存空间,而malloc函数从堆上动态分配内存。自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。自由存储区不等于堆,如上所述,布局new就可以不位于堆中。

 

静态多态和动态多态。静态多态是指通过模板技术或者函数重载技术实现的多态,其在编译器确定行为。动态多态是指通过虚函数技术实现在运行期动态绑定的技术。

虚函数表

虚函数的地址被存储一张叫做虚表的东西里,

每个类都会维护一张虚表,编译时,编译器根据类的声明创建出虚表,当对象被构造时,虚表的地址就会被写入这个对象内存的起始位置。这就是多态性在 C++ 中实现的方式,而像 Java、OC 这样的语言由于 Runtime 的存在,这些对象会有多余的内存空间记录类的信息(meta-object),在运行时根据这些信息解析出相应的函数去执行。虽然不同,但是异曲同工。


指针和引用的区别:

(1)非空区别。任何情况下都不能使用指向空值的引用。一个引用必须总是指向某 
些对象。因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指 
向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量。相反,如果 
变量肯定指向一个对象,例如你的设计不允许变量为空,这时你就可以把变量声明为引用。 
不存在指向空值的引用这个事实意味着使用引用的代码效率比使用指针要高。 
(2)合法性区别。在使用引用之前不需要测试它的合法性。相反,*指针则应该总是被 
测试,防止其为空**。 
(3)可修改区别。指针与引用的另一个重要的区别是指针可以被重新赋值以指向另一 
个不同的对象。但是引用则总是指向在初始化时被指定的对象,以后不能改变,但是指定的 
对象其内容可以改变。 
(4)应用区别。总的来说,在以下情况下应该使用指针:一是考虑到存在不指向任何 
对象的可能(在这种情况下,能够设置指针为空),二是需要能够在不同的时刻指向不同的 
对象(在这种情况下,你能改变指针的指向)。如果总是指向一个对象并且一旦指向一个对 
象后就不会改变指向,那么应该使用引用。

 

内联函数有什么优点?内联函数与宏定义的区别?

内联函数和普通函数相比可以加快程序运行的速度,因为不需要中断调用,在编译的时候内联函数可以直接被镶嵌到目标代码中。内联函数要做参数类型检查,这是内联函数跟宏相比的优势。

inline是指嵌入代码,就是在调用函数的地方不是跳转,而是把代码直接写到那里去。对于短小的代码来说,inline可以带来一定的效率提升,而且和C时代的宏函数相比,inline 更安全可靠。可是这个是以增加空间消耗为代价的。至于是否需要inline函数就需要根据你的实际情况取舍了。

宏是在代码处不加任何验证的简单替代,而内联函数是将代码直接插入调用处,而减少了普通函数调用时的资源消耗。

宏不是函数,只是在编译前(编译预处理阶段)将程序中有关字符串替换成宏体。

inline函数是函数,但在编译中不单独产生代码,而是将有关代码嵌入到调用处。

 

必须在构造函数初始化式里进行初始化的数据成员有哪些:

1,常量成员

常量成员只能初始化不能赋值,所以必须放在初始化列表里。

2,引用类型

引用必须在定义时初始化,并且不能重新赋值,所以必须放在初始化表里。

3,对象成员

这个成员是其他类的对象,例如上面的Address  addr成员。如果把它放在构造函数的初始化列表里,此时会调用Address类的copy constructor函数,对这个类对象进行初始化。如果把它放在构造函数体中,会先调用Address类的default constructor函数,然后再调用Address类的copy constructor函数。从性能上考虑,把对象成员的初始化放在初始化列表里性能会更高。

 

手写strcpy,memcpy,strcat,strcmp等函数

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值