【C++】01.基础、函数、封装
【嵌入式八股】一、语言篇(本专栏)https://www.nowcoder.com/creation/manager/columnDetail/mwQPeM
【嵌入式八股】二、计算机基础篇https://www.nowcoder.com/creation/manager/columnDetail/Mg5Lym
【嵌入式八股】三、硬件篇https://www.nowcoder.com/creation/manager/columnDetail/MRVDlM
【嵌入式八股】四、嵌入式Linux篇https://www.nowcoder.com/creation/manager/columnDetail/MQ2bb0
C++
相关基础
01.C++和C语言的区别
- 面向对象编程支持:C++是一种支持面向对象编程的语言,而C语言不支持面向对象编程。
- 类型检查:C++中有更加严格的类型检查,相对于C语言来说更加严格。
- 标准库:C++标准库中包含了很多C语言中没有的特性,如容器、迭代器、算法等。
- 多重继承:C++支持多重继承,而C语言不支持。
- 异常处理:C++中支持异常处理机制,而C语言没有提供。
- 函数重载:C++支持函数重载,即可以定义具有相同名称但参数类型和数量不同的多个函数,而C语言不支持函数重载。
- 操作符重载:C++中可以对操作符进行重载,以实现自定义的操作符行为,而C语言不支持操作符重载。
- 名字空间:C++中支持名字空间,可以避免命名冲突,而C语言不支持名字空间。
- 模板:C++支持模板,可以实现泛型编程,而C语言不支持模板。
02.C++和C语言函数调用的区别
- 函数原型声明:在C语言中,函数的原型声明是可选的,但在C++中,函数的原型声明是强制性的。在C++中,函数必须在使用之前进行原型声明或定义,以便编译器能够正确地进行类型检查和函数调用。
- 函数重载:C++支持函数重载,这意味着您可以定义具有相同名称但参数列表不同的多个函数。这样,编译器可以根据函数调用时的参数类型和数量来选择正确的函数。而在C语言中,函数重载是不允许的,因为C语言只根据函数名称来进行函数调用的解析。
- 默认参数:C++允许在函数声明中指定默认参数值,这意味着您可以为函数的某些参数提供默认值。在函数调用时,如果没有为这些参数提供值,则将使用默认值。而在C语言中,不支持默认参数。
- 类成员函数:C++中的函数可以作为类的成员函数。这些函数可以通过使用类的实例来调用,并且可以访问类的成员变量和其他成员函数。这是面向对象编程的一个重要特性,而在C语言中是不支持的。
03.C++和C语言代码存储的区别
C++和C语言在代码存储方面没有本质的区别,因为它们都使用文本文件来存储源代码。源代码文件通常使用以.cpp
为扩展名的文件来表示C++代码,以.c
为扩展名的文件来表示C代码。
然而,C++语言相对于C语言在编译和链接过程中有一些特定的要求和约定。以下是一些相关的区别:
-
文件扩展名:C++代码文件通常使用
.cpp
扩展名,而C代码文件使用.c
扩展名。虽然大多数编译器能够编译和链接C代码文件,但为了明确表示代码文件的类型,使用正确的文件扩展名是一种良好的实践。 -
链接器:在C++中,由于支持函数重载和类的成员函数等特性,C++编译器在链接过程中可能需要处理更复杂的符号解析和符号表生成。这可能导致在C++代码中使用外部库或模块时需要更多的链接器指令或配置。
-
兼容性:C++语言是C语言的超集,这意味着C++编译器可以编译和链接C代码。因此,C语言的代码可以在C++编译器中进行编译和执行。但是,C++引入了一些新的关键字和特性,这可能会导致在C++编译器中编译时出现错误。
总的来说,C++和C语言的代码存储没有太大的区别,都是使用文本文件来存储源代码。但在编译和链接过程中,C++的一些特定要求和语法可能会导致在处理C++代码时需要更多的配置和注意事项。
04.C++和Python的区别
- 编程范式:C++是一种多范式编程语言,支持面向对象编程、泛型编程和过程化编程,而Python主要是一种面向对象编程语言。
- 静态类型和动态类型:C++是静态类型语言,需要在编译时声明变量类型,而Python是动态类型语言,变量类型在运行时被确定。
- 性能:C++的性能通常比Python更好,因为C++是编译型语言,可以生成本地机器代码,而Python是解释型语言,需要解释器解释执行。
- 可移植性:Python在不同平台上运行时,代码可以不做任何修改。而C++需要对每个平台重新编译。
- 语法:C++语法比Python更为严格和复杂,需要更多的编码技巧和经验,而Python语法简单易懂,易于学习和使用。
- 库:C++标准库提供了许多底层的操作,而Python的标准库提供了许多高层次的操作,如文件读写、正则表达式等。
- 错误处理:C++通过异常机制来处理错误,而Python使用异常和返回值来处理错误。
C++和Python有不同的优势和适用场景。C++适用于对性能和内存要求较高的场合,如游戏、嵌入式系统等;而Python适用于快速开发和简单易用的场合,如数据科学、Web应用程序、自动化脚本等。
05.C++与Java的区别
- 编程范式:C++是一种多范式编程语言,支持面向对象编程、泛型编程和过程化编程,而Java是一种面向对象编程语言。
- 静态类型和动态类型:C++是静态类型语言,需要在编译时声明变量类型,而Java是动态类型语言,变量类型在运行时被确定。
- 性能:C++的性能通常比Java更好,因为C++是编译型语言,可以生成本地机器代码,而Java是解释型语言或者是JIT编译器编译后的字节码,需要在虚拟机中解释执行。
- 内存管理:C++程序员需要手动管理内存,包括分配、释放、回收等。而Java使用自动内存管理,即垃圾回收器自动回收不再使用的内存。
- 平台依赖性:C++需要对每个平台重新编译,而Java通过虚拟机的存在,实现了跨平台的编程。
- 异常处理:C++通过异常机制来处理错误,而Java使用异常和返回值来处理错误。
- 多线程:Java内置了多线程支持,而C++需要使用操作系统提供的多线程API。
C++和Java有不同的优势和适用场景。C++适用于对性能和内存要求较高的场合,如游戏、嵌入式系统等;而Java适用于需要跨平台、大规模并发的场合,如企业级应用程序、网络应用等。
06.为什么C++没有垃圾回收机制?这点跟Java不太一样。
C++没有内置的垃圾回收机制是因为它是一种系统级语言,设计的初衷是为了提供高性能和底层控制能力。垃圾回收机制会带来一定的性能损失,并且无法提供和手动内存管理相同的灵活性和精细控制。
相比之下,Java是一种基于虚拟机的语言,它的垃圾回收机制是由虚拟机来实现的。虚拟机可以根据应用程序的内存使用情况动态调整垃圾回收策略,以平衡性能和内存占用。
虽然C++没有内置的垃圾回收机制,但是可以使用智能指针等工具来辅助管理内存,同时也可以使用第三方库来实现垃圾回收功能。此外,现代C++标准中还提供了一些新特性,如move语义和右值引用,可以更方便地管理资源,减少内存泄漏等问题。
总之,C++没有内置的垃圾回收机制是为了保证高性能和灵活性,但是开发人员需要自行负责管理内存,这需要一定的经验和技能。
面向对象
07.面向对象和面向过程有什么区别?
面向对象编程强调的是数据和方法的封装,即将数据和相关的操作封装在一起,形成一个对象。面向对象编程的核心是类(Class)和对象(Object)的概念,通过类定义对象的属性和方法,然后通过实例化对象来进行操作。面向对象编程可以更好地抽象出现实世界的问题,并且代码的复用性和可维护性更强。
相比之下,面向过程编程则更强调程序的执行流程,即将程序的执行分解成一系列的函数或者过程,通过函数之间的调用来实现程序的功能。面向过程编程中的函数接受输入数据并返回输出数据,主要关注解决问题的步骤和方法。
08.面向对象的基本特征有哪些?
介绍面向对象的三大特性
三大特性:继承、封装和多态
四个基本特征:
- 封装 (Encapsulation):将数据和相关操作封装在一个对象中,只对外部暴露必要的接口,保证了数据的安全性和完整性。
- 继承 (Inheritance):允许在一个已有类的基础上创建一个新的类,并继承原有类的属性和方法。这样可以避免重复编写代码,同时也方便了代码的维护和修改。
- 多态 (Polymorphism):允许不同的对象对同一消息做出不同的响应,即同一方法可以在不同的对象中有不同的实现。这样可以增强代码的灵活性和可扩展性。
- 抽象 (Abstraction):将具有相似属性和行为的对象抽象成一个类,隐藏不必要的细节,只保留必要的属性和方法。这样可以使代码更加清晰、简洁、易于理解和维护。
09.面向对象与泛型编程是什么?
面向对象编程强调的是数据和方法的封装,即将数据和相关的操作封装在一起,形成一个对象。面向对象编程的核心是类和对象的概念,通过类定义对象的属性和方法,然后通过实例化对象来进行操作。面向对象编程可以更好地抽象出现实世界的问题,并且代码的复用性和可维护性更强。
而泛型编程则强调编写能够适用于多种数据类型的代码。泛型编程通过使用类型参数化的方式实现,即在编写代码时使用类型参数来表示待处理数据的类型,从而可以使得代码在不改变其功能的情况下适用于多种数据类型。
函数
10.C++提供默认参数的函数吗?
C++提供默认参数的函数。默认参数是指在函数声明中为参数提供一个默认值,如果调用函数时未提供该参数的值,则该参数将采用其默认值。默认参数可以帮助简化函数的调用,因为它允许调用者省略部分参数,而不需要在每个调用点都提供参数。
以下是一个使用默认参数的函数的示例:
void printMessage(std::string message = "Hello, World!")
{
std::cout << message << std::endl;
}
在这个例子中,printMessage()函数具有一个名为message的参数,并且该参数具有默认值"Hello, World!"。如果调用该函数时未提供参数,则会使用默认值输出消息。例如,以下调用将输出"Hello, World!":
printMessage();
如果提供了参数,则将使用提供的参数值。例如,以下调用将输出"Hello, C++!":
printMessage("Hello, C++!");
注意:
- 函数声明和实现只能有一个默认参数,不能重复定义默认参数。
- 如果某个形参有了默认参数,则位于这个形参之后的所有形参都要有默认参数。
- 有了默认参数,仍然可以传递实参,这样形参的值按照传递的实参优先。
void func(int a, int b = 1, int c = 2); // Valid
void func(int a = 0, int b, int c); // Invalid
11.C++中的重载、重写(覆盖)和隐藏的区别
(1)重载(overload)
重载是指在同一范围定义中的同名成员函数才存在重载关系。主要特点是函数名相同,参数类型和数目有所不同,不能出现参数个数和类型均相同,仅仅依靠返回值不同来区分的函数。重载和函数成员是否是虚函数无关。重载函数可以是成员函数或全局函数。重载可以实现静态多态性(编译时多态)。举个例子:
class A{
...
virtual int fun();
void fun(int);
void fun(double, double);
static int fun(char);
...
}
(2)重写(覆盖)(override)
重写指的是在派生类中覆盖基类中的同名函数,重写就是重写函数体,要求基类函数必须是虚函数且:
- 与基类的虚函数有相同的参数个数
- 与基类的虚函数有相同的参数类型
- 与基类的虚函数有相同的返回值类型
重写只能是成员函数,且必须使用虚函数的关键字来声明。重写可以实现动态多态性(运行时多态)。
举个例子:
//父类
class A{
public:
virtual int fun(int a){}
}
//子类
class B : public A{
public:
//重写,一般加override可以确保是重写父类的函数
virtual int fun(int a) override{}
}
重载与重写(覆盖)的区别:
- 重写是父类和子类之间的垂直关系,重载是同一个类之间不同函数之间的水平关系
- 重写要求参数列表相同,重载则要求参数列表不同,返回值不要求
- 重写关系中,调用方法根据对象类型(对象对应存储空间类型)决定,重载根据调用时实参表与形参表的对应关系来选择函数体
(3)隐藏(hide)
隐藏指的是某些情况下,派生类中的函数屏蔽了基类中的同名函数,隐藏可以是成员函数或全局函数。隐藏不是多态性的一种形式,因为它不会在运行时调用正确的函数。包括以下情况:
- 两个函数参数相同,但是基类函数不是虚函数。**和重写的区别在于基类函数是否是虚函数。**举个例子:
//父类
class A{
public:
void fun(int a){
cout << "A中的fun函数" << endl;
}
};
//子类
class B : public A{
public:
//隐藏父类的fun函数
void fun(int a){
cout << "B中的fun函数" << endl;
}
};
int main(){
B b;
b.fun(2); //调用的是B中的fun函数
b.A::fun(2); //调用A中fun函数
return 0;
}
- 两个函数参数不同,无论基类函数是不是虚函数,都会被隐藏。和重载的区别在于两个函数不在同一个类中。举个例子:
//父类
class A{
public:
virtual void fun(int a){
cout << "A中的fun函数" << endl;
}
};
//子类
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
查阅整理上千份嵌入式面经,将相关资料汇集于此,主要包括: 0.简历面试 1.语言篇【本专栏】 2.计算机基础 3.硬件篇 4.嵌入式Linux (建议PC端查看)