本文主要是介绍【面试题】【C++】01-C++语法部分面试题,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
【面试题】【C++】01-C++语法部分面试题
1 C和C++有什么区别? 2 以下代码中的a和&a有什么区别? 3 static关键字有什么作用? 4 #define和const有什么区别? 5 对于⼀个频繁使用的短小函数,应该使用什么来实现?有什么优缺点? 6 什么是智能指针?智能指针有什么作用?分为哪几种?各自有什么样的特点? 7 shared_ptr是如何实现的? 8 右值引用有什么作用? 9 悬挂指针与野指针有什么区别? 10 静态链接和动态链接有什么区别? 11 变量的声明和定义有什么区别 12 简述#ifdef、#else、#endif和#ifndef的作用 13 写出int、bool、float、指针变量与“零值”比较的if语句 14 结构体可以直接赋值吗 15 sizeof和strlen的区别 16 C语言的关键字static和C++的关键字static有什么区别 17 volatile有什么作用 18 一个参数可以既是const又是volatile吗 19 全局变量和局部变量有什么区别?操作系统和编译器是怎么知道的? 20 简述strcpy、sprintf与memcpy的区别 21 请解析((void ()( ) )0)( )的含义 22 C语言的指针和引用和c++的有什么区别? 23 typedef和#define有什么区别 24 指针常量与常量指针区别 25 简述队列和栈的异同 26 设置地址为0x67a9 的整型变量的值为0xaa66 27 C语言的结构体和C++的有什么区别 28 如何避免“野指针” 29 句柄和指针的区别和联系是什么? 30 说一说extern“C” 31 C++的顶层const和底层const ? 32 栈区和堆区的区别?栈区和堆栈的区别?
1 C和C++有什么区别?
和C语言相比,C++新增了面向对象的内容。C语言主要使用面向过程的编程范式,C++主要使用面向对象的编程范式(泛型编程和函数式编程使用相对较少); 和C语言相比,C++新增了引用、函数重载、异常处理、内联函数等功能; C++用new/delete替代了C语言中的malloc/free,此外还添加了智能指针,在动态内存的使用上安全性更高。
2 以下代码中的a和&a有什么区别?
int a[10];
int (*p)[10] = &a;
a是数组名,也是数组的首地址。a+1会向后移动sizeof(int),即*(a+1)就是a[1]。 &a是指向数组的指针,类型为int(*)[10]。a+1会向后移动sizeof(int) * 10。即数组尾元素之后的位置
3 static关键字有什么作用?
修饰局部变量 (1)静态局部变量存储在静态存储区内。 (2)静态局部变量仅在第一次调用时创建并初始化,后续调用到其定义代码时,不会再次定义或初始化; (3)静态局部变量的生命周期从其定义时开始,直到程序结束。 (4)静态局部变量仅在其定义域中可见,在其定义域之外不可见。 修饰全局变量 (1)静态全局变量存储在静态存储区内; (2)静态全局变量的生命周期从其定义位置开始,直到程序运行结束。 (3)静态全局变量在其声明的文件内可见,在文件外不可见。 修饰函数 (1)static修饰的函数仅在其定义的文件中可见,文件外不可见。由此可以避免函数命名冲突。 修饰成员变量 (1)static修饰的成员变量只有一份拷贝,为该类的所有对象共享。 (2)static修饰的成员变量无需实例化即可访问; (3)static修饰的成员变量在类外部初始化,且初始化时不加static。 修饰成员函数 (1)static修饰的成员函数无需实例化也可调用; (2)static修饰的成员函数不接受this指针 (3)static修饰的成员函数不能使用非static的成员变量,只能使用静态成员。
4 #define和const有什么区别?
编译器处理方式不同 (1)#define在预处理阶段进行替换,不能调试。 (2)const常量在编译阶段处理。 类型和安全检查不同 (1)#define不做类型检查,仅是代码展开,可能产生边际效应等错误。 (2)const常量具有类型,在编译阶段会进行类型检查。 存储方式不同 (1)#define是单纯的替换,不分配内存,存储在程序的代码段中。 (2)const常量会分配内存,但仅维持一份拷贝,存储在程序的数据段中。 定义域不同 (1)#define不受定义域限制。 (2)const常量仅在定义域内有效。
5 对于⼀个频繁使用的短小函数,应该使用什么来实现?有什么优缺点?
应使用inline内联函数来实现。
优点:
inline函数省略了函数调用的过程,效率相对更高; inline函数会进行语法检查和类型检查,安全性比宏函数更好。
缺点:
inline函数在所有调用位置展开,代码膨胀; 如果inline函数的执行时间比调用时间长很多,则省略函数调用带来的效率提升并不明显。 如果inline函数修改,则所有使用此函数的源码文件都需要重新编译。 inline函数只是建议,编译器是否内联是不确定的。
6 什么是智能指针?智能指针有什么作用?分为哪几种?各自有什么样的特点?
智能指针是为了解决手动申请、释放动态内存容易导致内存泄露和空悬指针的问题而出现的。智能指针会自动管理动态内存,在析构时释放资源。
auto_ptr:
auto_ptr是C++98的概念,在C++11中已被淘汰; auto_ptr本质上是独占的智能指针,但将其赋值给另一个智能指针是不会报错,此时继续使用前者可能导致内存崩溃。
unique_ptr:
unique_ptr是独占式的指针,同一时间只能有一个智能指针指向该对象。 unique_ptr不能拷贝构造和拷贝赋值,但可以移动构造和移动赋值。
shared_ptr:
shared_ptr是共享式的智能指针,允许多个智能指针同时指向同一对象。 shared_ptr有引用计数,用于记录当前有多少智能指针指向该对象。
构造函数中,将引用计数初始化为1; 拷贝构造函数中,将引用计数+1; 赋值运算符中,将左侧对象的引用计数-1,右侧对象的引用计数+1; 析构函数中,引用计数-1; 在析构或赋值时,如果某个对象的引用计数减为0,则调用delete释放对象。 成员函数:
use_count:返回引用计数的个数; unique:返回是否独占 swap:交换两个shared_ptr对象 reset get
weak_ptr:
weak_ptr是不影响所指对象生命周期的智能指针。weak_ptr是对对象的弱引用,可以绑定到shared_ptr,但weak_ptr的构造和析构不会改变引用计数; weak_ptr解决shared_ptr相互引用时,两个指针的引用计数永远不会减为0,从而导致的死锁问题。 weak_ptr和shared_ptr之间可以相互转化,shared_ptr可以直接赋值给weak_ptr,weak_ptr可以通过lock函数获得shared_ptr。 不能通过weak_ptr直接访问对象的方法,要先转化为shared_ptr再访问。
7 shared_ptr是如何实现的?
构造函数中,引用计数初始化为1; 拷贝构造函数中,引用计数+1; 赋值时,左侧对象引用计数-1,右侧对象引用计数+1 析构函数中,引用计数-1。 在赋值和析构函数中,如果引用计数降为0,调用delete释放对象。
8 右值引用有什么作用?
9 悬挂指针与野指针有什么区别?
悬挂指针:指针所指的对象已经释放,但指针仍指向这块已经被回收的内存。
野指针:未经初始化的指针。
10 静态链接和动态链接有什么区别?
静态链接在编译的链接阶段将执行代码拷贝到调用位置。
优点:
程序独立运行,不依赖库文件; 前期执行效率比动态链接略高。
缺点:
程序体积较大。如有多个程序使用同一静态库,会有一定空间浪费; 静态库更新后,相关可执行文件均需重新链接。
动态库不拷贝执行代码,而是在程序运行或加载时将一系列符号和参数传给操作系统,由操作系统将对应的动态库加载到内存中。需要调用相关代码时,再去共享内存中查找,从而实现动态链接。
优点:
多个程序可以共用一个动态库,节省资源; 动态库更新后,可执行文件不用重新链接;
缺点:
程序依赖动态库,如操作系统中动态库缺失,则无法使用; 由于是动态加载,前期执行效率会比静态库略慢。
11 变量的声明和定义有什么区别
(1)变量定义时分配内存,声明则不分配内存; (2)变量定义仅有一处,但声明可以有多处; (3)使用extern修饰的是变量声明,说明该变量将在本文件后续位置或其他文件中定义。
12 简述#ifdef、#else、#endif和#ifndef的作用
(1)使用条件编译将功能模块包含进去,可以快捷打开/关闭某个功能; (2)可用于快速打开/关闭调试信息。 (3)不同硬件平台的差异处理。
13 写出int、bool、float、指针变量与“零值”比较的if语句
// int
if (i == 0)
if (i != 0)
// bool
if (b)
if (!b)
// 指针
if (p == nullptr)
if (p != nullptr)
// float
#define EPSINON 0.00001
if ((x >= -EPSINON) && (x <= EPSINON))
14 结构体可以直接赋值吗
结构体可以在定义时直接初始化,同一结构体的不同对象之间也可以相互赋值。但如果结构体内存在指针类型的变量,则在释放时需要注意是否还有其他对象使用这段内存。
15 sizeof和strlen的区别
(1)sizeof是操作符,strlen是库函数; (2)sizeof的结果在编译阶段即可确定,strlen则在运行时确定; (3)sizeof可以处理类型、变量、数组等,strlen仅能处理以’\0’结尾的字符数组; (4)sizeof计算的是实际占用内存空间的大小,strlen计算的是字符个数。 (5)数组做sizeof的参数不退化,传递给strlen会退化为指针。
16 C语言的关键字static和C++的关键字static有什么区别
C语言的static关键字可以修饰局部变量、全局变量、函数。
C++的static关键字除了局部变量、全局变量、函数之外,还可以修饰成员变量和成员函数。
17 volatile有什么作用
volatile通知编译器不要优化该变量,每次使用变量时,都从内存重新读取,而不是从寄存器读取备份。
常见的应用场景:
状态寄存器一类的并行设备硬件寄存器; 中断服务子程序会访问到的非自动变量; 多线程间被几个任务共享的变量。
18 一个参数可以既是const又是volatile吗
可以。const只是说明在此程序中该参数是只读的,并不是实际禁止这段内存的读写特性。它仍有可能在程序外部条件变化下改变。volatile通知编译器不要优化该变量,每次使用变量时,都从内存重新读取,而不是从寄存器读取备份。
19 全局变量和局部变量有什么区别?操作系统和编译器是怎么知道的?
区别: (1)全局变量定义在所有函数之外,定义位置之后均可使用。生命周期从程序运行到结束。 (2)局部变量定义在代码块中,仅在该代码块中可见。生命周期从定义位置到代码块结束。
操作系统和编译器应是根据内存中存储位置判断的。全局变量位于全局数据区,在程序运行时被加载。局部变量位于栈区。
20 简述strcpy、sprintf与memcpy的区别
(1)功能区别:
strcpy用于两个字符串之间的拷贝; sprintf用于将其他类型数据格式化为字符串; memcpy是在两块内存之间拷贝。
(2)操作对象区别:
strcpy的两个操作对象均为字符串; sprintf的源对象可以是多种类型,目标对象是字符串; memcpy的两个操作对象均是内存地址
(3)效率区别: memcpy效率最高,strcpy次之,sprintf效率最低。
21 请解析((void ()( ) )0)( )的含义
22 C语言的指针和引用和c++的有什么区别?
(1)C语言没有引用的概念。 (2)指针本身占用内存,引用则是其他对象的别名,不占用内存。 (3)sizeof作用于指针,结果为4。sizeof作用于引用,结果是其所指对象的大小。 (4)指针有顶层const和底层const,引用只有底层const。 (5)非顶层const的指针可以修改,引用则不能修改; (6)指针可以二级,引用则只能有一级; (7)通过指针操作所指对象需要先解引用,引用则可以直接操作。 (8)对指针执行加法,会造成所指内存地址偏移。对引用执行加法,会导致其所指对象的数值改变。 (9)如果返回动态内存分配的对象或内存,必须使用指针。引用可能导致内存泄露。
23 typedef和#define有什么区别
(1)typedef通常用于定义数据类型别名,以增强程序可读性。#define则常用于定义常量、宏函数等。 (2)typedef在编译阶段处理,#define则在预处理阶段替换。typedef会进行类型检查,#define没有类型检查; (3)typedef有作用域限制,#define没有作用域限制,在其声明后的使用都是正确的。 (4)typedef和#define对指针的操作有很大区别。
24 指针常量与常量指针区别
指针常量是顶层const。指该指针本身是常量,不能修改其所指的地址,但可以通过该指针修改其所指内存中的数据。
常量指针是底层const。该指针所指的地址可以改变,但不能通过该指针修改其所指内存中的数据。
25 简述队列和栈的异同
队列和栈都是线性存储结构。区别在于队列是先进先出,栈是后进先出。
26 设置地址为0x67a9 的整型变量的值为0xaa66
int *p = (int *)0x67a9;
*p = 0xaa66;
在任何硬件平台上,地址长度和整型变量的长度都是相同的。因此,整型数据可以强制转换为地址使用。
27 C语言的结构体和C++的有什么区别
(1)C语言的结构体中不能定义成员函数; (2)C语言的结构体中没有访问说明符,不存在权限的概念。 (3)C语言的结构体没有继承关系。
28 如何避免“野指针”
(1)定义指针时执行初始化。如不明确应指向哪个对象,则初始化为nullptr。 (2)指针所指的对象被delete释放后,应将指针赋值为nullptr。 (3)指针所指变量的作用域结束前,释放变量并将指针赋值为nullptr。
29 句柄和指针的区别和联系是什么?
Windows操作系统用句柄来表示系统资源,是unsigned int类型。指针则是指向内存地址。两者是不同的概念。
30 说一说extern“C”
extern "c"添加在头文件中,作用是使编译器按C语言方式来编译代码,正确实现C++语言对C语言的调用。
31 C++的顶层const和底层const ?
顶层const:对象本身是常量。
底层const:所指对象是常量。
以指针为例说明。
顶层const:指针指向的地址是固定的,但该地址中的数据可以修改。 底层const:指针指向的地址可以改变,但不能通过该指针来改变所指地址内保存的数据。
32 栈区和堆区的区别?栈区和堆栈的区别?
栈区由编译器分配、释放。主要用于存储局部变量、函数参数等。堆区由编程者手动申请、释放。主要用于动态内存操作。
栈区、堆区和堆栈是两个层面的概念。栈区、堆区指的是内存的分区,堆栈指的是一种数据结构。
这篇关于【面试题】【C++】01-C++语法部分面试题的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!