07 2023 档案
摘要:# 122.lambda表达式 ## 1.Lambda表达式概述 Lambda表达式是现代C++在C++11和更高版本中的一个新的语法糖,在C++11、C++14、C++17和C++20中Lambda表达的内容还在不断更新。lambda表达式(也称为lambda函数)是在调用或作为函数参数传递的位置
阅读全文
摘要:# 121.仿函数 ## 1.为什么要有仿函数 我们先从一个非常简单的问题入手,来了解为什么要有仿函数。 假设我们现在有一个数组,数组中存有任意数量的数字,我们希望能够统计出这个数组中大于 10 的数字的数量,你的代码很可能是这样的: ```C++ #include using namespace
阅读全文
摘要:# 120.C++谓词 ## 1.定义 C++中的谓词:返回值为bool类型的仿函数; 一元谓词:operator() 函数接收一个参数; 二元谓词:operator() 函数接收两个参数。 **补充**:**函数对象** 重载函数调用操作符的类,其对象常称为函数对象。 函数对象使用重载的小括号时,
阅读全文
摘要:# 119.C++中的heap ## 1.简介 要想真正了解堆,就需要先了解[二叉树](树和二叉树(Tree&Binary Tree))。 堆是所有树中最具有特点的树,因为它是用数组存储的,并且总是完全二叉树。 如果有一个关键码的集合K = {k~0~,k~1~, k~2~,…,k~n-1~}把它的
阅读全文
摘要:# 118.C++ 中的stack ## 1.stack的概念 ==先进后出的线性表。== 栈是一个STL中的容器适配器,在std命名空间中,它限制插入和删除都在一个位置上(栈顶上),底层是deque(双端队列)。 要使用stack,需要添加头文件 ```C++ #include ``` **栈顶:
阅读全文
摘要:# 117.STL中的multiset ## 1.multiset的介绍 > 1.multiset是按照特定顺序存储元素的容器,其中元素是可以重复的 > 2.在multiset在,元素的value也会识别它组成的键值对,multiset元素的值不能在容器中进行修改,但可以插入和删除 > 3.在内部,
阅读全文
摘要:# 116.STL中的set ## 1.set的简介 set的中文译为集合,知名见其意,因此set容器也就具有集合的属性啦!而集合这个概念大家应该上数学课应该都是学过的哈,集合它具有确定性、互异性、无序性。当然我们这里重点记住它的互异性就OK了,那么什么是互异性呢?就是说一个集合里边是不会出现两个甚
阅读全文
摘要:# 115.STL中的multimap ## 1.multimap的基本性质 multimap容器是和map容器相似的关联式容器,所谓“相似”,是指multimap容器具有和map容器相同的特性,即multimap容器也存储pair类型的键值对(其中K表示键的类型,T表示值的类型),其中各个键值对的
阅读全文
摘要:# 114.STL中的map ## 1.map的简介 map是C++STL中的一个关联式容器,它提供一对一的hash,它类似于Python中的字典,也有着键值对(Key-Value)这一说。我们可以通过键(Key)来找到值(Value),但需要注意的是,每个键(Key)只能在map中出现一次哦! m
阅读全文
摘要:# 113.STL中的pair ## 1.pair的简介 pair是C++STL(标准模板库)中的一个现有容器,它将2个数据整合成一组数据,当我们类似需求的时候就可以使用到pair啦!pair其实有点像Python中字典中的键值对(Key-Value),一个Key对应着一个Value。pair的本质
阅读全文
摘要:# 112.STL中的array ## 1.array介绍 > 在C++标准库中,array是固定大小的序列容器,array中包含特定个数并且严格按照线性序列排序的元素。因此array允许对元素进行随机访问,指向某一元素的指针可以通过偏移访问其他元素。在array内部,它只保存自己包含的元素,其他任
阅读全文
摘要:# 111.C++队列queue和deque ## 1.queue ### 1.1queue的简介 queue的中文译为队列,队列是一种数据结构。C语言中队列的定义及初始化以及一些相关操作实现起来较为繁琐,而C++的queue让这些都变得简便易实现。因为C++中有着许多关于queue的方法函数。 队
阅读全文
摘要:# 110.STL中的list ## 1.list的介绍 1.list是序列容器,允许在序列中的任何位置执行固定O(1)时间复杂度的插入和删除操作,并在两个方向进行迭代。 2.list容器使用双链表实现;双链表将每个元素存储在不同的位置,每个节点通过next,prev指针链接成顺序表。 3.list
阅读全文
摘要:# 109.C++类内初始化 C++11规定,可以为数据成员提供一个类内初始值。创建对象时,类内初始值用于初始化数据成员。像下面这样,cursor和height的类内初始值均为0。 ```C++ class Screen { private: int cursor = 0; int height =
阅读全文
摘要:# 108.类型别名声明 在代码编辑过程中,为了书写省事或者更容易理解,通常会自定义别名,包括类型别名、方法别名等。在 C++ 中定义别名有以下几种方式。 ## 1.#define ### 1.1概述 \#define 是宏定义,作用就是将一个标识符定义为一个字符串,源程序中所有的该标识符均以指定的
阅读全文
摘要:# 107.继承总结 ## 1. 概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称子类或者派生类,被继承的类称为父类或基类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知
阅读全文
摘要:# 106.C++中NULL和nullptr区别 ## 1.NULL是什么 在[《NULL,0,'\0',"0","\0"的区别》](http://mp.weixin.qq.com/s?__biz=MzI2OTA3NTk3Ng==&mid=2649284887&idx=1&sn=e97526b0e2
阅读全文
摘要:# 105.C++初始化 > C++中变量的初始化有很多种方式,如:**默认初始化**,**值初始化**,**直接初始化**,**拷贝初始化**,**列表初始化**。 ## 1.默认初始化 默认初始化是指定义变量时 没有指定初值时 进行的初始化操作。 默认初始化变量的值与变量的类型与变量定义的位置有
阅读全文
摘要:# 104.字符串函数:strlen函数,strcpy函数,strcat函数,strcmp函数 ## 1.字符串函数strlen ### (1)strlen函数 strlen函数返回的是在字符串中’\0’前面出现的字符的个数 ### (2)strlen的使用 #### a.代码 ```C++ #in
阅读全文
摘要:# 119.模板会写吗?写一个比较大小的模板函数 本程序适合char、int、float类型数据进行比较,差距小于0.01视为相等 ```C++ #include #include using namespace std; //本程序适合char、int、float类型数据进行比较,差距小于0.01
阅读全文
摘要:# 118.main函数的返回值有什么值得考究之处吗? main函数的返回值用于说明程序的退出状态。如果返回0,则代表程序正常退出。返回其它数字的含义则由系统决定。通常,返回非零代表程序异常退出。 ## 1.void main() 有一些书上的,都使用了void main( ) ,其实这是错误的。C
阅读全文
摘要:# 117.你知道Debug和Release的区别是什么吗? 1.调试版本(Debug),包含调试信息,所以容量比Release大很多,并且不进行任何优化(优化会使调试复杂化,因为源代码和生成的指令间关系会更复杂),便于程序员调试。Debug模式下生成两个文件,除了.exe或.dll文件外,还有一个
阅读全文
摘要:# 116.如何禁止程序自动生成拷贝构造函数? ##### 1.为了阻止编译器默认生成拷贝构造函数和拷贝赋值函数,我们需要手动去重写这两个函数,某些情况下,为了避免调用拷贝构造函数和拷贝赋值函数,我们需要将他们设置成private,防止被调用。 ###### 1.1手动重写这两个函数 在C++中
阅读全文
摘要:# 115.如何阻止一个类被实例化?有哪些方法? 1.将类定义为抽象基类或者将构造函数声明为private; 将类定义为抽象类:抽象类是不能被实例化的,只能被继承。通过将类定义为抽象类,可以防止该类被实例化。 ```C++ class AbstractClass { public: virtual
阅读全文
摘要:# 114.你知道数组和指针的区别吗? 1.数组在内存中是连续存放的,开辟一块连续的内存空间;数组所占存储空间:sizeof(数组名);数组大小:sizeof(数组名)/sizeof(数组元素数据类型); 2.用运算符sizeof 可以计算出数组的容量(字节数)。sizeof(p),p 为指针得到的
阅读全文
摘要:# 113.将引用作为函数参数有哪些好处? 1.传递引用给函数与传递指针的效果是一样的。 这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。 2.使用引用传递函数的参数,在内存中并没有产生实参的副本
阅读全文
摘要:# 112.说一说strcpy、sprintf与memcpy这三个函数的不同之处 1.复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。 2.复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出
阅读全文
摘要:# 111.在进行函数参数以及返回值传递时,可以使用引用或者值传递,其中使用引用的好处有哪些? 对比值传递,引用传参的好处: 1)在函数内部可以对此参数进行修改 2)提高函数调用和运行的效率(因为没有了传值和生成副本的时间和空间消耗) 如果函数的参数实质就是形参,不过这个形参的作用域只是在函数体内部
阅读全文
摘要:# 110.成员初始化列表会在什么时候用到?它的调用过程是什么? 1.当初始化一个引用成员变量时; ```C++ struct MyClass { const int mya; int& myb; MyClass(int a, int& b) :mya(a), myb(b) {} ~MyClass(
阅读全文
摘要:# 109.怎么快速定位错误出现的地方? 1.如果是简单的错误,可以直接双击错误列表里的错误项或者生成输出的错误信息中带行号的地方就可以让编辑窗口定位到错误的位置上。 2.对于复杂的模板错误,最好使用生成输出窗口。 多数情况下出发错误的位置是最靠后的引用位置。如果这样确定不了错误,就需要先把自己写的
阅读全文
摘要:# 108.如何设计一个计算仅单个子类的对象个数? 1.为类设计一个static静态变量count作为计数器; 2.类定义结束后初始化count; 3.在构造函数中对count进行+1; 4.设计拷贝构造函数,在进行拷贝构造函数中进行count +1,操作; 5.设计赋值构造函数,在进行赋值函数中对
阅读全文
摘要:# 107.你知道静态绑定和动态绑定吗?讲讲? 1.对象的静态类型:对象在声明时采用的类型。是在编译期确定的。 2.对象的动态类型:目前所指对象的类型。是在运行期决定的。对象的动态类型可以更改,但是静态类型无法更改。 3.静态绑定:绑定的是对象的静态类型,某特性(比如函数依赖于对象的静态类型,发生在
阅读全文
摘要:# 106.你什么情况用指针当参数,什么时候用引用,为什么? ## 1.使用引用参数的主要原因有两个 1.程序员能修改调用函数中的数据对象 2.通过传递引用而不是整个数据–对象,可以提高程序的运行速度 ## 2.一般的原则 1.对于使用引用的值而不做修改的函数: (1)如果数据对象很小,如内置数据类
阅读全文
摘要:# 105.你知道const char* 与string之间的关系是什么吗? 1.string 是C++标准库里面其中一个,封装了对字符串的操作,实际操作过程我们可以用const char*给string类初始化 2.三者的转化关系如下所示: ```C++ a) string转const char*
阅读全文
摘要:# 104.C++中标准库是什么? ## 1.C++ 标准库可以分为两部分: 1.1标准函数库: 这个库是由通用的、独立的、不属于任何类的函数组成的。函数库继承自 C 语言。 输入/输出 I/O、字符串和字符处理、数学、时间、日期和本地化、动态分配、其他、宽字符函数 ``` * 输入输出流:`` 头
阅读全文
摘要:# 103.如果有一个空类,它会默认添加哪些函数? ```C++ 1) Empty(); // 缺省构造函数// 2) Empty( const Empty& ); // 拷贝构造函数// 3) ~Empty(); // 析构函数// 4) Empty& operator=( const Empty
阅读全文
摘要:# 102.volatile关键字的作用? volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。声明时语法:int vo
阅读全文
摘要:# 101.程序在执行int main(int argc, char *argv[])时的内存结构,你了解吗? 参数的含义是程序在命令行下运行的时候,需要输入argc 个参数,每个参数是以char 类型输入的,依次存在数组里面,数组是 argv[],所有的参数在指针char * 指向的内存中,数组的
阅读全文
摘要:# 100.你知道strcpy和memcpy的区别是什么吗? 1.复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。 2.复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根
阅读全文
摘要:# 99.如何在不使用额外空间的情况下,交换两个数?你有几种方法 ```C++ 1) 算术 x = x + y; y = x - y; x = x - y; 2) 异或 x = x^y;// 只能对int,char.. y = x^y; x = x^y; x ^= y ^= x; ``` 参考资料来
阅读全文
摘要:# 98.C++如何处理多个异常的? 1. C++中的异常情况: 语法错误(编译错误):比如变量未定义、括号不匹配、关键字拼写错误等等编译器在编译时能发现的错误,这类错误可以及时被编译器发现,而且可以及时知道出错的位置及原因,方便改正。 运行时错误:比如数组下标越界、系统内存不足等等。这类错误不易被
阅读全文
摘要:# 97.隐式转换,如何消除隐式转换? 1.C++的基本类型中并非完全的对立,部分数据类型之间是可以进行隐式转换的。所谓隐式转换,是指不需要用户干预,编译器私下进行的类型转换行为。很多时候用户可能都不知道进行了哪些转换 2.C++面向对象的多态特性,就是通过父类的类型实现对子类的封装。通过隐式转换,
阅读全文
摘要:# 96.说一下你理解的 ifdef endif代表着什么? 1.一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”。有时,希望当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。 2.
阅读全文
摘要:# 95.静态成员与普通成员的区别是什么? 1.生命周期 静态成员变量从类被加载开始到类被卸载,一直存在; 普通成员变量只有在类创建对象后才开始存在,对象结束,它的生命期结束; 2.共享方式 静态成员变量是全类共享;普通成员变量是每个对象单独享用的; 3.定义位置 普通成员变量存储在栈或堆中,而静态
阅读全文
摘要:# 94.全局变量和static变量的区别 C++变量根据定义的位置的不同的生命周期,具有不同的作用域,作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名空间作用域和文件作用域。 全局变量和局部变量主要在作用域、定义位置、内存存储方式、生命期以及使用方式上存在明显的区别。 1.作用
阅读全文
摘要:# 93.定义和声明的区别 **如果是指变量的声明和定义:** 从编译原理上来说,声明是仅仅告诉编译器,有个某类型的变量会被使用,但是编译器并不会为它分配任何内存。而定义就是分配了内存。 **如果是指函数的声明和定义:** 声明:一般在头文件里,对编译器说:这里有一个函数叫function() 让编
阅读全文
摘要:# 92.当程序中有函数重载时,函数的匹配原则和顺序是什么? 多数情况下,我们可以很容易的判断出该会调用哪一个重载函数,例如,调用的重载函数之间形参数量不同,形参的类型有明显的区别等。但是,当几个重载函数形参数量相等、具有默认形参以及形参又可以发生类型转换时,判断会调用哪个重载函数就显得不那么明了。
阅读全文
摘要:# 91.你知道重载运算符吗? 1.我们只能重载已有的运算符,而无权发明新的运算符;对于一个重载的运算符,其优先级和结合律与内置类型一致才可以;不能改变运算符操作数个数; 2.两种重载方式:成员运算符和非成员运算符,成员运算符比非成员运算符少一个参数;下标运算符、箭头运算符必须是成员运算符; 3.引
阅读全文
摘要:# 90.cout和printf有什么区别? `cout` 和 `printf` 是 C++ 和 C语言中用于输出信息的函数,它们有以下区别: 1. 语法和用法: - `cout` 是 C++ 中的输出流对象,可以使用流操作符 `和basic_ostream。实现了char,wchar_t具体化;i
阅读全文
摘要:# 89.C++中类成员的访问权限和继承权限问题 - public的变量和函数在类的内部外部都可以访问。 - protected的变量和函数只能在类的内部和其派生类中访问。 - private修饰的元素只能在类内访问 派生类可以继承基类中除了构造/析构、赋值运算符重载函数之外的成员,这些成员的访问属
阅读全文
摘要:# 88.为什么模板类一般都是放在一个h文件中 1.模板定义很特殊。由template处理的任何东西都意味着编译器在当时不为它分配存储空间,它一直处于等待状态直到被一个模板实例告知。在编译器和连接器的某一处,有一机制能去掉指定模板的多重定义。 所以为了容易使用,几乎总是在头文件中放置全部的模板声明和
阅读全文
摘要:# 87.你知道printf函数的实现原理是什么吗? printf是[格式化输出](https://so.csdn.net/so/search?q=格式化输出&spm=1001.2101.3001.7020)可以自己定义输出的格式;printf(“%d\n”,a),其中" "之间的是格式说明串。%
阅读全文
摘要:# 86.define、const、typedef、inline的使用方法?他们之间有什么区别? 一、const与#define的区别: 1. const定义的常量是变量带类型,而#define定义的只是个常数不带类型; 2. define只在预处理阶段起作用,简单的文本替换,而const在编译、链
阅读全文
摘要:# 85.函数调用过程栈的变化,返回值和参数变量哪个先入栈? 1.将函数的参数压入栈中。参数的压入顺序与调用约定有关,可以是从右到左,也可以是从左到右。而在大多数C/C++编译器中,在函数调用的过程中,函数的参数是 ***\*由右向左\****入栈的; 2.将当前函数的返回地址压入栈中。返回地址是指
阅读全文
摘要:# 84.结构体变量比较是否相等 ## 1.重载了 “==” 操作符 ```C++ #include using namespace std; struct foo { int a; int b; foo(int a, int b) { this->a = a; this->b = b; } //
阅读全文
摘要:# 83.说一说你理解的内存对齐以及原因 ## 1.什么是内存对齐?? 内存对齐可以提高CPU的内存访问效率,因为CPU在读取内存时是按照一块一块的方式进行读取,每块的大小由内存读取粒度确定,通常为2、4、8或16个字节。 1.硬件存储和读取 一个内存是由若干个黑色的内存颗粒构成的。每一个内存颗粒叫
阅读全文
摘要:# 82.函数指针? 函数指针指向的是函数而非对象。和其他指针一样,函数指针指向某种特定类型。函数的类型由它的返回类型和形参类型共同决定,与函数名无关。例如: ```C++ //比较两个string对象的长度 bool lengthCompare(const string&, const strin
阅读全文
摘要:# 81.知道C++中的组合吗?它与继承相比有什么优缺点吗? ## 1.继承 继承是Is a 的关系,比如说Student继承Person,则说明Student is a Person。继承的优点是子类可以重写父类的方法来方便地实现对父类的扩展。 继承的缺点有以下几点: ①父类的内部细节对子类是可见
阅读全文
摘要:# 80.继承机制中对象之间如何转换?指针和引用之间如何转换? ## 1.向上类型转换 将派生类指针或引用转换为基类的指针或引用被称为向上类型转换,向上类型转换会自动进行,而且向上类型转换是安全的。 ## 2.向下类型转换 将基类指针或引用转换为派生类指针或引用被称为向下类型转换,向下类型转换不会自
阅读全文
摘要:# 79.如果想将某个类用作基类,为什么该类必须定义而非声明? 派生类中包含并且可以使用它从基类继承而来的成员,为了使用这些成员,派生类必须知道他们是什么。 所以必须定义而非声明。 参考资料来源: 阿秀
阅读全文
摘要:# 78.类如何实现只能静态分配和只能动态分配 1.前者是把new、delete运算符重载为private属性。后者是把构造、析构函数设为protected属性,再用子类来动态创建 2.建立类的对象有两种方式: ① 静态建立,例如 A a; 静态建立一个类对象,就是由编译器为对象在栈空间中分配内存。
阅读全文
摘要:# 77.C++中的指针参数传递和引用参数传递有什么区别?底层原理你知道吗? 1.指针参数传递本质上是值传递,它所传递的是一个地址值。 值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,会在栈中开辟内存空间以存放由主调函数传递进来的实参值,从而形成了实参的一个副本(替身)。 值传递的特点是
阅读全文
摘要:# 76.方法调用的原理(栈,汇编) 1.机器用栈来传递过程参数、存储返回信息、保存寄存器用于以后恢复,以及本地存储。而为单个过程分配的那部分栈称为帧栈;帧栈可以认为是程序栈的一段,它有两个端点,一个标识起始地址,一个标识着结束地址,两个指针结束地址指针esp,开始地址指针ebp; 2.由一系列栈帧
阅读全文
摘要:# 75.怎样判断两个浮点数是否相等? 对两个浮点数判断大小和是否相等不能直接用==来判断,会出错!明明相等的两个数比较反而是不相等!对于两个浮点数比较只能通过相减并与预先设定的精度比较,记得要取绝对值!浮点数与0的比较也应该注意。与浮点数的表示方式有关。 参考资料来源: 阿秀
阅读全文
摘要:# 74.指针加减计算要注意什么? 指针加减本质是对其所指地址的移动,移动的步长跟指针的类型是有关系的,因此在涉及到指针加减运算需要十分小心,加多或者减多都会导致指针指向一块未知的内存地址,如果再进行操作就会很危险。 举个例子: ```C++ #include using namespace std
阅读全文
摘要:# 73.全局变量和局部变量有什么区别? C++变量根据定义的位置的不同的生命周期,具有不同的作用域,作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名空间作用域和文件作用域。 全局变量和局部变量主要在作用域、定义位置、内存存储方式、生命期以及使用方式上存在明显的区别。 1.作用域
阅读全文
摘要:# 72.引用是否能实现动态绑定,为什么可以实现? 可以。 引用在创建的时候必须初始化,在访问虚函数时,编译器会根据其所绑定的对象类型决定要调用哪个函数。注意只能调用虚函数。 举个例子: #include using namespace std; class Base { public: virtu
阅读全文
摘要:# 71.静态类型和动态类型,静态绑定和动态绑定的介绍 在C++中,变量的类型可以分为静态类型和动态类型两种。 ## 1.类型 **静态类型**:静态类型是指在程序运行时分配的类型,它们的大小和数据结构在程序运行时就已经确定了,因此可以直接使用int、float等基本数据类型或者自定义数据类型。静态
阅读全文
摘要:# 70.如何获得结构成员相对于结构开头的字节偏移量 使用头文件中的,offsetof宏。 举个例子: ```C++ #include #include using namespace std; struct S { int x; char y; int z; double a; }; int ma
阅读全文
摘要:# 69.C++中将临时变量作为返回值时的处理过程 1.函数返回值的存储位置: - 在C语言中,函数返回值通常会被**存储在寄存器中**(如ax、eax等),而不是堆栈中。这样设计的目的是为了提高执行效率,避免频繁的堆栈操作。 - 在函数调用结束后,返回值**仍然保留在寄存器中**,并且在函数退出时
阅读全文
摘要:# 68.说说移动构造函数 1.我们用对象a初始化对象b,后对象a我们就不再使用了,但是对象a的空间还在呀(在析构之前),既然拷贝构造函数实际上就是把a对象的内容复制一份到b中,那么为什么我们不能直接使用a的空间呢?这样就避免了新的空间的分配,大大降低了构造的成本。这就是移动构造函数设计的初衷; 2
阅读全文
摘要:# 67.写C++代码时有一类错误是 coredump ,很常见,你遇到过吗?怎么调试这个错误? coredump是程序由于异常或者bug在运行时异常退出或者终止,在一定的条件下生成的一个叫做core的文件,这个core文件会记录程序在运行时的内存,寄存器状态,内存指针和函数堆栈信息等等。对这个文件
阅读全文
摘要:# 66.C++函数调用的压栈过程 ## 1.以例子进行讲解 从代码入手,解释这个过程: ```C++ #include using namespace std; int f(int n) { cout << n << endl; return n; } void func(int param1,
阅读全文
摘要:# 65.C++的四种强制转换 ## 1.C语言中的类型转换 ``` C语言和C++都是强类型语言,如果赋值运算符左右两侧变量的类型不同,或形参与实参的类型不匹配,或返回值类型与接收返回值的变量类型不一致,那么就需要进行类型转换。 ``` C语言中有两种形式的类型转换,分别是隐式类型转换和显式类型转
阅读全文
摘要:# 64.成员初始化列表的概念,为什么用它会快一些? ## 1.成员初始化列表的概念 在类的构造函数中,不在函数体内对成员变量赋值,而是在构造函数的花括号前面使用冒号和初始化列表赋值 ## 2.效率 用初始化列表会快一些的原因是,对于类型,它少了一次调用构造函数的过程,而在函数体中赋值则会多一次调用
阅读全文
摘要:# 63.介绍面向对象的三大特性,并且举例说明 三大特性:继承、封装和多态 ## 1.封装 C++中的封装是指将属性和方法包装在一个类中,并通过访问控制符来限制外部对类的访问。封装可以提高代码的可维护性和安全性,同时也可以实现多态性。 在C++中,封装可以通过以下方式实现: 1.使用访问控制符:C+
阅读全文
摘要:# 62.对象复用的了解,零拷贝的了解 ## 1.对象复用 对象复用是指将已经创建的对象进行重复使用,而不是创建新的对象。在面向对象编程中,对象复用可以通过以下几种方式实现: 1.对象池:对象池是一种常见的对象复用方式,它可以将已经创建的对象保存起来,并在需要时将其重新使用。 2.模板类和模板对象:
阅读全文
摘要:# 61.什么是内存泄露,如何检测与避免 内存泄漏是指在程序运行过程中,一部分程序申请的内存空间由于没有及时释放,导致系统中存在大量的已分配但无法使用的内存空间,最终会耗尽可用内存资源,导致程序崩溃或者运行缓慢。 ## 1.内存泄漏的主要原因包括: 1.忘记释放内存:程序员在使用完已分配的内存后,没
阅读全文
摘要:# 60.C++中新增了string,它与C语言中的 char *有什么区别吗?它是如何实现的? 1.实现方式:string是一种抽象类,它的实现由std::string和char *转换而来。 在实现上,`std::string` 内部通常会使用动态数组来存储字符串,可以动态地分配内存。同时,`s
阅读全文
摘要:# 59.有哪些情况必须用到成员列表初始化?作用是什么? ## 1.必须使用成员初始化的四种情况 ① 当初始化一个引用成员时; ```C++ struct MyClass { const int mya; int& myb; MyClass(int a, int& b) :mya(a), myb(b
阅读全文
摘要:# 58.类成员初始化方式?构造函数的执行顺序 ?为什么用成员初始化列表会快一些? ## 1.类成员初始化方式 ### 1.1初始化方式一:默认时初始化 如果类成员没有被显式初始化,将会使用默认初始化。默认初始化指没有提供初始化式的情况下,将使用默认值进行初始化。对于基本数据类型(如整数、浮点数等)
阅读全文
摘要:# 57.malloc、realloc、calloc的区别 malloc、realloc和calloc是C语言中的内存分配函数,它们有以下区别: 1.内存来源:malloc和realloc分配的内存空间位于堆中,而calloc在分配内存空间后会将其每一位都初始化为零,它也被称为“零初始化内存分配器”
阅读全文
摘要:# 56.malloc与free的实现原理? 1.在标准C库中,提供了malloc/free函数分配释放内存,这两个函数底层是由brk、mmap、,munmap这些系统调用实现的; 2.brk是将数据段(.data)的最高地址指针_edata往高地址推,mmap是在进程的虚拟地址空间中(堆和栈中间,
阅读全文
摘要:# 55.malloc申请的存储空间能用delete释放吗? 不能,malloc /free主要为了兼容C,new和delete 完全可以取代malloc /free的。 malloc /free的操作对象都是必须明确大小的,而且不能用在动态类上。 new 和delete会自动进行类型检查和大小,m
阅读全文
摘要:# 54.new和delete的实现原理,delete是如何知道释放内存的大小的? 1、 new简单类型直接调用operator new分配内存; 而对于复杂结构,先调用operator new分配内存,然后在分配的内存上调用构造函数; 对于简单类型,new[]计算好大小后调用operator ne
阅读全文
摘要:# 1.重载new和delete 尽管我们说能够 “重载new和delete",但是实际上重载这两个运算符与重载其他运算符的过程大不相同。要想真正掌握重载new和delete的方法,首先要对new表达式和delete表达式的工作机理有更多了解。 当我们使用一条new表达式时: ```C++ // n
阅读全文
摘要:==☀警告== ``` volatile的确切含义与机器有关,只能通过阅读编译器文档来理解。要想让使用了volatile的程序在移植到新机器或新编译器后仍然有效,通常需要对该程序进行某些改变。 ``` 直接处理硬件的程序常常包含这样的数据元素,它们的值由程序直接控制之外的过程控制。例如,程序可能包含
阅读全文
摘要:在C++中,final是一个关键字,用于修饰类的成员变量和成员函数。 1.final修饰成员变量:当一个类中的成员变量被声明为final时,它就变成了常量,即它的值不能再被修改。final修饰的成员变量必须在类定义中进行初始化,且只能初始化一次。 假设我们有一个名为Person的类,其中包含一个成员
阅读全文
摘要:# 53.delete p、delete [] p、allocator都有什么作用? 1、 动态数组管理new一个数组时,[]中必须是一个整数,但是不一定是常量整数,普通数组必须是一个常量整数; `delete p`是用于释放由`new`运算符分配的单个对象的内存。如果使用`new[]`运算符创建了
阅读全文
摘要:# 51.深拷贝与浅拷可以描述一下吗? ## 1.浅拷贝 同一类型的对象之间可以赋值,使得两个对象的成员变量的值相同,两个对象仍然是独立的两个对象,这种情况被称为**浅拷贝。** 浅拷贝和深拷贝之间的区别:浅拷贝是指将对象中的数值类型的字段拷贝到新的对象中,而对象中的引用型字段则指复制它的一个引用到
阅读全文
摘要:# 52.new和malloc的区别 **相同点** ●都可用于内存的动态申请和释放 ●new和malloc都可以分配指定大小的内存块,并且分配的内存都在堆上。 ●new和malloc的结果都返回一个指向已分配内存的指针。 ●都允许使用字面量作为参数来分配内存。 **不同点** ●前者是C++运算符
阅读全文
摘要:# 50.从汇编层去解释一下引用 ``` 9: int x = 1; 00401048 mov dword ptr [ebp-4],1 10: int &b = x; 0040104F lea eax,[ebp-4] 00401052 mov dword ptr [ebp-8],eax ``` x的
阅读全文
摘要:# 47.静态变量什么时候初始化? 1.初始化只有一次,但是可以多次赋值,在主程序之前,编译器已经为其分配好了内存。 2.静态局部变量和全局变量一样,数据都存放在全局区域,所以在主程序之前,编译器已经为其分配好了内存,但在C和C++中静态局部变量的初始化节点又有点不太一样。在C中,初始化发生在代码执
阅读全文
摘要:# 48.const关键字的作用有哪些? 编写程序过程中,我们有时不希望改变某个变量的值。此时就可以使用关键字 **const** 对变量的类型加以限定。 ***初始化和const*** 因为const对象一旦创建后其值就不能再改变,所以const对象必须初始化。一如既往,初始值可以是任意复杂的表达
阅读全文
摘要:# 49.什么是类的继承? ## 1.类与类之间的关系 has-A包含关系,用以描述一个类由多个部件类构成,实现has-A关系用类的成员属性表示,即一个类的成员属性是另一个已经定义好的类; use-A,一个类使用另一个类,通过类之间的成员函数相互联系,定义友元或者通过传递参数的方式来实现; is-A
阅读全文
摘要:# 45.形参与实参的区别? 1.形参变量只有在被调用时才分配内存单元,在调用结束时, 即刻释放所分配的内存单元。因此,形参只有在函数内部有效。 函数调用结束返回主调函数后则不能再使用该形参变量。 2.实参可以是常量、变量、表达式、函数等, 无论实参是何种类型的量,在进行函数调用时,它们都必须具有确
阅读全文
摘要:# 46.值传递、指针传递、引用传递的区别和效率 1.值传递:有一个实参向函数所属的栈拷贝数据的过程,如果值传递的对象是类对象或是大的结构体对象,将耗费一定的时间和空间。(传值) 2.指针传递:同样有一个实参向函数所属的栈拷贝数据的过程,但拷贝的数据是一个固定为4字节(32位操作系统)的地址。(传值
阅读全文
摘要:# 43.static的用法和作用? 在C++中,`static`关键字有多种用法,可以用于声明静态成员变量、静态成员函数、静态局部变量和静态全局变量。下面是它们的作用和特点: ## 1.静态成员变量 ●在类内声明,类外进行定义和初始化(const修饰的静态成员变量最好在类内初始化) ```C++
阅读全文
摘要:# 44.C++中的const 编写程序过程中,我们有时不希望改变某个变量的值。此时就可以使用关键字 **const** 对变量的类型加以限定。 ***初始化和const*** 因为const对象一旦创建后其值就不能再改变,所以const对象必须初始化。一如既往,初始值可以是任意复杂的表达式: ``
阅读全文
摘要:# 42.C++的异常处理的方法 在程序执行过程中,由于程序员的疏忽或是系统资源紧张等因素都有可能导致异常,任何程序都无法保证绝对的稳定,常见的异常有: - 数组下标越界 - 除法计算时除数为0 - 动态分配空间时空间不足 - ... 如果不及时对这些异常进行处理,程序多数情况下都会崩溃。 ## 1
阅读全文
摘要:# 41.C++中有几种类型的new 在C++中,new有三种典型的使用方法:plain new,nothrow new和placement new (1)**plain new** 言下之意就是普通的new,就是我们常用的new,在C++中定义如下: ```C++ void* operator n
阅读全文
摘要:# 39.volatile、mutable和explicit关键字的用法 ## 1.**volatile** ==☀警告== ``` volatile的确切含义与机器有关,只能通过阅读编译器文档来理解。要想让使用了volatile的程序在移植到新机器或新编译器后仍然有效,通常需要对该程序进行某些改变
阅读全文
摘要:# 40.什么情况下会调用拷贝构造函数 - 用类的一个实例化对象去初始化另一个对象的时候 - 函数的参数是类的对象时(非引用传递) - 函数的返回值是函数体内局部对象的类的对象时 ,此时虽然发生(Named return Value优化)NRV优化,但是由于返回方式是值传递,所以会在返回值的地方调用
阅读全文
摘要:# 38.如何用代码判断大小端存储? 大端存储:字数据的高字节存储在低地址中 小端存储:字数据的低字节存储在低地址中 例如:32bit的数字0x12345678 **所以在Socket编程中,往往需要将操作系统所用的小端存储的IP地址转换为大端存储,这样才能进行网络传输** 小端模式中的存储方式为:
阅读全文
摘要:# 37.public,protected和private访问和继承权限的区别? - public的变量和函数在类的内部外部都可以访问。 - protected的变量和函数只能在类的内部和其派生类中访问。 - private修饰的元素只能在类内访问 派生类可以继承基类中除了构造/析构、赋值运算符重载
阅读全文
摘要:# 36.内联函数和宏定义的区别 ■在使用时,宏只做简单字符串替换(编译前)。内联函数在编译时直接将函数代码嵌入到目标代码中,可以进行参数类型检查(编译时),语法判断等功能,且具有返回值,可以实现重载。 ■宏看起来像一个函数调用,但是会有隐藏一些难以发现的错误,宏定义时要注意书写(参数要括起来)否则
阅读全文
摘要:# 33.C++中的重载、重写(覆盖)和隐藏的区别 (1)重载(overload) 重载是指在同一范围定义中的同名成员函数才存在重载关系。主要特点是函数名相同,参数类型和数目有所不同,不能出现参数个数和类型均相同,仅仅依靠返回值不同来区分的函数。重载和函数成员是否是虚函数无关。举个例子: ```C+
阅读全文
摘要:# 34.C++有哪几种的构造函数 C++中的构造函数可以分为4类: - 默认构造函数:在没有显式定义构造函数时,C++会自动生成一个默认构造函数,该函数没有参数,不执行任何操作。 - 初始化构造函数(有参数) - 拷贝构造函数:当使用现有对象初始化新对象时,拷贝构造函数被调用。它的语法是在函数声明
阅读全文
摘要:# 35.浅拷贝和深拷贝的区别 **浅拷贝** 浅拷贝只是拷贝一个指针,并没有新开辟一个地址,拷贝的指针和原来的指针指向同一块地址,如果原来的指针所指向的资源释放了,那么再释放浅拷贝的指针的资源就会出现错误。 **深拷贝** 深拷贝不仅拷贝值,还开辟出一块新的空间用来存放新的值,即使原先的对象被析构
阅读全文
摘要:# 32.C和C++的类型安全 **什么是类型安全?** 类型安全很大程度上可以等价于内存安全,类型安全的代码不会试图访问自己没被授权的内存区域。“类型安全”常被用来形容编程语言,其根据在于该门编程语言是否提供保障类型安全的机制;有的时候也用“类型安全”形容某个程序,判别的标准在于该程序是否隐含类型
阅读全文
摘要:# 31.野指针和悬空指针 都是是指向无效内存区域(这里的无效指的是"不安全不可控")的指针,访问行为将会导致未定义行为。 ●野指针 “野指针”(wild pointer):是没有被初始化过的指针,所以不确定指针具体指向。因为“野指针”可能指向任意内存段,因此它可能会损坏正常的数据,也有可能引发其他
阅读全文
摘要:# 30.externC的用法 为了能够**正确地在C++代码中调用C语言**的代码:在程序中加上extern "C"后,相当于告诉编译器这部分代码是C语言写的,因此要按照C语言进行编译,而不是C++; 哪些情况下使用extern "C": (1)C++代码中调用C语言代码; (2)在C++中的头文
阅读全文
摘要:# 27.final和override关键字 在C++中,final是一个关键字,用于修饰类的成员变量和成员函数。 1.final修饰成员变量:当一个类中的成员变量被声明为final时,它就变成了常量,即它的值不能再被修改。final修饰的成员变量必须在类定义中进行初始化,且只能初始化一次。 假设我
阅读全文
摘要:# 28.拷贝初始化和直接初始化 ●当用于类类型对象时,初始化的拷贝形式和直接形式有所不同:直接初始化直接调用与实参匹配的构造函数,拷贝初始化总是调用拷贝构造函数。拷贝初始化首先使用指定构造函数创建一个临时对象,然后用拷贝构造函数将那个临时对象拷贝到正在创建的对象。举例如下 ```C++ strin
阅读全文
摘要:# 29.初始化和赋值的区别 在C++中,初始化和赋值是两个不同的概念。 需要注意的是,对于某些类型的变量,初始化和赋值的效果是一样的。例如,对于基本类型的变量,使用等号进行初始化和赋值的效果是一样的。但是对于一些复杂类型的变量,如类对象,初始化和赋值的效果是不同的。在这种情况下,初始化会调用类的构
阅读全文
摘要:# 25.C++的顶层const和底层const 任意常量对象为**顶层const**,包括常量指针;指向常量的指针和声明const的引用都为**底层const** 顶层const(top-level const)表示指针本身是个常量int* const ptr=&m; 此时指针不可以发生改变,但是
阅读全文
摘要:# 26.数组名和指针(这里为指向数组首元素的指针)区别? - 二者均可通过增减偏移量来访问数组中的元素。 - 数组名不是真正意义上的指针,可以理解为常指针,所以数组名没有自增、自减等操作。 - **当数组名当做形参传递给调用函数后,就失去了原有特性,退化成一般指针,多了自增、自减操作,但sizeo
阅读全文
摘要:# 23.define宏定义和const的区别 **编译阶段** - define是在编译的**预处理**阶段起作用,而const是在编译、运行的时候起作用 **安全性** - define只做替换,不做类型检查和计算,也不求解,容易产生错误,一般最好加上一个大括号包含住全部的内容,要不然很容易出错
阅读全文
摘要:# 24.C++中const和static的作用 **static** ●不考虑类的情况 ○隐藏。所有不加static的全局变量和函数具有全局可见性,可以在其他文件中使用,加了之后只能在该文件所在的编译模块中使用 ○默认初始化为0,包括未初始化的全局静态变量与局部静态变量,都存在全局未初始化区 ○静
阅读全文
摘要:# 22.C++中struct和class的区别 **相同点** - 两者都拥有成员函数、公有和私有部分 - 任何可以使用class完成的工作,同样可以使用struct完成 **不同点** - C中struct是没有权限的设置的,struct成员权限默认是公有的,且struct中只能是一些变量的集合
阅读全文
摘要:# 20.C++和C语言的区别 - C++中new和delete是对内存分配的运算符,取代了C中的malloc和free。 - 标准C++中的字符串类取代了标准C函数库头文件中的字符数组处理函数(C中没有字符串类型)。 - C++中用来做控制态输入输出的iostream类库替代了标准C中的stdio
阅读全文
摘要:# 21.C++与Java的区别 **语言特性** - Java语言给开发人员提供了更为简洁的语法;完全面向对象,由于JVM(Java虚拟机)可以安装到任何的操作系统上,所以说它的可移植性强 - Java语言中没有指针的概念,引入了真正的数组。不同于C++中利用指针实现的“伪数组”,Java引入了真
阅读全文
摘要:# 17.常量指针和指针常量区别? ## 1)常量指针(指向常量的指针) 语法:const 数据类型 *变量名; 不能通过解引用的方法修改内存地址中的值(用原始的变量名是可以修改的)。 注意: ●指向的变量(对象)可以改变(之前是指向变量a的,后来可以改为指向变量b)。 ●一般用于修饰函数的形参,表
阅读全文
摘要:# 18.a和&a有什么区别? 假设数组int a[10]; int (*p)[10] = &a;其中: - a是数组名,是数组首元素地址,+1表示地址值加上一个int类型的大小,如果a的值是0x00000001,加1操作后变为0x00000005。*(a + 1) = a[1]。 - &a是数组的
阅读全文
摘要:# 19.C++和Python的区别 包括但不限于: - Python是一种脚本语言,是解释执行的,而C++是编译语言,是需要编译后在特定平台运行的。python可以很方便的跨平台,但是效率没有C++高。 - Python使用缩进来区分不同的代码块,C++使用花括号来区分 - C++中需要事先定义变
阅读全文
摘要:# 14.宏定义和typedef区别? - 宏主要用于定义常量及书写复杂的内容;typedef主要用于定义类型别名。 - 宏替换发生在编译阶段之前,属于文本插入替换;typedef是编译的一部分。 - 宏不检查类型;typedef会检查数据类型。 - 宏不是语句,不在在最后加分号;typedef是语
阅读全文
摘要:# 15.变量声明和定义区别? - 声明仅仅是把变量的声明的位置及类型提供给编译器,并不分配内存空间;定义要在定义的地方为其分配存储空间。 - 相同变量可以在多处声明(外部变量extern),但只能在一处定义。
阅读全文
摘要:# 16.strlen和sizeof区别? - sizeof是运算符,并不是函数,结果在编译时得到而非运行中获得;strlen是字符处理的库函数。 - sizeof参数可以是任何数据的类型或者数据(sizeof参数不退化);strlen的参数只能是字符指针且结尾是'\0'的字符串。 - 因为size
阅读全文
摘要:# 11.既然有了malloc-free,C++中为什么还需要new-delete呢?直接用malloc-free不好吗? - malloc/free和new/delete都是用来申请内存和回收内存的。 - 在对非基本数据类型的对象使用的时候,对象创建的时候还需要执行构造函数,销毁的时候要执行析构函
阅读全文
摘要:# 12.被free回收的内存是立即返还给操作系统吗? 不是的,被free回收的内存会首先被ptmalloc使用双链表保存起来,当用户下一次申请内存的时候,会尝试从这些内存中寻找合适的返回。这样就避免了频繁的系统调用,占用过多的系统资源。同时ptmalloc也会尝试对小块内存进行合并,避免过多的内存
阅读全文
摘要:# 13.宏定义和函数有何区别? - 宏在预处理阶段完成替换,之后被替换的文本参与编译,相当于直接插入了代码,运行时不存在函数调用,执行起来更快;函数调用在运行时需要跳转到具体调用函数。 - 宏定义属于在结构中插入代码,没有返回值;函数调用具有返回值。 - 宏定义参数没有类型,不进行类型检查;函数参
阅读全文
摘要:# 9.new和delete是如何实现的? - new的实现过程是:首先调用名为**operator new**的标准库函数,分配足够大的原始为类型化的内存,以保存指定类型的一个对象;接下来运行该类型的一个构造函数,用指定初始化构造对象;最后返回指向新分配并构造后的的对象的指针 - delete的实
阅读全文
摘要:# 10.malloc和new的区别? - malloc和free是标准库函数,支持覆盖;new和delete是运算符,支持重载。 - malloc仅仅分配内存空间,free仅仅回收空间,不具备调用构造函数和析构函数功能,用malloc分配空间存储类的对象存在风险;new和delete除了分配回收功
阅读全文
摘要:# 7.区别以下指针类型? ```C++ int *p[10] int (*p)[10] int *p(int) int (*p)(int) ``` - int *p[10]表示指针数组,强调数组概念,是一个数组变量,数组大小为10,数组内每个元素都是指向int类型的指针变量。 - int (*p)
阅读全文
摘要:# 8.new-delete操作与malloc-free的操作异同 **相同点** ●都可用于内存的动态申请和释放 ●new和malloc都可以分配指定大小的内存块,并且分配的内存都在堆上。 ●new和malloc的结果都返回一个指向已分配内存的指针。 ●都允许使用字面量作为参数来分配内存。 **不
阅读全文
摘要:# 5.堆和栈的区别 - 申请方式不同。 - 栈由系统自动分配。 - 堆是自己申请和释放的。 - 申请大小限制不同。 - 栈顶和栈底是之前预设好的,栈是向栈底扩展,大小固定,可以通过ulimit -a查看,由ulimit -s修改。 - 堆向高地址扩展,是不连续的内存区域,大小可以灵活调整。 - 申
阅读全文
摘要:# 6.你觉得栈快一点还是堆快一点? 毫无疑问是栈快一点。 因为操作系统会在底层对栈提供支持,会分配专门的寄存器存放栈的地址,栈的入栈出栈操作也十分简单,并且有专门的指令执行,所以栈的效率比较高也比较快。 而堆的操作是由C/C++函数库提供的,在分配堆内存的时候需要一定的算法寻找合适大小的内存。并且
阅读全文
摘要:# 3.指针和引用的区别 - 指针是一个变量,存储的是一个地址,需要占用存储空间;引用本质上是一个常量指针,引用跟原来的变量实质上是同一个东西,是原变量的别名 - 指针可以有多级,引用只有一级 - 指针可以为空,引用不能为NULL(必须有具体实体) - 指针声明和定义可以分开,可以先只声明指针变量而
阅读全文
摘要:# 4.在传递函数参数时,什么时候该使用指针,什么时候该使用引用呢? ●需要返回函数内局部变量的内存的时候用指针。使用指针传参需要开辟内存,用完要记得释放指针,不然会内存泄漏。而返回局部变量的引用是没有意义的 ``` 如果需要返回函数内局部变量的内存,应该使用指针而不是引用。 原因如下: 1.因为引
阅读全文
摘要:例子1: ```C++ struct S1 { char c1; int i; char c2; }; ``` ```C #include struct S1 { char c1; int i; char c2; }; int main() { printf("%d\n", sizeof(struc
阅读全文
摘要:# 1.在main执行之前和之后的代码可能是什么? **main函数执⾏之前,主要就是初始化系统相关资源:** ■设置栈指针:所谓设置栈,就是将栈指针指向某块内存 ■初始化静态`static`变量和`global`全局变量,即`.data`段的内容 ■将未初始化部分的全局变量赋初值:数值型`shor
阅读全文