C++方向的面试题总结

1.C++中struct和class的区别是什么?

解答:C++需要兼容C语言,所以C++中struct可以当成结构体去使用。另外C++中struct还可以用来定义类。 和class是定义类是一样的,区别是struct的成员默认访问方式是public,class是struct的成员默认访问方式 是private。

2.C++面向对象的三大特性:封装/继承/多态

解答:
封装:将数据和操作数据的方法进行有机的结合,隐藏对象的属性的实现细节,仅对外公开接口和对象 进行交互
封装的本质是一种管理:兵马俑的例子

3.结构体怎么对齐? 为什么要进行内存对齐?

解答:
1.第一个成员与结构体的偏移量是0
2.其他成员要对齐到对齐数的整数倍数的地址处
(对齐数vs中默认为8,gcc中默认为4,取默认对齐数和变量数据类型大小的较小值作为对齐数)
3.结构体的总大小为:最大对齐数的整数倍
4.如果嵌套了结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的总大小就是所有最大对齐数(含嵌套的结构体)的整数倍处

为什么进行对齐?
1.平台移植原因:不是所有的硬件平台都能随意的访问任意地址上的任意数据的,某些硬件只能在某些地址处取某些特定类型的数据,否则抛出硬件异常
2.性能原因:数据结构(尤其是栈)应该尽可能的在自然边界上对齐,原因在于,为了访问未对齐的内存,处理器需要作两次访问,而对齐的内存访问仅需要一次

如何让结构体按照指定的大小进行对齐
1.使用(#pragma pack())
2.在编译器中自行设置

如何知道结构体中的某个成员相对于结构体起始位置的偏移量?
printf("%d\n",offsetof(A,c));用offsetof这个宏去求结构体中成员在结构体中的偏移量

什么是大小端?如何测试一台机器是大端还是小端,有没有遇到过需要考虑大小端的场景?

小端:低地址存低位;
大端:低地址存高位;
在这里插入图片描述
vs2013中是小端存储的
使用共用体测试大小端

#include <iostream>
using namespace std;

int sys() {
	union un
	{
		char a;
		int b;
	}un;
	un.b = 1;
	return un.a;
}

int main() {

	int ret = sys();
	if (1 == ret) {
		cout << "当前机器为小端存储" << endl;
	}
	else
		cout << "当前机器为大端存储" << endl;
	
	cout<<"hello....."<<endl;
	system("pause");
	return 0;
}

利用指针方法

int sys() {
	int a = 1;
	char* p = (char*)&a;
	if (*p == 1)
		cout << "小端" << endl;
	else
		cout << "大端" << endl;
}

在套接字编程时需要考虑大小端的问题

4.this指针存在哪里?this指针可以为空吗?

this指针存在哪里?
this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址最为实参传递给this形参的.所以对象中不存储this指针
this指针是成员函数第一个隐含的指针形参,一般情况下是由编译器通过ecx寄存器自动传递的,不需要用户传递

this指针可以为空吗?
可以为空,当我们在调用函数的时候,如果函数内部并不需要使用到this,也就是不需要通过this指向当前对象并对其进行操作时才可以为空(当我们在其中什么都不放或者在里面随便打印一个字符串),如果调用的函数需要指向当前对象,并进行操作,则会发生错误(空指针引用)就跟C中一样不能进行空指针的引用.

5.malloc/calloc/realloc的区别

1.malloc分配一块内存空间,但他不能初始化内存空间,返回值为void*,C和C++允许强制类型转换
2.calloc分配一块内存空间并将该空间中值初始化为0;
3.realloc重新分配空间大小(缩小或者扩大),一般在已有的空间后面开辟内存,如果大小不够则在堆上寻找足够大小的neicun,并将老的空间返回到堆上

6.malloc/free和new/delete的区别

malloc/free和new/delete的共同点是:都是从堆上开辟内存空间,并且需要用户手动进行释放,

不同点:
1.malloc和free是库函数,new和delete是操作符
2.malloc申请的空间不会初始化,new可以进行初始化
3.malloc申请空间时,需要通过手动计算空间大小并传递,new只需在后面跟上空间类型即可
4.malloc的返回值是一个void*,在使用的时候必须进行强制类型转换,new不需要,因为new后跟的是空间类型
5.malloc申请空间失败时会返回一个NULL,因此使用的时候必须判空,new不需要,但是new需要捕获异常
6.申请自定义类型对象时,malloc/free只会开辟内存空间,不会调用构造函数和析构函数,而new在申请空间后会调用构造函数完成对对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理

7.vector和list的区别?

对比vectorlist



动态顺序表一段连续的空间带头结点的双向循环链表


访
支持随机访问访问效率为O(1)不支持随机访问访问效率为O(n)




任意位置插入和删除效率低
需要搬动元素时间复杂度为O(n)
增容:开辟新空间拷贝元素释放旧空间
导致效率更低
任意位置插入和删除效率高
不需要搬动元素,时间复杂度为O(1)




底层为连续空间不容易造成内存碎片
空间利用率高缓存利用率高
底层结点动态开辟,小结点
容易造成内存碎片,空间利用率低
缓存利用率低


原生态指针对原生态指针<结点指针>进行封装




在插入元素时要给所有元素重新赋值,因为插入
元素可能会导致重新扩容,致使原来迭代器失效,删
除时,当前迭代器需要重新赋值否则失效
插入元素不会导致迭代器失效,
删除元素时只会导致当前迭代器
失效,其他迭代器不受影响
使


需要高效存储,支持随机访问,不关心插入删除效率大量插入删除,不关心随机访问

8.为什么要将deque作为stack和queue的底层结构?

stack是一种先进后出的特殊线性结构,因此只要具有push_back()和pop_back()操作的线性结构,都可以作为stack的底层容器,比如vector和list都可以;queue是先进先出的特殊线性数据结构,只要具有
push_back()和pop_back()操作的线性结构,都可以作为queue的底层容器,比如list.但在STL中对stack和queue默认选择deque作为其底层容器,主要是因为:

1.stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或者两端进行操作.
2.在stack中元素增长时,deque比vector的效率高,queue中的元素增长时,deque不仅效率高,而且内存使用率高.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值