c++面试题汇总-58-118

2026芯片公司能力五维评估模型 芯片公司技术实力不能仅看TOPS或工艺节点,而应回归可验证的工程本质:制程适配深度决定硅后稳定性,IP复用效率反映设计资产沉淀,验证闭环速度保障流片成功率,软件栈交付厚度影响客户导入周期,量产良率爬坡曲线体现制造协同能力。这五大维度相互咬合,共同构成AI芯片与边缘SoC在2026年能否规模落地的核心技术标尺。面向硬件选型、系统集成与供应链决策,需以PDK定制能力、Verification Reuse Report、Process Window Analysis等实证材料为依据,穿透营销话术,识别真实工程能力 阅读详情

c++面试题汇总-58-118

58. class和struct在使用大括号{ }上的区别

关于使用大括号初始化
1.class和struct如果定义了构造函数的话,都不能用大括号进行初始化
2.如果没有定义构造函数,struct可以用大括号初始化。
3.如果没有定义构造函数,且所有成员变量全是public的话,class可以用大括号初始化

59. 说说static关键字的用法和特点

引出原因:函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现?
最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。类的静态成员也是这个道理。
解决方案:因此C++中引入了static,用它来修饰变量,它能够指示编译器将此变量在程序的静态存储区分配空间保存,这样即实现了目的,又使得此变量的存取范围不变static函数的作用
1.static 全局变量:
只能在当前文件使用的全局变量,不支持extern
2.static 局部变量:
在局部使用
3.static 修饰成员属性
存放在全局区,类共享的变量,不能被继承(共用),补依赖对象存在,要在类外初始化,不能在.h文件中初始化(会发生重定义),需要在.cpp文件中初始化 使用时 类名::
4.static 修饰成员函数
类共用的,不能被virtual修饰,不能直接调用非静态成员属性,想调用要依赖对象,只能调用静态的,【实质:static函数无this指针】
5.static对象 与变量的理解一样
【const和static不能修饰成员属性和成员函数,可以修饰变量】

60. 迭代器失效的原因?(迭代序列改变前和改变后是否有变化)

数组型数据结构:该数据结构的元素是分配在连续的内存中,insert和erase操作,都会使得删除点和插入点之后的元素挪位置,所以,插入点和删除点之后的迭代器全部失效,也就是说insert(*iter)(或erase(*iter)),然后在iter++,是没有意义的。解决方法:erase(*iter)的返回值是下一个有效迭代器的值。 iter =cont.erase(iter);
链表型数据结构:对于list型的数据结构,使用了不连续分配的内存,删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器。解决办法两种,erase(*iter)会返回下一个有效迭代器的值,或者erase(iter++)。
树形数据结构: 使用红黑树来存储数据,插入不会使得任何迭代器失效;删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器。erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用erase(iter++)的方式删除迭代器。
注意:经过erase(iter)之后的迭代器完全失效,该迭代器iter不能参与任何运算,包括iter++,*ite
https://blog.youkuaiyun.com/cmdxly/article/details/126587100?spm=1001.2014.3001.5501

61. 使用过哪些容器?

顺序性容器:vector,deque,list,forward_list(单向链表)
关联性容器:map/unordered_map,set/unordered_sethash表,当元素总量超过buckets的数量后,进行rehashing,对散列表进行扩容,将元素进行重新散列(解决哈希冲突使用的是拉链法)
容器配置器:stack,queue
<1>vector容器
vector容器是一个动态数组的结构,在内存中有一个指针指向一块连续的内存。类似数组结构一样。它的特点支持随机访问数据,因为其在内存中的单元是连续。如此之外, vector的大小是可以自动增长的。当向一个vector中继续存放数据的时候,如果当前的内存大小不够,内核会重新生成一个是原来1.5倍的大小的单元,之后将数据从原先的单元中拷贝至新创建的单元中,并将原来的单元释放掉。(但是所谓的释放单元,仅仅是将原来单元中的数据清空,相应的内存单元还是存在的)
优点:支持随机访问,所以查询效率高。
缺点:当向其分非尾插入元素时,因内存单元需要移动数据元素,所以插入的效率比较低。
适用场景:适用于对象简单,变化较小,并且频繁随机访问的场景。
2.deque容器
deque和vector类似,支持快速随机访问。二者最大的区别在于,vector只能在末端插入数据,而deque支持双端插入数据。deque的内存空间分布是小片的连续,小片间用链表相连,实际上内部有一个map的指针。deque空间的重新分配要比vector快,重新分配空间后,原有的元素是不需要拷贝的。deque的连续是假象,实际为分段连续每次扩充一个buffer
2.list容器
list容器在内存中的结构是类似双向链表结构,每个元素的内存单元结构是不连续的,彼此之间通存储相关的地址进行关联。由于在内存中的单元不是连续的,所以其不支持随机访问,不具备[]操作运算。每一个节点都有三个域,前驱节点指针域,数据域,后驱节点指针域。
优点:因为类似链表结构在内存中,所以任意位置删除节点和插入节点都是高效的。
缺点:因为内存单元不连续,所以不支持随机访问操作。
适用场景:对象变化大,并且对象数量变化频繁,删除和插入操作的情况。
3.map容器
map容器是一个关联式容器。在其内部元素的存储结构是通过key-value结构进行存储,并且其key是唯一存在的。支持那种一对一的数据处理过程。其底层是通过rbtree来实现的,利用红黑树的一种严格的平衡二叉树结构实现。在其实现过程,自动创建key-value的插入数据的过程。并且支持快速的查找,通过键值可进行快速的查找对应的数据元素。以及快速删除操作。
4.set容器
set也是一种关联性容器,它同map一样,底层使用红黑树实现,插入删除操作时仅仅移动指针即可,不涉及内存的移动和拷贝,所以效率比较高。set中的元素都是唯一的,而且默认情况下会对元素进行升序排列。所以在set中,不能直接改变元素值,因为那样会打乱原本正确的顺序,要改变元素值必须先删除旧元素,再插入新元素。不提供直接存取元素的任何操作函数,只能通过迭代器进行间接存取。

62. STL中的sort使用什么排序?

快排+插入排序+堆排序
vector,deque适用sort算法
STL的sort算法,数据量大时采用快速排序,分段归并排序。一旦分段后的数据量小于某个门槛(16),为避免快排的递归调用带来过大的额外负荷,就改用插入排序。如果递归层次过深,改用堆排序,因为堆排序是时间复杂度恒定为nlogn,又因为插入排序在面对“几近排序”的序列时,表现更好

63. 静态全局变量和全局静态变量一样吗?若有不同,体现在哪?

首先,并不是说全局变量在定义时加了static关键字才是静态存储,不加static就是动态存储,不是的。不管加不加static,全局变量都是存储在静态存储区的,都是在编译时分配存储空间的,两者只是作用域不同,全局变量默认具有外部链接性,作用域是整个工程,全局静态变量的作用域仅限本文件,不能在其他文件中引用。

64. 左值,右值,右值引用

左值:左值是指表达式结束后依然存在的持久化对象
右值:表达式结束时就不再存在的临时对象
区分:看能不能对表达式取地址,如果能,则为左值,否则为右值。

65. 函数参数传递的三种方式

函数的参数传递:当进行函数调用的时候,要填入与函数形式参数个数相同的实际参数,在程序运行的过程中,实参会将参数值传递给形参,这就是函数的参数传递。
函数参数传递有以下三种:
一. 值传递 void fun(int x)

  1. 用值传递方式,实际上是把实参的内容复制到形参中,实参和形参是存放在两个不同的内存空间中。在函数体内对形参的一切修改对实参都没有影响;
  2. 如果形参是类的对象,利用值传递的话每次都要调用类的构造函数构造对象,效率比较低。
    二. 指针传递(地址传递)void fun(int *x)
  3. 当进行指针传递的时候,形参是指针变量,实参是一个变量的地址或者是指针变量,调用函数的时候,形参指向实参的地址;
  4. 指针传递中,函数体内可以通过形参指针改变实参地址空间的内容。
    三. 传递引用 void fun(int &x)
    1.引用实际上是某一个变量的别名,和这个变量具有相同的内存空间;
  5. 实参把变量传递给形参引用,相当于形参是实参变量的别名,对形参的修改都是直接修改实参;
  6. 在类的成员函数中经常用到类的引用对象作为形参,大大的提高代码的效率。

66. C++中父类指针指向子类对象是如何实现的?

#include<iostream>
using namespace std;

//基类
class Base
{
public:
	Base()
	{
		cout<<"===Base()==="<<endl;
	}
	//虚析构函数
	virtual int fun() = 0;
	~Base()
	{
		cout<<"===~Base()==="<<endl;
	}
};
//子类
class Son:public Base
{
public:
	Son()
	{
		cout<<"===Son()==="<<endl;
	}
	int  fun()
	{
		cout<<"===fun()==="<<endl;
		return 0;
	}
	~Son()
	{
		cout<<"===~Son()==="<<endl;
	}
};
 void test()
 {
	Son s;
	s.fun();
	//父类指针指向子类对象
	Base *b = &s;
	b->fun();
 }
 int main()
 {
	 test();
	 return 0;
 }

67. 如何不用第三个变量交换两个地址空间?

A = A + B;
B = A – B:
A = A – B;
或者
A = A ^ B;
B = A ^ B;
A = A ^ B;

68. 什么是深拷贝?什么是浅拷贝?(浅拷贝共用一个实体,深拷贝相互独立)

深拷贝:源对象和拷贝对象相互独立,其中任何一个对象的改动都不会对另外一个对象造成影响
浅拷贝:源对象与拷贝对象共用一份实体,仅仅是引用的变量不同,对其中任何一个改动,都会影响另一个对象
浅拷贝的影响:

  1. 两个对象的指针成员可能指向相同的内存,相互影响。
  2. 对其中一个指针进行释放操作或销毁析构,将导致另一个指针成为 “悬空指针”

69. 深拷贝和浅拷贝各出现什么时候?

c++类的中有两个特殊的构造函数
(1) 无参构造函数,(2)拷贝构造函数。
它们的特殊之处在于:
(1)当类中没有定义任何构造函数时,编译器会默认提供一个无参构造函数且其函数体为空;
(2)当类中没有定义拷贝构造函数时,编译器会默认提供一个拷贝构造函数,进行成员变量之间的拷贝。(系统不知道申请多大空间,所以只能浅拷贝)
1.70. 什么是拷贝构造?什么时间会用到拷贝构造?
在什么情况下系统会调用拷贝构造函数:(三种情况)
(1)用类的一个对象去初始化另一个对象时
(2)当函数的形参是类的对象时(也就是值传递时),如果是引用传递则不会调用
(3)当函数的返回值是类的对象或引用时

拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它的一个参数必须是本类型的一个引用变量。

71. 拷贝构造参数为什么是引用传递,改成值传递或者地址传递可以吗?

首先值传递是不可以的,使用值传递,那么就需要给形参拷贝构造,形参还会再给形参拷贝构造,就会陷入死循环;如果使用地址传递,不符合使用习惯,因为拷贝构造,是使用对象来给另一个对象来初始化,这里不使用指针,所以用地址传递不符合习惯

72. 句柄和指针的区别?

句柄实际上是一种指向某种资源的指针,但与指针又有所不同:指针对应着一个数据在内存中的地址,得到了指针就可以自由地修改该数据。Windows并不希望一般程序修改其内部数据结构,因为这样太不安全。所以Windows给每个使用GlobalAlloc等函数声明的内存区域指定一个句柄(本质上仍是一个指针,但不要直接操作它),平时你只是在调用API函数时利用这个句柄来说明要操作哪段内存。当你需要对某个内存进行直接操作时,可以使用GlobalLock锁住这段内存并获得指针来直接进行操作。
https://blog.youkuaiyun.com/weixin_42845574/article/details/89110434

73. 结构体和联合体的区别?

结构体:是一种数据类型,把不同类型的数据组合成一个整体,其内存在对齐后为各个数据成员的和(引向字节对齐)
联合体:使几个不同类型变量共占同一段空间(相互覆盖),其内存大小为联合体中成员内存最大的那个,存入新成员后,旧有成员失效

74. 字节对齐的意义?

首先,我们需要明确无论数据是否对齐,大多数计算机还是能够正确工作,但在有些处理器中,如果存在未对齐的数据,可能无法运行。
我们假设计算机总是从内存中取8个字节,如果一个double数据的地址对齐成8的倍数,那么一次内存操作就可以读或者写。
但是如果这个double数据的地址没有对齐,数据就可能被放在两个8字节块中,那么我们可能需要执行两次内存访问,才能读写完成。
显然在这样的情况下,是低效的,所以需要字节对齐来提高内存读写性能。

75. 静态链接库和动态链接库链接的过程,显式和隐式的区别,其中动态链接库的显式调用的几个函数?

Windows
静态库:函数和数据被编译进一个二进制文件(.lib)(一个或多个obj文件打包),在编译链接可执行文件时,链接器从库中复制这些函数和数据并把它们和应用程序的其他模块组合起来创建最终的可执行文件(.exe)。

动态库:使用动态库时,往往提供两个文件:引入库(后缀也为.lib)、动态链接库(.DLL)。引入库包含被DLL导出的函数和变量的符号名,DLL包含实际的函数和数据。在编译链接可执行文件时,只需要链接引入库,DLL中的函数代码和数据并不可复制到可执行文件中,在运行时,再去加载DLL,访问DLL中导出的函数。

隐式调用:在编译/链接阶段完成,由编译系统根据动态库的头文件和库文件进行编译和链接,即需要将引入库加入到应用程序的工程中,从而确定待调用的函数原型和地址。

显示调用:利用API函数实现加载和卸载DLL,获取调用函数地址获取错误信息等功能。

Linux
静态库:与Windows下的静态库类似,后缀名为.a。

动态库:与Windows下动态库类似,没有引入库,后缀名为.so。

隐式调用:编译可执行程序时需要指定库文件的搜索路径。

显式调用:显式调用编译可执行程序时不用加上动态库的搜索路径(因为已经在主函数中包含了库文件的路径),但是需要增加几个系统调用。

76. delete和delete[]的用法,使用不当为什么会造成那些现象?原理是什么?

https://blog.youkuaiyun.com/ARLoverKang/article/details/9122413

77. main函数为什么返回0,返回0代表什么?成功返回后程序还会走其他函数吗?

在这里插入图片描述

78. 内存池的好处?

为什么需要内存池:

  1. 因为在C/C++下的内存管理需要调用malloc或者是new,系统需要根据最先匹配和最优匹配或者其他算法在内存空闲块表中查找一块空闲内存,调用free/delete,系统可能需要合并空闲内存块,这些会产生额外的开销
  2. 频繁使用时会产生大量的内存碎片,从而降低程序效率
  3. 容易造成内存泄漏

什么是内存池?
代替直接调用malloc/free、new/delete进行内存管理的常用方法,当我们申请内存空间时,首先到我们的内存池中查找合适的内存块,而不是直接向操作系统申请,优势在于:

  1. 比malloc/free进行内存申请/释放的方式快
  2. 不会产生或很少产生堆碎片
  3. 可避免内存泄漏
    内存池的架构?

79. extern,static的区别?static和auto变量的区别?

https://www.jb51.net/article/234831.htm

80. fopen和open的区别?

https://blog.youkuaiyun.com/qq_26690505/article/details/120201708

81. 析构函数为什么要声明成虚函数?

我们知道在类的继承中,构造函数的执行顺序是先构造基类然后再构造派生类,析构函数则相反,是先析构派生类再析构基类。我们也知道声明父类的指针指向派生类,编译器会默认实施静态绑定,不能调用派生类重写的函数,所以才需要虚函数。虚函数是通过虚函数表实现,在运行时进行动态绑定,可以调用在派生类重写的函数。那么如果一个类存在派生,那么就应该将基类的析构函数声明为虚函数,否则,将实施静态绑定无法析构派生类对象。
https://blog.youkuaiyun.com/Li_haiyu/article/details/88082071

82. 位运算有哪些?怎么用?

https://blog.youkuaiyun.com/qq_54180412/article/details/126160242

83. 指针大小多大?是确定的吗?

https://blog.youkuaiyun.com/puppet_master/article/details/49963727
指针大小是由当前CPU运行模式的寻址位数决定!

84. 内联和宏的应用场合?

https://blog.youkuaiyun.com/Mr_H9527/article/details/100596854

85. 局部变量可以和全局变量重名吗?

能,局部会屏蔽全局。要用全局变量,需要使用 “::” ;
局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。

86. 左++和右++哪个效率高,原因?

https://blog.youkuaiyun.com/weixin_42795141/article/details/89331430

87. 用过GetLastError吗?怎么实现的?

https://blog.youkuaiyun.com/liunan199481/article/details/94432950

88. 普通函数和虚函数的区别?

https://blog.youkuaiyun.com/weixin_50897975/article/details/123913888

89. 左引用和右引用?

https://www.cnblogs.com/kaleidopink/p/13720773.html

90. 智能指针有哪些?

https://blog.youkuaiyun.com/misterdo/article/details/108684059

91. unique_ptr可以拷贝吗?

不能
https://blog.youkuaiyun.com/qq_34525916/article/details/121822361

92. 容器是线程安全的吗 怎么保证线程安全?

不是
https://cloud.tencent.com/developer/article/1915007

93. 如果底层是hash表怎么加锁?

94. 如何理解互斥锁、条件变量、读写锁以及自旋锁?

https://mp.weixin.qq.com/s?__biz=MjM5NDIyMjI3OQ==&mid=2649002539&idx=1&sn=b0cd8b1d1e471be565168b71458863e4&scene=21#wechat_redirect

95. C++异常?

https://blog.youkuaiyun.com/weixin_45966328/article/details/120474036

96. shared_ptr和unique_ptr的区别

https://blog.youkuaiyun.com/MissXy_/article/details/81029794

97. int const * p和int * const p的区别

https://blog.youkuaiyun.com/weixin_52848650/article/details/116658437

98. map和unordered_map的底层实现和复杂度以及两者区别(红黑树和hash表)

https://blog.youkuaiyun.com/sebeefe/article/details/124164460

99. 手写智能指针shared_ptr

#include <iostream>
#include <memory>
using namespace std;
template<typename T>
class my_shared_ptr {
private:
	size_t* _useCnt;  
	T* _ptr;

public:
	// 默认构造函数
	my_shared_ptr() : _ptr(new T), _useCnt(new size_t(0)) {}

	// 构造函数
	//explicit显示转换声明,implicit隐式转换声明
	explicit my_shared_ptr(T* p) : _ptr(p),  _useCnt(new size_t){
		if (p) {
			*_useCnt = 1;
		} else {
			*_useCnt = 0;
		}
	}

	// 拷贝构造函数
	my_shared_ptr(const my_shared_ptr& rhs) {
		this->_ptr = rhs._ptr; // 指向同一块内存
		this->_useCnt = rhs._useCnt;
		(*this->_useCnt)++; // 引用计数增加	
	}

	// 拷贝赋值函数,注意检查自赋值
	my_shared_ptr& operator= (const my_shared_ptr& rhs) {
		if (this != &rhs) {			// 检查自赋值
			if (_ptr) {				// 防止自身原来指向空指针,_useCnt>0说明确实是指向实体的
				--(*_useCnt);		// 自己要被rhs覆盖了,引用计数减1
				// 如果没有引用计数了,把自己清空,释放动态内存
				if (*_useCnt == 0) {
					delete _useCnt;
					delete _ptr;
				}
				// 把自己变成rhs, 引用计数加一
				_useCnt = rhs._useCnt;
				_ptr = rhs._ptr;
				++(*_useCnt);
			}
		}
		return *this;
	}

	// 得到计数
	int use_count() {
		return *_useCnt;
	}
	~my_shared_ptr() {
		if (!_ptr || (*_useCnt == 1)) { // 只有当前指针指向空或者只有一个指向对象时释放内存
			delete _useCnt;
			delete _ptr;
		} else {  // 否则只减少引用计数
			--(*_useCnt);
		}
	}
};

int main() {

	// 检查构造函数是否正常工作
	my_shared_ptr<int> p1(new int(1));
	cout << "p1 cnt:" << p1.use_count() << endl;

	// 检查拷贝构造是否正常工作
	{
		my_shared_ptr<int> p2(p1);
		cout << "p2 cnt:" << p2.use_count() << endl;
		cout << "p1 cnt:" << p1.use_count() << endl;
	}

	// 检查引用计数是否正常工作
	cout << "p1 cnt:" << p1.use_count() << endl;

	// 检查默认初始化时计数是否正常
	my_shared_ptr<int> p4;
	cout << "p4 cnt:" << p4.use_count() << endl;

	// 检查拷贝赋值是否正常工作
	p4 = p1;
	cout << "p1 cnt:" << p1.use_count() << " p4 cnt:" << p4.use_count() << endl;

	return 0;
}

100. C++对象模型,虚继承

https://blog.youkuaiyun.com/cmdxly/article/details/125488012

101. 普通函数的实现底层

https://blog.youkuaiyun.com/weixin_51431342/article/details/120358794

102. 模板?

https://blog.youkuaiyun.com/cmdxly/article/details/125794425?spm=1001.2014.3001.5501
https://blog.youkuaiyun.com/cmdxly/article/details/125980866?spm=1001.2014.3001.5501
https://blog.youkuaiyun.com/cmdxly/article/details/126295022?spm=1001.2014.3001.5501

103. 面向对象特性?

https://blog.youkuaiyun.com/weixin_44728238/article/details/116173026

104. 讲一下hashMap底层实现和HashSet底层实现

105. 泛型编程

https://blog.youkuaiyun.com/liyazhen2011/article/details/82349890

106. 实现一个不能实例对象的类

#include<iostream>
using namespace std;

//基类-因为纯虚函数,不能实例化对象
class Base
{
public:
	Base()
	{
		cout<<"===Base()==="<<endl;
	}

	//虚析构函数
	virtual int fun() = 0;

	~Base()
	{
		cout<<"===~Base()==="<<endl;
	}
};

//子类
class Son:public Base
{
public:
	Son()
	{
		cout<<"===Son()==="<<endl;
	}

	int  fun()
	{
		cout<<"===fun()==="<<endl;
		return 0;
	}

	~Son()
	{
		cout<<"===~Son()==="<<endl;
	}
};

 void test()
 {
	Son s;
	s.fun();
	Base *b = &s;
	b->fun();
 }

 int main()
 {
	 test();
	 return 0;
 }

107. 智能指针(进阶)

https://blog.youkuaiyun.com/qq_56673429/article/details/124837626

108. 左值,右值引用和move语义(进阶)

https://blog.youkuaiyun.com/fb_941219/article/details/118516925

109. 类型转换方式(进阶)

https://blog.youkuaiyun.com/GreedySnaker/article/details/112614456

110. 线程安全的单例模式(进阶)

https://blog.youkuaiyun.com/qq_34462436/article/details/100888303

111. 内存溢出和内存泄漏(进阶)

https://blog.youkuaiyun.com/weixin_52244492/article/details/124620561

112. C++11新特性(进阶)

113. 静态链接库和动态链接库(进阶)

https://blog.youkuaiyun.com/oqqHuTu12345678/article/details/125083174

114. C++传递参数的形式?

C++中有三种方式来进行参数传递
值传递,地址传递,引用传递
值传递
向函数传递参数的值,即把参数的值复制给函数的形式参数。
这种情况下,修改函数内的形式参数,并不会影响到函数外的实际参数
地址传递
向函数传递参数的指针,即把参数的地址复制给形式参数。
在函数内,该地址用于访问要用到的实际参数,这意味着修改形式参数会影响实际参数
引用传递
形参相当于是实参的“别名”,对形参的操作其实就是对实参的操作,在引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。

115. C++异常底层的实现?

https://blog.youkuaiyun.com/fcsfcsfcs/article/details/120106519

116. const 常量修饰

const 推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时
继承它的优点。
现在它的形式变成了:
const DataType VariableName = VariableValue ;
2) 具体作用
1.const 用于指针的两种情况分析:
  int const *A;  //A可变,*A不可变
  int *const A;  //A不可变,*A可变
 分析:const 是一个左结合的类型修饰符,它与其左侧的类型修饰符和为一个
类型修饰符,所以,int const 限定 *A,不限定A。int const 限定A,不限定A。
2.const 限定函数的传递值参数:
  void Fun(const int Var);
  分析:上述写法限定参数在函数体中不可被改变。
3.const 限定函数的值型返回值:
const int Fun1();
const MyClass Fun2();
  分析:上述写法限定函数的返回值不可被更新,当函数返回内部的类型时(如Fun1),已经是一个数值,当然不可被赋值更新,所以,此时const无意义,最好去掉,以免困惑。当函数返回自定义的类型时(如Fun2),这个类型仍然包含可以被赋值的变量成员,所以,此时有意义。
4. 传递与返回地址: 此种情况最为常见,由地址变量的特点可知,适当使用const,意义昭然。
5. const 限定类的成员函数:
class ClassName {
 public:
  int Fun() const;
 …
}
  注意:采用此种const 后置的形式是一种规定,亦为了不引起混淆。在此函数的声明中和定义中均要使用const,因为const已经成为类型信息的一部分。
获得能力:可以操作常量对象。
失去能力:不能修改类的数据成员,不能在函数中调用其他不是const的函数。

117. 宏(#define)和内联函数(inline)的理解以及区别

宏
缺点:
1.宏没有类型检测,不安全
2.宏是在预处理时进行简单文本替换,并不是简单的参数传递(很难处理一些特定情况。例如:Add(z++))
3.使代码变长
4.宏不能进行调试
5.当预处理搜索#define定义的符号时,字符串常量并不被搜索
优点:
1.加快了代码的运行效率
2.让代码变得更加的通用
内联函数
类中的成员函数是默认的内联函数
内联函数内不准许有循环语句和开关语句
内联函数的定义必须出现在第一次调用内联函数之前

缺点:代码变长,占用更多内存
优点:1.有类型检测,更加的安全
2.内联函数是在程序运行时展开,而且是进行的是参数传递
3.编译器可以检测定义的内联函数是否满足要求,如果不满足就会当作普通函数调用(内联函数不能递归,内联函数不能太大)

对比
相同点:
两者都是可以加快程序运行效率,使代码变得更加通用
不同点:
1.内联函数的调用是传参,宏定义只是简单的文本替换
2.内联函数可以在程序运行时调用,宏定义是在程序编译进行
3.内联函数有类型检测更加的安全,宏定义没有类型检测
4.内联函数在运行时可调式,宏定义不可以
5.内联函数可以访问类的成员变量,宏不可以
6.类中的成员函数是默认的内联函数

C++基础面试问题总结 目录1.面向对象的特征?2.一个C++源文件从文本到可执行文件经历的过程?3.new和malloc的区别?4.虚函数是什么以及其作用?5.虚函数表是什么?6.什么函数不能声明为虚函数?构造函数为什么不能为虚函数?7.纯虚函数是什么?8.虚函数与纯虚函数的区别?9.简单描述虚继承与虚基类?10.简单描述多态?11.C++内存分为哪几块?12.简单介绍内存池?13.简单描述内存泄漏?14.内存中的堆与栈有什么区别?15.说几个C++11的新特性?16.简单介绍智能指针?17.shared_ptr 和 uniqu 阅读详情

相关推荐

IC芯片验证 - 手把手教你搭建UVM验证环境

这是一个UVM的demo项目

howard789的博客 3万+

【c++】变量

存储区 变量的命名 声明变量 C 中的变量定义 变量持续性 变量的连接性 变量的作用域 C 中的左值Lvalues和右值Rvalues 存储区 我们可以把内存分为如下区域(这些区域都是软件模拟出来的,而不是硬件) 1栈:栈(static)特点时先进后出,后进先出,代码块中的定义的变量就是这种类型。先定义的变量先入栈,后定义的变量先出栈 2堆:堆(h

god_wen的博客 825

ILI9488 TFT屏驱动与触摸协同开发指南

TFT-LCD显示模块是嵌入式人机交互系统的核心外设,其工作原理依赖于专用显示控制器(如ILI9488)对GRAM显存的精确读写,并通过SPI等串行总线接收指令与图像数据。理解RGB接口时序、寄存器初始化流程及DC/CS信号控制逻辑,是实现稳定显示的基础技术前提;而四线电阻式触摸功能则需配合XPT2046类ADC控制器,通过独立SPI或模拟时序完成坐标采集。该方案兼顾低功耗、高集成与工程可移植性,广泛应用于工业HMI、仪器仪表及STM32F407等MCU平台的教学与产品开发。本文围绕3.5英寸320×480

weixin_33814090的博客 148

C++的存储持续性(自动、静态、动态),作用域,链接性

1.c++使用三种不同的方案进行数据的存储,z

liuwei271551048的专栏 1905

四足机器人——机械结构

目录 一、四足机器人腿型: 1、并联腿 2、串联腿 3、 腿的布局(关节配置) 二、四足机器人足端设计: 三、四足机器人膝关节驱动: 1、皮带轮驱动: 2、四连杆或者推杆驱动 四、四足机器人机械整体结构设计细节 一、四足机器人腿型: 1、并联腿 优点:受力角度来说,并联腿比串联腿好,并联腿较为灵活。 2、串联腿 优点:运动范围大 3、 腿的布局(关节配置) 为了使机器人具有较好的稳定性,一般会采用比较低的重心。这就导致了机器人腿的髋关节位置需要位于机器人身体的两侧..

m0_58585940的博客 3万+

告别C盘空间焦虑!Miniforge环境路径精准配置全攻略

本文深入解析Miniforge虚拟环境默认占用C盘空间的根本原因,即未正确配置`.condarc`文件中的`envs_dirs`路径优先级。通过详细的诊断步骤与配置命令,指导用户将环境路径精准迁移至指定磁盘(如D盘),并分享禁用自动激活、使用`--prefix`参数等高阶技巧,帮助开发者彻底告别C盘空间焦虑,实现虚拟环境的整洁与可控管理。

weixin_28831399的博客 238

C语言——变量

C变量 变量其实只不过是程序可操作的存储区的名称。C 中每个变量都有特定的类型,类型决定了变量存储的大小和布局,该范围内的值都可以存储在内存中,运算符可应用于变量上。 变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头。大写字母和小写字母是不同的,因为 C 是大小写敏感的。基于前一章讲解的基本类型,有以下几种基本的变量类型: 类型 描述 char 通常是一个字节(八位)。这是一个整数类型。 int 对机器而言,整数的最自然的大小。 float .

qq_38361726的博客 565

Outlook总是提示登录微软,怎么办?

Outlook 2021反复弹出Microsoft登录窗口,可能是由于Modern Authentication身份验证机制或凭据问题导致。解决方案包括:1)通过注册表关闭Modern Authentication(适用于本地Exchange);2)清理Windows凭据管理器中的旧认证信息;3)手动配置Exchange服务器地址;4)通过注册表阻止Microsoft登录窗口弹出(适用于非M365环境)。建议按顺序尝试,尤其前两步通常能解决问题。经测试,步骤1和2已有效解决该问题。

剪刀石头布 4661

静态持续变量

C++为静态存储持续性提供了3种链接性:外部链接(可在其他文件中访问)、内部链接(只能在当前文件中访问)和无链接(只能在当前函数或代码块中访问)。 编译器将分配固定的内存块来存储所有的静态变量,这些静态变量在整个程序执行期间一直存在。如果没有显式的初始化静态变量,编译器将把它设置为0,在默认情况下,静态数组和结构将每个元素或成员的所有位置都设置为0。 (1)外部链接:必须在代码块的外部声明它;

Rosa_zz的博客 1423

HT7533与1117稳压芯片动态特性对比:实测分析与优化策略

本文深入对比了HT7533与1117稳压芯片的动态特性,包括电压过冲和瞬态响应能力,并提供了实测数据与优化策略。HT7533适合低功耗设备,而1117在大电流和稳定性要求高的场景表现更优。文章还分享了PCB布局和电容选择的实用建议,帮助工程师根据项目需求选择合适的稳压芯片。

weixin_28454475的博客 609

操作系统笔记【全-408统考】【附思维导图】

操作系统 思维导图 概述 操作系统的概念 管理计算机软件和硬件资源 最基本的系统软件 特征 并发 区分并发并行 共享 互斥共享方式 同时访问方式 虚拟 逻辑上多个。虚拟处理器的分时,空分复用的虚拟存储器 采用多道程序设计 异步 由于资源有限,进程走走停停 可能会导致进程产生与时间有关的错误。访问顺序 目的和功能 1.管理计算机资源 功能 处理机管理、存储器管理、文件管理、设备管理 目标:安全、有效 2.作为用户与计算机硬件系统

wvdon 2363

Keil5 ARM CC编译错误和警告解释大全(4),序列号3000-3730

Keil5 ARM CC编译错误和警告解释大全(4),序列号3000-3730

Miao8miao的博客 1385

浏览器缓存导致代码不更新?一招解决部署后用户仍看到旧页面的问题

方案效果适用场景文件名哈希永久解决前端工程化项目HTTP缓存头控制精准控制需服务器权限Meta标签部分生效临时补救方案最佳实践:入口HTML禁用缓存,静态资源使用哈希文件名 + 长期缓存,达到「秒级更新」+「高性能」的平衡!

江拥羡橙的博客 809

C++软件开发常见面试题【涵盖C++基础、操作系统、网络、数据结构,计算机组成原理等总字数约7w字】

由本人整理的非常详细的C++开发面经

weixin_65589140的博客 2152

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

嵌入式面试题 C/C++ 链表面试题总结

创建2个链表,对两个链表对应位进行相加。

weixin_49303682的博客 683

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

C++面试题:循环数列问题

21     22     23     24     25     … 20     7       8       9       10 19     6       1       2       11 18     5       4       3       12 17     16     15     14     13 看清以上数字排列的规律,设1点的坐标是(0, 0)

SHIroh的专栏 1357

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

面试宝典-面试题1

一、题意:对赋值操作符进行重定义,使其可以进行类对象的赋值 二、代码: 1 #include<cstring> 2 #include<cstdio> 3 #include<iostream> 4 using namespace std; 5 6 class CMyString 7 { 8 public:...

weixin_33743880的博客 92

面试题3:二维数组中的查找

  剑指offer中面试题3,在二维数组中的查找。   题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断,数组中是否含有该整数。 例如: 1   2 8 9 2 4 9 12 4 7 10 13 6 8 11 15 ...

weixin_33806914的博客 90

程序面试题——C实现

平台:win10 x64 +VC6.0 2019/5/22 1.合并三个有序的链表链表节点定义struct node{ int val; struct node* next;};struct node* merge_3 (形参由你定义){ //这部分是实现}当输入的有序链表是多个的时候,请给出合并算法,并假设链表个数为m,平均长度为n,请分析时间复杂度 思路:参看 http...

weixin_30347009的博客 111

面试题4:字符串

解法1:从前往后扫描,碰到空格就替换,空格后面的元素向后移2。显然这种方式中有很多冗余的移动操作,其复杂度为O(n2) 解法2:先遍历一遍获得空格的总个数。 1 #include<iostream> 2 3 using std::cout; 4 using std::cin; 5 using std::endl; ...

weixin_30593443的博客 81

面试题 -二元查找树转变成排序的双向链表

1 // Tree.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include <malloc.h> 6 #include <iostream> 7 using namespace std; 8 9 template<cl...

weixin_34352449的博客 74

拷贝构造和赋值构造

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38...

weixin_52995261的博客 1033

面试题12:打印1到最大的n位数

题目:输入数字n,按顺序打印出从1最大的n位十进制数。例如输入3,则打印出1,2,3,....,一直到最大的3位数即999 陷阱:考虑大数问题,就是输入的数字非常大的情况,如100,怎么表示100位的数呢。用字符串保存 细节问题 1,字符串递增的溢出判断 2,打印时过滤0 源代码 #include "stdio.h" #include "stdlib.h" #include "st

lskyne的专栏 2072

面试题3:自己实现单链表

1 #include <cassert> 2 #include <iostream> 3 4 using namespace std; 5 6 struct SingleListNode { 7 int val; 8 SingleListNode *next; 9 SingleLi...

weixin_30502965的博客 66

输入一串中文字符并打印最频繁出现的文字。

1 #include<iostream> 2 #include<string> 3 #include<cstring> 4 #include<list> 5 #include<iomanip> 6 using namespace std; 7 struct cell //结构单体 8 { ...

weixin_30364147的博客 157
上一篇: c++面试题目汇总-1-57
下一篇: C++笔记-针对从0到1学习VIO中代码中的遗忘知识点
xiaoliyu00
博客等级 码龄9年 4180粉丝 122原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值