C和C++之间的区别和联系

 2024-03-17 03:03:28  阅读 0

星标/置顶 公众号,硬核文章第一时间送达!

C语言和C++有什么关系?

首先,C++和C语言本来是两种不同的编程语言,但C++确实是C语言的扩展和延伸,并且为C语言提供了向后兼容性。 有人说C++完全包含了C语言,这并没有错。

c++中引用和指针的区别_指针与引用_指针和引用都有const

C++最初由 ()发明时,最初被称为“C with”,即“带有类的C”。

很明显,它在C语言的基础上扩展了类等面向对象的特性和机制。 但后来,经过一步步的修改和多次演变,最终成为了今天支持一系列主要特性的庞大编程语言。

c++中引用和指针的区别_指针与引用_指针和引用都有const

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

我们都知道C语言是面向过程的语言,C++是面向对象的语言。 谈论C和C++的区别,就是比较面向过程和面向对象的区别。

(一)面向过程和面向对象的区别

面向过程:面向过程编程就是分析解决问题的步骤,然后一步步实现这些步骤。 使用时只需一一调用即可。

面向对象:面向对象编程就是将问题分解为各种对象。 建立对象的目的不是为了完成一个步骤,而是为了描述某个事物在整个解决问题的步骤中的行为。

指针和引用都有const_c++中引用和指针的区别_指针与引用

(二)面向过程和面向对象的优缺点

面向过程的语言

优点:性能比面向对象高,因为类调用需要实例化,比较昂贵,消耗资源; 比如单片机、嵌入式开发、Linux/Unix等一般都采用面向过程的开发,性能是最重要的因素。

缺点:非面向对象、易维护、易复用、易扩展

面向对象语言

优点:易维护、易复用、易扩展。 由于面向对象的封装、继承、多态等特点,可以设计出低耦合的系统,使系统更加灵活,更易于维护。

缺点:性能比面向过程低。

c++中引用和指针的区别_指针和引用都有const_指针与引用

2. 具体语言的差异

1、关键词的差异

C语言有32个关键字;

C++有63个关键字;

2、后缀名不同

C 源文件的后缀为 .c,C++ 源文件的后缀为 .cpp。 在VS中,如果创建源文件时不指定任何内容,则默认为.cpp。

3、返回值

C语言中,如果函数没有指定返回值类型,则默认返回int类型; 在C++中,如果函数没有返回值,则必须将其指定为void。

指针与引用_指针和引用都有const_c++中引用和指针的区别

4、参数表

在C语言中,当函数没有指定参数列表时,默认可以接收任意数量的参数; 但在C++中,由于严格的参数类型检测,没有参数列表的函数默认为void,不接收任何参数。

5、默认参数

默认参数在声明或定义函数时指定函数参数的默认值。 调用该函数时,如果没有指定实际参数,则使用默认值,否则使用指定的参数。 (C语言不支持默认参数)

·半默认参数

指针和引用都有const_指针与引用_c++中引用和指针的区别

·全部默认参数

指针与引用_指针和引用都有const_c++中引用和指针的区别

注意:

·半默认情况下,有默认值的参数必须放在参数列表的末尾。

·默认参数不能同时出现在函数声明和函数定义中。 您只能选择两者之一。

·默认值必须是常量或全局变量。

·默认参数必须通过值参数或常量参数传递。

6. 函数重载

函数重载:函数重载是函数的一种特例。 是指在同一作用域内声明多个具有相似功能的同名函数。 这些同名函数的形参列表(参数个数、类型、参数顺序)必须不同。 返回值类型可以相同也可以不同,常用于处理实现类似功能时不同数据类型的问题。 (C语言没有函数重载,C++支持函数重载)。

c++中引用和指针的区别_指针与引用_指针和引用都有const

C语言中函数符号的生成规则是基于名称的,这意味着C语言中不存在函数重载的概念。 当 C++ 生成函数符号时,它会考虑函数名称、参数数量和参数类型。 需要注意的是,函数的返回值不能作为函数重载的依据。 也就是说int sum和sum这两个函数不能构成重载!

我们的函数重载也是多​​态的一种,称为静态多态。

静态多态:函数重载、函数模板

动态多态性(运行时多态性):继承中的多态性(虚函数)。

使用重载时,需要注意范围问题:请看下面的代码。

指针与引用_指针和引用都有const_c++中引用和指针的区别

我在全局范围内定义了两个函数。 由于参数类型不同,它们可能会重载。 这时在主函数中调用时,就可以正确调用各个函数了。

但请看一下 main 函数中注释掉的代码行。 如果将其输出,则会发出警告:转换为 int 类型可能会丢失数据。

这意味着我们的编译器在接下来的两次调用中调用了参数类型int。 可以看出,编译器调用函数时,优先在局部作用域内进行搜索。 如果查找成功,就会按照函数的标准全部调用。 如果没有找到,就会在全局范围内查找。

总结:C语言中不存在函数重载。 C++根据函数名参数的数量和参数类型来确定重载。 属于静态多态,必须在同一作用域内才能称为重载。

c++中引用和指针的区别_指针和引用都有const_指针与引用

7.常量

C语言中const修饰的变量不是常量,而称为常量变量或只读变量。 该常量变量不能用作数组下标。 但在C++中,const修饰的变量可以作为数组下标,成为真正的常量。 这是C++中const的扩展。

C语言中的const:修改后不能用作左值。 不需要初始化,但是以后就没有机会再初始化了。 不能作为数组下标,可以通过指针修改。

简单来说,它与普通变量唯一的区别就是它不能是左值。 其他一切都一样。

C++ 中的 const:真正的常量。 定义时必须初始化,并且可以用作数组的下标。 C++中const的编译规则是替换(很像宏),因此它被视为真正的常量。 也可以通过指针来修改。 需要注意的是,C++指针可能会退化为C语言指针。 例如:

此时a只是C语言中的一个普通的const常变量,不能再作为数组下标了。 (指编译时未确定的值)

当const生成符号时,它是一个局部符号。 这仅在本文档中可见。 如果必须在其他文件中使用,请在文件头声明:int data = 10; 这样生成的符号就是一个符号。

总结:C中const称为只读变量,但不能用作左值变量; C++中的const是真正的常量,但在C语言中也可能退化为常量,默认生成局部符号。

c++中引用和指针的区别_指针和引用都有const_指针与引用

8. 报价

说起引用,我们的第一反应就是想到他的兄弟:指针。

在底层,引用和指针是一样的东西,但它的特性与编译器中的指针完全不同。

c++中引用和指针的区别_指针和引用都有const_指针与引用

首先定义一个变量a = 10,然后定义一个引用b和一个指向a的指针p。 我们通过反汇编来看看底层的实现:

指针和引用都有const_指针与引用_c++中引用和指针的区别

可以看到底层实现是完全一样的。 取出a的地址并将其放入eax寄存器中,然后将eax中的值存储到引用b/指针p的内存中。 此时我们可以说(在底层)引用本质上是一个指针。

现在我们了解了底层实现,我们回到编译器。 我们看到a的值被修改了。 指针p为*p = 20; 也就是说,该值在取消引用后被替换。

我们看一下参考修改:

我们看到修改a的值的方法是一样的,就是解引用。 只是我们在调用时不同:*p在调用p时需要解引用,而b可以直接使用。 由此我们推断,直接使用时该引用是指针取消引用。 如果直接使用p,它就是它自己的地址。

这样我们也就明白了,我们为引用而打开的内存根本无法访问。 如果直接使用的话,会直接解引用。 即使打印&b,输出的也是a的地址。

c++中引用和指针的区别_指针与引用_指针和引用都有const

这里有一个将指针转换为引用的技巧:int *p = &a。 我们将引用符号移至左侧并替换*:int &p = a。

接下来让我们看看如何创建对数组的引用:

intarray[10] = {0};//定义一个数组

我们知道,数组取出来使用的时候,是数组数组第一个元素的地址。 也就是int *类型。

那么 &array 是什么意思呢? int **类型是用来指向array[0]地址的地址吗? 不要想当然,&array 是整个数组类型。

然后要定义数组引用,请按照上面的提示操作,首先写入数组指针:

int(*q) [10] = &array;

用左侧的 * 覆盖右侧的 &:

int(&q)[10] = array;

test(q) = 10。我们成功创建了数组引用。

经过上面的详细解释,我们知道引用其实就是地址。那么我们都知道立即数是没有地址的,即

int&b = 10;

这样的代码无法编译。 因此,如果您只需要引用一个立即值,实际上您无能为力:

constint &b = 10;

只需用 const 修改这个立即数即可。 为什么?

这时候因为const修改的任何东西都会生成一个临时量来保存数据,自然就会有一个地址可用。

c++中引用和指针的区别_指针与引用_指针和引用都有const

9.,免费&&新,

这个问题很有趣,也是需要关注的关键问题。 ()和free()是C语言标准库中动态申请内存和释放内存的函数。 新的 and 是 C++ 运算符和关键字。 新的底层其实还是调用和自由的。 它们之间的区别如下:

1)、free是函数,new和是运算符。

2)分配内存之前需要大小,但new不需要。

例如:

int *p1 = (int *)malloc(sizeof(int));int *p2 = new int; //int *p3 = new int(10);

需要指定大小,还需要进行类型转换。 使用new时不需要指定大小,因为可以从给定的类型来判断,同时也可以指定一个初始值。

指针与引用_指针和引用都有const_c++中引用和指针的区别

3)不安全,需要手动类型转换。 New不需要类型转换。

4)、free仅释放空间,先调用析构函数再释放空间(如果需要)。

对应第5条,如果使用复杂类型,必须先析构,然后调用回收内存。

5)、new先调用构造函数,然后申请空间(如果需要的话)。

对应第四项,当我们调用new时(如int *p2 = new int;这段代码),底层代码的实现是:先压入4个字节(int类型的大小),然后调用new函数来分配内存。 由于我们的代码不涉及复杂类型(例如类类型),因此没有构造函数调用。 以下是new的源码,这也是new实现的一个重要功能:

指针和引用都有const_指针与引用_c++中引用和指针的区别

我们可以看到first(size)申请了参数字节大小的内存。 如果失败(失败返回0),则进入判断:if(size)也失败,抛出异常。 () 该函数检查new是否可用。 如果可用,就会释放部分内存,然后返回继续申请。 如果 new 不可用,则会抛出异常。

指针与引用_c++中引用和指针的区别_指针和引用都有const

6)内存不足(开发失败)时处理方式不同。

失败时返回 0,new 失败时抛出异常。

7) 新的和分配的内存的位置不同。

在堆区打开,new在空闲存储区打开。

8)、new可以调用(),但不能调用new。

new 是使用 () 实现的。 new是C++特有的,当然不能被调用。

10. 范围

C语言中只有两种作用域:局部作用域和全局作用域。 在C++中,存在三种类型:本地作用域、类作用域和命名空间作用域。

所谓命名空间,就是当我们定义一个命名空间的时候,也就定义了一个新的作用域。 访问时需要通过以下方式访问(以std为例)

std::cin<<"123" <

例如,我们有一个名为 data 的命名空间,其中包含一个名为 data 的变量。 如果我们想在其他地方使用数据,我们需要在文件头中声明:using::data; 这样data就会使用in中的值。但是声明每个符号不是很累吗?

指针和引用都有const_指针与引用_c++中引用和指针的区别

我们只需要使用; 导入所有符号。

这就是我们经常看到的使用std的情况; 方法。

不学C语言可以直接学C++吗?

前面说过,C++编程语言的第一个重要组成部分是“面向过程编程”,而这正是C语言老大哥的领域。 即使你从来没有学过C语言,刚刚开始学习C++,你也不应该逃脱“面向过程”的部分。

从理论上讲,不一定要先学C语言再学C++,但在有了C语言基础之后再学C++往往更有优势。 至少“过程式编程”部分可以熟悉。

结尾

2T程序员礼包发售,包含C/C++、Linux、Java、PHP、人工智能、单片机、树莓派等。

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码