第2章 C++相关知识(一)

2.1 C和C++区别(有了C语言为什么还要C++?)

C语言是面向过程语言,而C++是面向对象语言。

1. 编程范式

  • C 语言(面向过程编程):
  • 面向过程编程(Procedure-Oriented Programming)是一种基于函数的编程方式,程序被视为一个由数据和操作数据的函数组成的集合。开发人员通过编写多个函数来完成程序任务,然后按照步骤(流程)依次调用这些函数。
  • 在 C 语言中,开发者必须通过明确的函数调用来控制程序的执行流,数据和函数是分离的,函数操作的是数据,代码的结构主要是围绕函数展开的。

  • C++ 语言(面向对象编程)
  • 面向对象编程(Object-Oriented Programming, OOP)是一种更高层次的编程范式,它将程序组织为对象的集合。每个对象是数据和操作这些数据的函数的结合体。通过创建类和对象,面向对象编程强调数据的封装、继承、多态和抽象。
  • 在 C++ 中,程序不仅仅是函数的集合,而是由具有属性和方法的对象组成。对象和类的概念使得程序设计更符合实际世界的模拟。

2. 数据和函数的关系

  • C 语言:数据和操作数据的函数是分离的。在 C 语言中,数据和函数是独立的,数据由全局或局部变量存储,函数通过参数传递数据进行操作。
  • C++ 语言:数据和操作数据的函数被封装在一起。C++ 引入了类的概念,类不仅包含数据成员(属性),还包含操作这些数据的成员函数(方法)。类提供了一种自然的方式来组织和操作数据。

3. 面向对象的特性(封装、继承、多态)

  • C 语言:C 语言不支持面向对象的特性。它只是一个过程化的语言,无法直接支持类和对象的创建、继承、方法重写等功能。
  • C++ 语言:C++ 支持面向对象编程,并且引入了类、对象、继承、多态等重要特性。封装:类把数据和操作数据的函数封装在一起,提供良好的数据保护。继承:类可以继承其他类的特性和行为,促进代码的复用。多态:通过虚函数和动态绑定,C++ 实现了运行时多态,使得不同类型的对象可以以统一的接口进行操作。

4. 内存管理

  • C 语言:C 语言使用 malloc() 和 free() 函数来进行动态内存管理,手动分配和释放内存,容易出错,如内存泄漏和访问无效内存。
  • C++ 语言:C++ 引入了 new 和 delete 运算符来进行内存的动态分配和释放。new 和 delete 提供了更简单的语法,同时也支持对象的构造和析构。C++ 的内存管理可以通过类的构造函数和析构函数来自动处理资源的分配和释放。

5. 函数重载与运算符重载

  • C 语言:C 语言不支持函数重载,也不支持运算符重载。在 C 中,如果你需要多个具有相似功能的函数,它们的名字必须不同,且类型必须明确指定。
  • C++ 语言:C++ 支持函数重载(同名不同参数的多个函数)和运算符重载(自定义运算符的行为)。这使得 C++ 具有更高的灵活性和扩展性。

示例(函数重载):

  • 函数重载允许我们定义多个相同名字的函数,但每个函数的参数类型或数量必须不同。编译器根据传递的参数类型来决定调用哪个版本的函数。
  • 在上述代码中,print 函数通过接受不同类型的参数(整数、浮点数和字符串)实现了重载。通过这种方式,我们可以利用相同的函数名执行不同类型的打印操作,增强了代码的可读性和可维护性。
  • 6. 标准库

    • C 语言:C 标准库提供了基本的输入输出、字符串操作、内存管理、数学等功能,如 stdio.h、stdlib.h 等头文件。
    • C++ 语言:C++ 标准库不仅包含了 C 语言的标准库,还引入了如标准模板库(STL)等强大的工具。STL 提供了如容器(vector、list)、算法(sort、find)等常用的类和函数,使得 C++ 更加高效和灵活。

    总结

    总体来说,C++ 是在 C 的基础上引入了面向对象编程的特性,同时保留了 C 的面向过程的特性,这使得 C++ 既可以进行高效的系统编程,也可以进行灵活的面向对象设计。

    2.2 new和malloc的区别

    在 C++ 中,new 和在 C 语言中的 malloc 都用于动态内存分配,但它们的原理、用法以及其他方面有一些显著的不同。

    1. 定义与原理

    • new:
    • new 是 C++ 的关键字,用于动态分配内存并创建对象。
    • 它不仅分配内存,还会自动计算所需内存空间,并调用对象的构造函数进行初始化。
    • 使用 new 分配内存时,内存块的类型已经确定,因此无需手动指定内存大小。
    • 分配的内存可以是基本数据类型的内存,也可以是对象的内存。
    • 当使用 new 分配内存时,必须使用 delete 来释放内存,否则会造成内存泄漏。
    • malloc:
    • malloc 是 C 语言的库函数,用于动态分配一块指定大小的内存块。
    • malloc 只分配内存,不会初始化内存的内容,返回的是 void* 类型指针,需要手动强制类型转换。
    • malloc 只关心内存的大小,并不关心内存所存储的数据类型。
    • 返回的内存块是未初始化的。
    • 使用 malloc 分配的内存必须通过 free 来释放,防止内存泄漏。

    2. 语法

    • new 语法:

    • malloc 语法:

    3. 类型安全

    • new:new 是类型安全的,编译器根据数据类型自动计算所需内存空间,并返回对应类型的指针。不需要手动指定内存的大小,且返回的是已指定类型的指针。
    • malloc:malloc 返回的是 void* 类型指针,这意味着它不具备类型信息,因此必须手动进行类型转换。如果直接在 C++ 中使用 malloc,需要强制转换返回的 void* 指针为正确类型。
    • 示例(malloc 使用)

      4. 构造函数与析构函数的调用

    • new:new 会自动调用对象的构造函数来初始化对象,因此创建的对象是已初始化的。对象销毁时会调用析构函数,释放资源。
    • malloc:malloc 不会调用构造函数。它只是为数据分配内存,分配的内存是未初始化的。对象的构造和析构需要手动处理。

    示例(构造函数与析构函数的调用):

  • 构造函数MyClass() 是一个默认构造函数,当对象创建时被调用。它打印 Constructor called! 来表明对象的构造过程。
  • 析构函数~MyClass() 是析构函数,当对象销毁时被自动调用。它打印 Destructor called! 来表示对象的销毁过程。
  • MyClass* obj = new MyClass();:这行代码使用 new 操作符来创建 MyClass 类型的对象 objnew 不仅分配内存,还调用 MyClass 的构造函数初始化对象。
  • delete obj;:这行代码使用 delete 操作符来销毁对象 obj,并自动调用析构函数,释放该对象占用的内存。
  • 5. 内存分配失败的处理

    • new:当 new 分配内存失败时,它会抛出一个 std::bad_alloc 异常。因此,可以通过异常处理来捕获内存分配失败的情况。
    • malloc:当 malloc 分配内存失败时,它会返回 NULL,需要程序员手动检查返回值,确保内存分配成功。

    示例(malloc 内存分配失败处理):

    6. 重载与自定义类型

    • new:
    • new 可以被重载,允许开发者自定义内存分配行为。例如,可以重载 new 操作符来定制内存池管理。
    • new 也能够与自定义类型的构造函数和析构函数配合使用。
    • malloc:
    • malloc 是 C 标准库中的函数,不能被重载。
    • 它不能调用对象的构造函数或析构函数,因此不能与自定义类型的生命周期管理直接结合。

    7. 内存管理和类型转换

    • new:new 和 delete 配对使用,内存管理更加直观和安全。new 可以根据类型自动计算内存大小,并且返回正确的类型指针。
    • malloc:malloc 和 free 配对使用,手动进行内存管理。必须使用 sizeof 来计算所需内存大小,并且必须进行强制类型转换。

    总结:newmalloc 的比较

    2.3 结构体和共用体的区别

    结构体:

    • 成员在内存中独立存储,每个成员占用独立的内存空间。

    • 内存占用是成员之和,每个成员都占用独立的空间。

    • 成员可以同时被访问,通过成员名字来访问。

    • 适合存储和处理多个不同类型的数据,如员工信息、图形对象等。

    • 对于结构体的不同成员赋值,对结构体的其他成员不受影响

    共用体:

    • 成员共享同一块内存空间,只能存储一个成员的值。

    • 内存占用是最大成员的大小,所有成员共享该空间。

    • 成员只能同时访问其中的一个,存取时要明确指定。

    • 适合存储和处理只使用其中一种类型的数据,可以节省内存空间或进行数据类型转换。

    • 对于联合体的不

    剩余60%内容,订阅专栏后可继续查看/也可单篇购买

    作者简介:仅用大半年时间0基础天坑急转嵌入式开发,逆袭成功拿下华为、vivo、小米等15个offer,面试经验60+,收藏20+面经,分享自己的求职历程与学习心得。 专栏内容:最新求职与学习经验,详细讲解了嵌入式开发的学习路径、项目经验分享、简历优化技巧、面试心得及实习经验,从测评,笔试,技术面,HR面,AI面,主管面,谈薪一站式服务,助你突破技术瓶颈、打破信息差,争取更多大厂offer。

    全部评论
    好强
    点赞 回复 分享
    发布于 02-24 16:34 浙江
    C和C++区别讲得好
    点赞 回复 分享
    发布于 02-24 18:33 浙江
    结构体共用体对比实用
    点赞 回复 分享
    发布于 02-24 18:48 浙江
    都是手打的咩
    点赞 回复 分享
    发布于 02-25 15:48 浙江
    点赞 回复 分享
    发布于 02-25 15:48 浙江

    相关推荐

    秋招拖延offer的3个实用话术金九银十的秋招季已经过去大半,有些同学可能已经收到了心仪的offer,而有些同学还在犹豫,想要再看看有没有更合适的。那么,如何措辞才能巧妙地拖延offer呢?以下是一些实用的话术:理由1:与父母沟通型话术1:您好,收到贵公司的offer非常荣幸,贵公司的发展前景和公司文化我都非常看好,与我的所学专业也很契合。目前我还没有和家里沟通,等我和家里沟通之后第一时间给您答复(这个时候一般可以拖2-5天,只要单位不催你,你就可以装死)。话术2:您好,这几天和家里沟通了贵单位的基本情况,家里各方面都挺满意的,但由于通勤较远(可替换其他原因)家里有点担心,想问问您公司有没有市内通勤车或者人才公寓呢(这里不管他回答什么,你都可以往下接)?我再和家里商量一下,三天内给您答复(这次如果催得紧最好说个时间,让公司感受到你的诚意)。理由2:系统故障型话术1:您好,我们学校的签约系统是网签。由于近期收到offer的同学还不是太多,所以我们学院的三方系统还没有开放,问过就业的老师,答复是近期会开放,开放之后第一时间联系您(中间不催你的话,可以装死,催的话就说联系老师问一下,基本可以拖一周—半个月)。话术2:您好,我们学校的签约系统是网签。但是就业处的老师说最近的系统出了点问题正在加急维护,维护好发通知后第一时间联系您(道理同上)。理由3:老师有事型话术1:您好,签约三方需要老师系统进行操作,学院老师说每个月的月中(月末)统一处理,处理好了之后联系您,您看看公司那边还有什么需要我注意的吗?话术2:您好,签约三方需要老师系统进行操作,负责就业的老师最近两周请了事假,再加上最近收到offer的同学并不太多,所以她回来到岗后才会统一处理。写在最后:拖延重在随机应变,每个环节都可以拖延。从公司给你发了offer的那一刻开始,主动权就已经到了各位同学的手中,只是各位同学要拿捏好尺度。举个不恰当的例子有点像钓鱼🎣,又不能让🐟跑了,又不要一下就钓上来。从工资待遇开始商量,到家里是否支持,到个人的其他考虑,从学校的三方合同拟定,到系统发放,再到学校审核,老师签字,这当中的每一个环节都至少可以拖2-3天。当然了,并不是让各位同学有意撒谎,只是希望各位同学都能签到最心仪的,最适合自己的offer。最后呢祝各位同学工作顺利,关注我分享更多面试知识,嵌入式c++的同学可以看一下大佬总结的面经https://www.nowcoder.com/creation/manager/columnDetail/MJNwoM
    点赞 评论 收藏
    分享
    评论
    7
    4
    分享

    创作者周榜

    更多
    牛客网
    牛客企业服务