C与C++的区别与联系

本篇博客对C与C++的区别与联系进行了整理。并对一些小的知识点进行了扩展。

首先我们先来看一看C/C++的联系

C/C++的联系:

  • C是C++的子集,C++兼容大部分的C语言的语法结构

C/C++的区别:

  • 我们都知道C是面向过程的语言,而C++是面向对象的语言。那这里我们就要知道什么是面向对象?

      面向对象是一种思想,是基于面向过程而言的,就是说面向对象是将功能等通过对象来实现,将功能封装进对象之中,让对象去实现具体的细节;这种思想是将数据作为第一位,而方法或者说是算法作为其次,这是对数据一种优化,操作起来更加的方便,简化了过程。面向对象有三大特征:封装、继承、多态,其中封装性指的是隐藏了对象的属性和实现细节,仅对外提供公共的访问方式,这样就隔离了具体的变化,便于使用,提高了复用性和安全性。对于继承性,就是两种事物间存在着一定的所属关系,那么继承的类就可以从被继承的类中获得一些属性和方法;这就提高了代码的复用性。继承是作为多态的前提的。多态是说父类或接口的引用指向了子类对象,这就提高了程序的扩展性,也就是说只要实现或继承了同一个接口或类,那么就可以使用父类中相应的方法,提高程序扩展性,但是多态有一点不好之处在于:父类引用不能访问子类中的成员。

特点:

1:将复杂的事情简单化。

2:面向对象将以前的过程中的执行者,变成了指挥者。

3:面向对象这种思想是符合现在人们思考习惯的一种思想。

2、面向对象的三大特征:封装,继承、多态

1.封装:只隐藏对象的属性和实现细节,仅对外提供公共访问方式

好处:将变化隔离、便于使用、提高复用性、提高安全性

原则:将不需要对外提供的内容隐藏起来;把属性隐藏,提供公共方法对其访问

2.继承:提高代码复用性;继承是多态的前提

注:

    子类中所有的构造函数都会默认访问父类中的空参数的构造函数,默认第一行有super()若无空参数构造函数,子类中需指定;另外,子类构造函数中可自己用this指定自身的其他构造函数。

3.多态:是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象

好处:提高了程序的扩展性

弊端:当父类引用指向子类对象时,虽提高了扩展性,但只能访问父类中具备的方法,不可访问子类中的方法;即访问的局限性。

前提:实现或继承关系;覆写父类方法。

  • C/C++的动态内存管理的方法不同,C是使用malloc/free函数,而C++是使用new/delete关键字(关于malloc/free和new/delete在知识点扩充里补充)
  • C++支持函数重载,而C语言不支持
  • C中的struct和C++中的class类也有区别,C++的类是C中没有的,C++可以使用C的类,并且C++对struct进行了进一步的扩展,使struct在C++中可以和class一样当做类使用,而唯一和class不同的地方在于:struct的成员默认访问修饰符是public,而class默认的是private;
  • C++中有引用,C中没有;此时就要说一下引用和指针的区别了(在知识点扩充里补充)
  • C++特有的输入输出流;cin>>      cout<<
  • C语言中,如果一个函数没有指定返回值的类型,默认返回int类型;C++中,如果一个函数没有返回值,则必须指定为void
  • 在C语言中,函数没有指定的参数列表时,默认可以接收任意多个参数;但是在C++中,因为严格的参数类型检测,没有参数列表的函数,默认为void。

知识点扩充

扩展1:malloc/free 和 new/delete的用法和区别

  1. malloc是从堆上动态开辟空间的,而new是从自由存储区开辟为对象动态分配内存空间。
  2. malloc/free势函数,而new/delete是关键字
  3. malloc对开辟的空间大小有严格的指定,而new只需要对象名
  4. malloc开辟的空间即可以给单个对象使用也可以给数组使用,释放的方式都是free();而new开辟对象数组用new[size],释放的时候用delete[];
  5. new在申请内存分配空间时,不需要指定内存块的大小,编译器会自动根据类型信息自行计算。而malloc则需要指定内存块的大小;
  6. 返回值,malloc开辟成功后返回void*,需要通过强制类型转换将void*指针转换。new内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,不需要进行强制类型转换;
  7. 如果内存分配失败,那么malloc将会返回NULL,而new会抛出异常
  8. 自定义类型:new会先调用operator new函数,深爱你给足够的内存(通常底层用malloc实现),然后调用类型的构造函数,初始化成员变量,最后返回自定义类型的指针。delete先调用operator delete函数书房内存(底层通常用free类实现)
  9. malloc开辟空间大小如果太小,可以使用realloc实现,但是new没有直观的方法实现

注:

自由存储区:是C++基于new的一个抽象的概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。而堆是操作系统的术语,是操作系统所维护的一块特殊的内存,用于程序的内存动态分配,C语言是使用malloc从堆上分配空间的,使用free释放已分配的空间,如上所述,new不位于堆中。

ps:

在C++中,内存区分为5个区,分别是堆,栈,自由存储区,全局/静态存储区和常量存储区

在C中,内存区分为堆,栈,全局/静态存储区和常量存储区(对比C++,C内存区不包含自由存储区)

扩展2:指针和引用的区别

  1. 指针是一个实体,指向一块内存,它的内容是所指向内存的地址;引用只是一个别名
  2. 引用在使用时必须初始化,而指针可以不需要
  3. 有NULL指针,但是没有NULL引用
  4. 可以由const指针,但是没有const引用
  5. 指针在使用时可以指向其他对象,而引用只能是一个对象的引用
  6. 在sizeof中的含义不同,引用的结果为引用类型的大小,但是指针是地址空间所占的字节数
  7. 可以由多级指针,但是没有多级引用
  8. 引用自加改变变量的内容,指针自加改变了指针的指向
  9. 做为参数传递时,指针需要被解引用才可以对对象进行操作,而引用可以直接改变引用所指向的对象

扩展3:常见关键字的作用

  1. static关键字

  • 修饰全局变量时,会将变量的链接属性变为内部链接属性,并且变量的存储位置变为全局静态区
  • 修饰局部变量时,改变变量的存储位置为静态存储区,改变局部变量的生命周期为整个程序开始到结束
  • 修饰类的成员变量和函数,属于类而不属于对象,属于所有实例类

     2.const关键字

  • 修饰全局变量:C/C++略有不同,C++的const修饰的全局变量可以作为数组的初始化大小,而C不可以;同时变量的值不能被修改;C++利用const这一属性,代替了C中的define进行全局常量的定义
  • 修饰局部变量:我们来举个栗子看看:
const int *p;//修饰的是所指向的内容不能改变,p可以改变
int const *p//和上面一样
int* const p;//修饰的指针p不能改变,但是但是所指向内容可以改变
  • 修饰类的成员变量:必须初始化列表,除此之外呢,还必须在初始化列表中初始化的引用类型的数据成员,没有默认的构造函数的对象成员,如果存在继承关系,如父类没有默认构造函数,则也必须在吃石化列表中被初始化,初始化列表对数据成员的初始化顺序是按照数据成员的声明顺序严格执行的
  • 修饰类的成员函数:一般放在成员函数的最后面,修饰的是类的成员函数中的隐藏的参数this指针,代表不可以通过this指针修改类的数据成员,声明形式如下:
Base::void fun() const;

     3.volatile关键字

       volatile一般修饰变量,而它存在的原因是因为,我们的程序在进行编译的时候,编译器会进行一系列的优化,比如,某个变量被修饰为const的,编译器就认为,这个值是只读的,就会在寄存器中保存这个变量的值,每次需要的时候从寄存器直接读取,但是有时候,我们可能会在不经意间修改了这个变量,比如说我们去了这个变量的地址,然后强行改变这个变量在内存中的值,那么编译器并不知道,读取还是从寄存器中读取,这就造成了结果的不匹配,而volatile声明的变量就会告诉编译器,这个变量随时会改变,需要每次都从内从中读取,就是不需要优化,从而避免了这个问题,其实,volatile应用更多的场景是多线程对共享资源的访问的时候,避免编译器的优化,而造成多线程之间的通信不匹配!


猜你喜欢

转载自blog.csdn.net/lu_1079776757/article/details/80463115