当前位置: 首页 > 科技观察

C语言和C++的区别和联系

时间:2023-03-13 23:45:40 科技观察

C语言和C++有什么关系?首先,C++和C语言本来就是两种不同的编程语言,但是C++确实是C语言的扩展和延伸,它为C语言提供了向后兼容性。有人说C++完全包含了C语言,这没有错。C++最初由BjarneStroustrup发明时,最初被称为“CwithClasses”,意思是“Cwithclasses”。显然,它在C语言的基础上扩展了类等面向对象的特性和机制。但经过逐步修改和多次演化,最终形成了支持一系列主要特性的庞大编程语言。1、C语言是面向过程的语言,C++是面向对象的语言。我们都知道C语言是面向过程的语言,而C++是面向对象的语言。C和C++的区别就是比较面向过程和面向对象的区别。(1)面向过程和面向对象的区别面向过程:面向过程编程就是分析解决问题的步骤,然后一步一步地实现这些步骤,在使用的时候一一调用。面向对象:面向对象编程就是把问题分解成各种对象。建立对象的目的不是为了完成一个步骤,而是为了描述某事物在整个求解步骤中的行为。(2)面向过程和面向对象的优缺点面向过程语言的优点:比面向对象的性能更高,因为调用时需要实例化类,开销比较大,比较耗资源;如单片机、嵌入式开发、Linux/Unix等。面向过程开发,性能是最重要的因素。缺点:不面向对象,易维护,易复用,易扩展面向对象语言优点:易维护,易复用,易扩展,因为面向对象具有封装,继承,多态的特点,可以设计一个低耦合的系统,让系统更灵活,更容易维护缺点:性能比面向过程低。2.特定语言的差异1。不同的关键字。C语言有32个关键字;C++有63个关键字;2.后缀不同。C源文件后缀.c,C++源文件后缀.cpp,在VS中,如果创建源文件时不指定,默认为.cpp。3、返回值在C语言中,如果一个函数没有指定返回值类型,则默认返回int类型;在C++中,如果函数不返回值,则必须将其指定为void。4、参数列表在C语言中,当一个函数没有指定参数列表时,默认可以接收任意数量的参数;但在C++中,由于严格的参数类型检测,没有参数列表的函数默认为void,不接收任何参数。.5、默认参数默认参数是在声明或定义函数时,为函数的参数指定一个默认值。调用函数时,如果没有指定实参,则使用默认值,否则使用指定的参数。(C语言不支持默认参数)·半默认参数·全默认参数注意:·在半默认情况下,具有默认值的参数必须放在参数列表的末尾。·默认参数不能同时出现在函数声明和函数定义中,只能选择其中之一。·默认值必须是常量或全局变量。·默认参数必须按值或常量传递。6.函数重载函数重载:函数重载是函数的一种特例,是指在同一作用域内声明多个具有相似功能的同名函数,形参列表(参数个数、类型、顺序)必须不同,返回值类型可以相同也可以不同,常用于处理相似函数不同数据类型的问题。(C语言没有函数重载,C++支持函数重载)。C语言中函数符号的生成规则是根据名字来的,也就是说C语言中没有函数重载的概念。当C++生成函数符号时,它会考虑函数名称、参数数量和参数类型。需要注意的是,函数的返回值不能作为函数重载的依据,也就是说intsum和doublesum这两个函数不能构成重载!我们的函数重载也是一种多态,叫做静态多态。静态多态:函数重载、函数模板动态多态(运行时多态):继承多态(虚函数)。使用重载时,需要注意范围问题:请看下面的代码。我在全局范围内定义了两个函数。由于不同的参数类型,它们可能会被重载。这时main函数中的调用就可以正确调用各自的函数了。但是看看主函数中被注释掉的代码行。如果你把它放出来,你会被警告:将double类型转换为int类型可能会丢失数据。这意味着我们的编译器为以下两个调用调用参数类型为int的比较。可以看出,编译器在调用一个函数时,首先在局部范围内进行搜索,如果搜索成功,则所有的调用都按照函数的标准进行。如果找不到,则会在全局范围内搜索。总结:C语言中没有函数重载。C++根据函数名的参数个数和参数类型来判断重载。属于静态多态,必须在同一个作用域下调用重载。7.在constC语言中,被const修饰的变量不是常量。它们被称为常量变量或只读变量。此常量变量不能用作数组下标。但是C++中const修饰的变量可以作为数组下标,成为实常量。这是C++对const的扩展。C语言中的const:修饰后不能作为左值使用,也不能初始化,但之后没有机会重新初始化。不能作为数组的下标,可以通过指针修改。简单的说,它和普通变量的区别就是不能是左值,其他地方也一样。C++中的const:实常数。定义时必须初始化,可以作为数组的下标。C++中const的编译规则是替换(很像宏),所以被当做一个真正的常量。也可以通过指针修改。需要注意的是,C++指针有可能退化为C语言指针。比如下面这种情况:此时a只是一个普通的C语言const常量变量,不能再作为数组下标使用。(指编译阶段不确定的值)const是生成符号时的局部符号。也就是说,它仅在本文档中可见。如果非要在其他文件中使用,在文件头声明:externcosntintdata=10;生成的符号是全局符号。总结:const在C中称为只读变量,但不能是左值变量;C++中的const是真正的常量,但在C语言中可能退化为常量,默认生成局部符号。8.References一提到引用,我们的第一反应就是想到他的弟弟:指针。引用在底层和指针是一样的东西,但是它的特性和编译器里面的指针是完全不同的。首先定义一个变量a=10,然后我们分别定义一个引用b和一个指向a的指针p。我们转反汇编看看底层实现:可以看到底层实现是一模一样的,取a的地址放入eax寄存器,然后将eax中的值存入引用b/指针的内存中p.到目前为止,我们可以说(在幕后)引用本质上是一个指针。了解了底层实现,我们再回到编译器。我们看到修改a的值,指针p的方法是*p=20;也就是说,该值在取消引用后被替换。再来看引用修改:我们看到修改a的值的方法是一样的,也是解引用。只是我们调用的时候不一样:*p调用p的时候需要解引用,b可以直接使用。由此我们推断,当直接使用时,引用是指针解引用。p直接使用的是自己的地址。这样我们也就明白了,我们开辟出来供引用的内存是根本无法访问的。如果直接使用,则直接解引用。即使打印&b,输出的也是a的地址。这里有一个将指针转换为引用的小技巧:int*p=&a,我们将引用符号向左移动,替换为*:int&p=a。接下来我们看看如何创建数组引用:intarray[10]={0};//定义一个数组我们知道,如果把数组取出来使用,就是数组数组第一个元素的地址。也就是int*类型。那么&array是什么意思呢?int**类型是用来指向array[0]地址的一个地址吗?不要想当然,&array就是整个数组类型。然后定义一个数组引用,根据上面的提示,先写数组指针:int(*q)[10]=&array;用左边的*覆盖右边的&:int(&q)[10]=array;测试sizeof(q)=10。我们成功创建了数组引用。经过上面的详细解释,我们知道引用其实就是取地址。那么我们都知道一个立即数是没有地址的,也就是int&b=10;这样的代码。无法编译。那么如果只想引用一个立即数,其实也没有办法:constint&b=10;用const修改立即数就行了。为什么?这时候因为修改后的const会生成一个临时量来保存这个数据,自然也就有了地址。9、malloc,free&&new,delete的问题很有意思,也是需要注意的关键问题。malloc()和free()是C语言标准库中动态申请内存和释放内存的函数。new和delete是C++运算符和关键字。new和delete底层其实调用了malloc和free。它们之间的区别有以下几个方面:1)、malloc和free是函数,new和delete是操作符。2)、malloc需要分配内存前的大小,new不需要。例如:int*p1=(int*)malloc(sizeof(int));整数*p2=新整数;//int*p3=newint(10);malloc需要指定大小和类型转换。new的时候不需要指定size,因为可以从给定的类型判断,同时也可以赋初值。3)malloc不安全,需要手动类型转换,而new不需要类型转换。4)、free只释放空间,delete先调用析构函数再释放空间(必要时)。对应第5条,如果使用了复杂类型,先destruct再调用operatordelete回收内存。5)、new是先调用构造函数再申请空间(如果需要的话)。对应④项,当我们调用new时(比如int*p2=newint;这段代码),底层代码的实现是:先push4字节(int类型的大小),然后调用operatornew函数分配内存不足。由于我们的代码不涉及复杂类型(比如类类型),所以没有调用构造函数。下面是operatornew的源码,也是new实现的一个重要功能:我们可以看到,首先malloc(size)申请参数bytesize的内存,如果失败(malloc失败返回0),进入判断:如果_callnewh(size)也失败,则抛出bad_alloc异常。函数_callnewh()是检查新的处理程序是否可用。如果可用,则释放部分内存,然后返回malloc继续申请。如果新的处理程序不可用,则会抛出异常。6)内存不足(开发失败)时处理方法不同。如果malloc失败,则返回0,如果new失败,则抛出bad_alloc异常。7)、new和malloc开辟的内存位置不同。malloc分配在堆区,new分配在空闲存储区。8)、new可以调用malloc(),但是malloc不能调用new。new是用malloc()实现的,new是C++特有的,当然不能调用malloc。10.作用域C语言中只有两种作用域:局部作用域和全局作用域。在C++中,存在三种类型:局部作用域、类作用域和命名空间作用域。所谓命名空间就是命名空间,我们定义一个命名空间来定义一个新的作用域。访问时,需要通过如下方式访问(以std为例)std::cin<<"123"<