当前位置: 首页 > news >正文

【C++复习1】基础篇

1.C/C++基础

1.1.简述下C++语言的特点

回答:

1.C++在C语言的基础上引入了面向对象机制,同时也兼容C语言。

2.C++有三大特性 : 封装 继承 多态。

3.C++语言编写出的程序结构清晰、易于扩充、程序可读性好。

4.C++生成的代码质量高、运行效率高,仅比汇编语言慢10%~20%。

5.C++更加安全,增加了const常量、引用、四类cast转换(static_cast、dynamic_cast、           const_cast、reinterpret_cast)、智能指针、try—catch等等;

6.C++可复用性高,C++引入了模板的概念,后面在此基础上,实现了方便开发的标准模板库 STL(Standard Template Library)。

7.同时,C++是不断在发展的语言。C++后续版本更是发展了不少新特性,如C++11中引入了         nullptr、auto变量、Lambda匿名函数、右值引用、智能指针。

1.2.说说C语言和C++语言的区别

回答:

1. C语言是C++的子集,C++可以很好兼容C语言。但是C++又有很多新特性,如引用、智能指针、 auto变量等。

2. C++是面对对象的编程语言;C语言是面对过程的编程语言。

3. C语言有一些不安全的语言特性,如指针使用的潜在危险、强制转换的不确定性、内存泄露等。而 C++对此增加了不少新特性来改善安全性,如const常量、引用、cast转换、智能指针、try—catch 等等;

4. C++可复用性高,C++引入了模板的概念,后面在此基础上,实现了方便开发的标准模板库STL。 C++的STL库相对于C语言的函数库更灵活、更通用。

1.3.说说C++中struct 和 class的区别

回答:

1. struct 一般用于描述一个数据结构集合,而 class 是对一个对象数据的封装;

2. struct 中默认的访问控制权限是 public 的,而 class 中默认的访问控制权限是 private 的,例如:

struct A{int iNum; //默认访问控制权是public
}
class B{int iNum; //访问控制权是private
}

3. 在继承关系中,struct 默认是公有继承,而 class 是私有继承;

4. class 关键字可以用于定义模板参数,就像 typename,而 struct 不能用于定义模板参数,例如:

template<typename T, typename Y>     // 可以把typename 换成 class 
int Func(const T& t, const Y& y) { //TODO 
}

5. C++ 中的 class 是对 C 中的 struct 进行了扩充,它们在声明时的区别如下:

5. 使用时的区别:C 中使用结构体需要加上 struct 关键字,或者对结构体使用 typedef 取别名,而 C++ 中可以省略 struct 关键字直接使用

struct Student{int  iAgeNum;string strName;}
typedef struct Student Student2;//C区别名
struct Student stu1;    // C 中正常使用
Student2 stu2;  // C 中通过取别名的使用
Student stu3; // C++ 中使用

1.4.说说include头文件的顺序以及双引号""和尖括号<>的区别

回答:

1. 区别:

(1)尖括号<>的头文件是系统文件,双引号""的头文件是自定义文件。

(2)编译器预处理阶段查找头文件的路径不一样。

2. 查找路径:

(1)使用尖括号<>的头文件的查找路径:编译器设置的头文件路径-->系统变量。

(2)使用双引号""的头文件的查找路径:当前头文件目录-->编译器设置的头文件路径-->系统变 量。

1.5.说说C++结构体和C结构体的区别

回答:

(1)C的结构体内不允许有函数存在,C++允许有内部成员函数,且允许该函数是虚函数。 (2) C的结构体对内部成员变量的访问权限只能是public,而C++允许public,protected,private三种。

(3)C语言的结构体是不可以继承的,C++的结构体是可以从其他的结构体或者类继承过来的。 (4)C 中使用结构体需要加上 struct 关键字,或者对结构体使用 typedef 取别名,而 C++ 中可以省略 struct 关键字直接使用。

1.6.导入C函数的关键字是什么,C++编译时和C有什么不同?

回答:

1. 关键字:在C++中,导入C函数的关键字是extern,表达形式为extern “C”, extern "C"的主要作 用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分 代码按C语言的进行编译,而不是C++的。

2. 编译区别:由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译 后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会 带上函数的参数类型,一般只包括函数名

1.7.简述C++从代码到可执行二进制文件的过程

回答:C++和C语言类似,一个C++程序从源码到执行文件,有四个过程,预编译、编译、汇编、链接。

具体一点的回答:

1. 预编译:这个过程主要的处理操作如下:

(1) 将所有的#define删除,并且展开所有的宏定义

(2) 处理所有的条件预编译指令,如#if、#ifdef

(3) 处理#include预编译指令,将被包含的文件插入到该预编译指令的位置。

(4) 过滤所有的注释

(5) 添加行号和文件名标识。

2. 编译:这个过程主要的处理操作如下:

(1) 词法分析:将源代码的字符序列分割成一系列的记号。

(2) 语法分析:对记号进行语法分析,产生语法树。

(3) 语义分析:判断表达式是否有意义。

(4) 代码优化:

(5) 目标代码生成:生成汇编代码。

(6) 目标代码优化:

3. 汇编:这个过程主要是将汇编代码转变成机器可以执行的指令。

4. 链接:将不同的源文件产生的目标文件进行链接,从而形成一个可以执行的程序。

链接分为静态链接和动态链接。

静态链接,是在链接的时候就已经把要调用的函数或者过程链接到了生成的可执行文件中,就算你 在去把静态库删除也不会影响可执行程序的执行;生成的静态链接库,Windows下以.lib为后缀, Linux下以.a为后缀。

动态链接,是在链接的时候没有把调用的函数代码链接进去,而是在执行的过程中,再去找要链 接的函数,生成的可执行文件中没有函数代码,只包含函数的重定位信息,所以当你删除动态库 时,可执行程序就不能运行。生成的动态链接库,Windows下以.dll为后缀,Linux下以.so为后 缀。

1.8.说说static关键字的作用

回答:

1. 定义全局静态变量和局部静态变量:在变量前面加上static关键字。初始化的静态变量会在数据段 分配内存,未初始化的静态变量会在BSS段(未初始化的数据段)分配内存。直到程序结束,静态变量始终会维持前值。 只不过全局静态变量和局部静态变量的作用域不一样;

2.定义静态函数:在函数返回类型前加上static关键字,函数即被定义为静态函数。静态函数只能在 本源文件中使用;

3.在变量类型前加上static关键字,变量即被定义为静态变量。静态变量只能在本源文件中使用

4. 在c++中,static关键字可以用于定义类中的静态成员变量:使用静态数据成员,它既可以被当成 全局变量那样去存储,但又被隐藏在类的内部。类中的static静态数据成员拥有一块单独的存储 区,而不管创建了多少个该类的对象。所有这些对象的静态数据成员都共享这一块静态存储空间。

5. 在c++中,static关键字可以用于定义类中的静态成员函数:与静态成员变量类似,类里面同样可 以定义静态成员函数。只需要在函数前加上关键字static即可。如静态成员函数也是类的一部分, 而不是对象的一部分。所有这些对象的静态数据成员都共享这一块静态存储空间。

6.当调用一个对象的非静态成员函数时,系统会把该对象的起始地址赋给成员函数的this指针。而静态成 员函数不属于任何一个对象,因此C++规定静态成员函数没有this指针(划重点,面试题常考)。既然 它没有指向某一对象,也就无法对一个对象中的非静态成员进行访问。

1.9.说说数组和指针的区别

回答:

1. 概念:

(1)数组:数组是用于储存多个相同类型数据的集合。 数组名是首元素的地址。

(2)指针:指针相当于一个变量,但是它和不同变量不一样,它存放的是其它变量在内存中的地 址。 指针名指向了内存的首地址。

2. 区别:

(1)赋值:同类型指针变量可以相互赋值;数组不行,只能一个一个元素的赋值或拷贝

(2)存储方式:

        数组:数组在内存中是连续存放的,开辟一块连续的内存空间。数组是根据数组的下标进行访问的,数组的存储空间,不是在静态区就是在栈上。

        指针:指针很灵活,它可以指向任意类型的数据。指针的类型说明了它所指向地址空间的内 存。由于指针本身就是一个变量,再加上它所存放的也是变量,所以指针的存储空间不能确定。

(3)求sizeof:

        数组所占存储空间的内存大小:sizeof(数组名)/sizeof(数据类型) 在32位平台下,无论指针的类型是什么,sizeof(指针名)都是4,在64位平台下,无论指针的 类型是什么,sizeof(指针名)都是8。

1.10.说说什么是函数指针, 如何定义函数指针,有什么使用场景

回答:

1. 概念:函数指针就是指向函数的指针变量。每一个函数都有一个入口地址,该入口地址就是函数指 针所指向的地址。

2. 定义形式如下:

int func(int a);  
int (*f)(int a);  
f = &func; 

3. 函数指针的应用场景:回调(callback)。我们调用别人提供的 API函数(Application Programming Interface,应用程序编程接口),称为Call;如果别人的库里面调用我们的函数,就叫 Callback。

1.11.说说静态变量什么时候初始化

回答:

对于C语言的全局和静态变量,初始化发生在任何代码执行之前,属于编译期初始化

而C++标准规定:全局或静态对象当且仅当对象首次用到时才进行构造。

1.12.nullptr调用成员函数可以吗?为什么?

回答:

可以 , 只要成员函数内部不适用解引用操作即可 

因为在编译时对象就绑定了函数地址,和指针空不空没关系。pAn->breathe();编译的时候,函数 的地址就和指针pAn绑定了;调用breath(*this), this就等于pAn。由于函数中没有需要解引用this的地 方,所以函数运行不会出错,但是若用到this,因为this=nullptr,运行出错。

1.13.说说什么是野指针, 怎么产生的 , 如何避免?

回答:

1. 概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

2. 产生原因:释放内存后指针不及时置空(野指针),依然指向了该内存,那么可能出现非法访问的错误。这些我们都要注意避免。

3. 避免办法: (1)初始化置NULL (2)申请内存后判空 (3)指针释放后置NULL (4)使用智能指针

1.14.说说静态局部变量,全局变量,局部变量的特点,以及使用场景

回答:

1. 首先从作用域考虑:C++里作用域可分为6种:全局,局部,类,语句,命名空间和文件作用域。

全局变量:全局作用域,可以通过extern作用于其他非定义的源文件。

静态全局变量 :全局作用域+文件作用域,所以无法在其他文件中使用。 局部变量:局部作用域,比如函数的参数,函数内的局部变量等等。

静态局部变量 :局部作用域,只被初始化一次,直到程序结束。

2. 从所在空间考虑:除了局部变量在栈上外,其他都在静态存储区。因为静态变量都在静态存储区, 所以下次调用函数的时候还是能取到原来的值。

3. 生命周期: 局部变量在栈上,出了作用域就回收内存;而全局变量、静态全局变量、静态局部变 量都在静态存储区,直到程序结束才会回收内存。

1.15.说说内联函数和宏函数的区别

回答:区别是:

1. 宏定义不是函数,但是使用起来像函数。预处理器用复制宏代码的方式代替函数的调用,省去了函 数压栈退栈过程,提高了效率;而内联函数本质上是一个函数,内联函数一般用于函数体的代码比 较简单的函数,不能包含复杂的控制语句,while、switch,并且内联函数本身不能直接调用自身。

2. 宏函数是在预编译的时候把所有的宏名用宏体来替换,简单的说就是字符串替换 ;而内联函数则 是在编译的时候进行代码插入,编译器会在每处调用内联函数的地方直接把内联函数的内容展开, 这样可以省去函数的调用的开销,提高效率

3. 宏定义是没有类型检查的,无论对还是错都是直接替换;而内联函数在编译的时候会进行类型的检 查,内联函数满足函数的性质,比如有返回值、参数列表等

1.17.说说new和malloc的区别, 各自底层实现原理

回答:

1. new是操作符,而malloc是函数。

2. new在调用的时候先分配内存,在调用构造函数,释放的时候调用析构函数;而malloc没有构造 函数和析构函数。

3. malloc需要给定申请内存的大小,返回的指针需要强转;new会调用构造函数,不用指定内存的 大小,返回指针不用强转。

4. new可以被重载;malloc不行

5. new分配内存更直接和安全。 6. new发生错误抛出异常,malloc返回null

malloc底层实现:当开辟的空间小于 128K 时,调用 brk()函数;当开辟的空间大于 128K 时,调用 mmap()。malloc采用的是内存池的管理方式,以减少内存碎片。先申请大块内存作为堆区,然后将 堆区分为多个内存块。当用户申请内存时,直接从堆区分配一块合适的空闲块。采用隐式链表将所有空闲块,每一个空闲块记录了一个未分配的、连续的内存地址。

new底层实现:关键字new在调用构造函数的时候实际上进行了如下的几个步骤:

1. 创建一个新的对象

2. 将构造函数的作用域赋值给这个新的对象(因此this指向了这个新的对象)

3. 执行构造函数中的代码(为这个新对象添加属性)

4. 返回新对象

1.18.说说const和define的区别

回答:

const用于定义常量;而define用于定义宏,而宏也可以用于定义常量。都用于常量定义时,它们的区 别有:

1.const生效于编译的阶段;define生效于预处理阶段

2. const定义的常量,在C语言中是存储在内存中、需要额外的内存空间的;define定义的常量,运 行时是直接的操作数,并不会存放在内存中。

3. const定义的常量是带类型的;define定义的常量不带类型。因此define定义的常量不利于类型检 查。

1.19.说说C++中函数指针和指针函数的区别

回答:

1. 定义不同

    指针函数本质是一个函数,其返回值为指针。

    函数指针本质是一个指针,其指向一个函数。

2.写法不同

指针函数:int *fun(int x,int y);
函数指针:int (*fun)(int x,int y);

3.用法不同

1.20.说说const int *a, int const *a, const int a, int *const a, const int *const a分别是什么,有什么特点。

1.21.说说使用指针需要注意什么?

回答:

1. 定义指针时,先初始化为NULL。

2. 用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内 存。

3. 不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。

4. 避免数字或指针的下标越界,特别要当心发生“多1”或者“少1”操作

5. 动态内存的申请与释放必须配对,防止内存泄漏 6. 用free或delete释放了内存之后,立即将指针设置为NULL,防止“野指针”

1.22.说说内联函数和函数的区别,内联函数的作用。

回答:

1. 内联函数比普通函数多了关键字inline

2. 内联函数避免了函数调用的开销;普通函数有调用的开销

3. 普通函数在被调用的时候,需要寻址(函数入口地址);内联函数不需要寻址。

4. 内联函数有一定的限制,内联函数体要求代码简单,不能包含复杂的结构控制语句;普通函数没有 这个要求。

内联函数的作用:内联函数在调用时,是将调用表达式用内联函数体来替换。避免函数调用的开销。

1.23.简述C++有几种传值方式,之间的区别是什么?

回答:

传参方式有这三种:值传递、引用传递、指针传递

1. 值传递:形参即使在函数体内值发生变化,也不会影响实参的值;

2. 引用传递:形参在函数体内值发生变化,会影响实参的值;

3. 指针传递:在指针指向没有发生改变的前提下,形参在函数体内值发生变化,会影响实参的值;

值传递用于对象时,整个对象会拷贝一个副本,这样效率低;而引用传递用于对象时,不发生拷贝行为,只是绑定对象,更高效;指针传递同理,但不如引用传递安全。

1.24.简述const(星号)和(星号)const的区别

回答:

http://www.lryc.cn/news/580039.html

相关文章:

  • 负载均衡--常见负载均衡算法
  • 大带宽服务器中冗余技术的功能
  • 【深度解析】Seedance 1.0:重新定义 AI 视频生成的工业级标准
  • 10.双端Diff算法
  • [代码学习] c++ 通过H矩阵快速生成图像对应的mask
  • 嵌入式C语言:指针
  • Jenkins-Email Extension 插件插件
  • ubuntu 18.04配置镜像源
  • ubuntu22桌面版中文输入法 fcitx5
  • 运维打铁:企业云服务解决方案
  • 金融系统中常用的FIX协议
  • 企业电商解决方案哪家好?ZKmall模块商城全渠道支持 + 定制化服务更省心
  • 文本分词 nltk
  • ODS 系统是什么?企业为什么需要搭建 ODS?
  • CentOS配置网络
  • 【Oracle APEX开发小技巧15】多级弹窗关闭子级保留父级
  • 建议大家都去频繁大量地记录自己:让目标在笔尖下生根发芽
  • 【银行测试】手机银行APP专项项目+测试点汇总(一)
  • 【烧脑算法】最小字典序:巧用单调栈,从栈底到最优解
  • Jmeter安装使用-测试Java接口
  • iOS IPA 混淆,如何对企业定制 App 做渠道差异化保护
  • 写一个ununtu C++ 程序,调用ffmpeg , 来判断一个数字电影的音频文件mxf 的 采样率(频率),通道数, 采样位数
  • ARMv8 没开mmu执行memset引起的非对齐访问异常
  • 新商品冷启动:基于语义Embedding与GBRT的消费指标预估技术实践
  • chrome插件合集
  • vue 循环无限滚动表格
  • Mint密室 · 猫猫狐狐的“特征选择”囚室逃脱
  • QT5.14.2+VS2019 打包程序找dll(纯QT+Opencv程序)
  • 鸿蒙开发List长按Item拖拽切换效果
  • kali安装教程