C 和 C++的区别 / struct 和 class 的区别 / 指针和引用的区别 / new 与 malloc 的区别 / 堆和栈的区别 / sizeof 和 strlen 的区别

20 篇文章 2 订阅

C 和 C++ 的区别

主要从以下三个方面来谈:

  • 设计思想、编程思想方面
  • 语言特性方面(语法、内存管理、库)
  • 执行效率方面

C 和 C++ 的区别

  • C 是面向过程的语言,而 C++ 是面向对象的语言,因此 C++ 语言中有类和对象以及继承多态这样的面向对象语言必备的内容,C++ 支持模板,运算符重载,异常处理机制,以及一个非常强大的 C++ 标准模板库 STL,另外一个 Boost 库现在也归属 C++ 标准库,提供了很多强大的功能。
  • C 只能写面向过程的代码,而 C++ 既可以写面向过程的代码,也可以实现面向对象的代码;C++ 有许多设计模式,比如单例、工厂、观察者模式等等,这些在 C 语言当中都是不支持的。由于 C++ 是面向对象的语言,支持类对象,类和类之间组合,继承,多态等等面向对象的设计,有很多的设计模式可以直接使用,因此在设计大型软件的时候,通常都会采用面向对象语言,而不会采用面向过程语言,可以更好的进行模块化设计,做到软件设计的准则:高内聚、低耦合!
  • 内存管理上,C 语言通过 malloc 和 free 来进行堆内存的分配和释放,而 C++ 是通过 new 和 delete 来管理堆内存的。
  • 强制类型转换上也不一样,C 的强制类型转换使用小括号里面加类型进行类型强转的,而 C++ 有四种自己的类型强转方式,分别是 const_cast、static_cast、reinterpret_cast 和 dynamic_cast。
  • 输入输出方式也不一样,C语言是用printf/scanf,他们是 C 的库函数, C++ 是用cout/cin ,是 ostream 和 istream 类型的对象。
  • C++ 支持带有默认值的函数、函数的重载、inline 内联函数,C 语言都不支持。
  • 由于 C++ 多了一个类,因此和 C 语言的作用域比起来,就多了一个类作用域,C++ 还支持命名空间,可以让用户自己定义新的命名空间,避免全局的名字冲突问题。
  • C++ 不仅支持指针,还支持引用,引用比指针更安全。但在汇编代码上,指针和引用的操作是一样的,而且在底层引用也是通过指针来实现的。

C++ 中 struct 和 class 的区别

  • C++ 中对 struct 的功能进行了很多的扩充,它可以有自己的成员函数、构造函数,也可以实现继承、多态,class 可以继承 struct、struct 可以继承 class。

它们的区别在于三点:

  • 默认的成员变量访问权限
    struct 对数据成员的默认访问权限是 public 的,class 默认是 private 的。
  • 默认的继承访问权限
    struct 的默认继承权限是 public 的,class 默认是 private 的。
  • class 可以定义模板参数,但 struct 不可以。

指针和引用的区别

  • 指针是一个实体,它是一个地址,指向一块内存区域;引用是一个别名,并不是一个实体。
  • 底层指针和引用的实现是一样的,它们的效率是一致的,具体在于编译器的处理不同。
  • 编译时期生成符号表,存储变量名和变量地址,对于指针来说,符号表中存储指针名和指针本身的地址;指针在运行时可以改变其值或者指向。对于引用来说,符号表中存储引用对象的地址,符号表一旦生成,程序运行过程中不会修改,因此引用初始化后不可改变(其所引用的对象可以改变)。
  • 内存分配方面:程序为指针是分配内存的,而对于引用是不分配内存的,因此存在多级指针,但只有一级引用。
  • 大小方面:对一个指针使用 sizeof,返回的是指针变量本身的大小,4 或 8 字节,但是对一个引用使用 sizeof,返回的是其引用的对象的大小。
  • 作为函数形参:引用做函数形参,那么在函数内部,对形参的修改即为对实参的修改。指针做函数形参,若是对指针本身做操作,不会影响实参指针,因为形参指针是实参指针的副本,但是对其所指向的内容操作,会更改实参所指的内容。
  • 自增运算:对指针做自增运算会只指向下一个地址,而对引用做自增运算会使所指对象自增。

new 与 malloc 的区别

  • new 操作符从自由存储区(free store)上为对象动态分配内存空间,而 malloc 函数从堆上动态分配内存。
  • new 操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故 new 是符合类型安全性的操作符。而 malloc 内存分配成功则是返回 void*,需要通过强制类型转换将 void* 指针转换成我们需要的类型。
  • new 内存分配失败时,会抛出 bac_alloc 异常,不会返回 NULL;malloc 分配内存失败时返回 NULL。
  • 使用 new 操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算,而 malloc 则需要显式地指出所需内存的大小。
  • new/delete 会调用对象的构造函数/析构函数以完成对象的构造/析构。而 malloc 则不会。
  • C++ 提供了 new[] 与 delete[] 来专门处理数组类型,new 对数组的支持体现在它会分别调用构造函数初始化每一个数组元素,释放对象时为每个对象调用析构函数。至于 malloc,它并不知道你在这块内存上要放的数组还是其他类型,它只分配一块原始的内存,返回一个内存的地址。所以如果要动态分配一个数组的内存,还需要我们手动自定数组的大小。
  • operator new/operator delete 的实现可以基于 malloc,而 malloc 的实现不可以去调用 new。
  • opeartor new/operator delete 可以被重载。而 malloc/free 不允许重载。
  • 使用 malloc 分配的内存后,如果在使用过程中发现内存不足,可以使用 realloc 函数进行内存重新分配实现内存的扩充。new 没有这样直观的配套设施来扩充内存。
  • 在 operator new 抛出异常以反映一个未获得满足的需求之前,它会先调用一个用户指定的错误处理函数,这就是 new-handler。对于 malloc,客户并不能够去编程决定内存不足以分配时要干什么事,只能看着 malloc 返回 NULL。

堆和栈的区别

  • 管理方式不同:
    栈由操作系统自动分配释放,无需我们手动控制;
    堆的申请和释放工作由程序员控制,容易产生内存泄漏。
  • 申请后系统的响应不同:
    只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
    对于堆来说,操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。
  • 申请大小的限制不同:
    栈是向低地址扩展的数据结构,是一块连续的内存的区域。栈顶的地址和栈的最大容量是系统预先规定好的,栈的大小是是一个编译时就确定的常数,如果申请的空间超过栈的剩余空间时,将提示 overflow。因此,能从栈获得的空间较小。
    堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
  • 申请效率的比较不同:
    栈由系统自动分配,速度较快。但程序员是无法控制的。
    堆是由 new 分配的内存,一般速度比较慢,而且容易产生内存碎片。

sizeof 和 strlen 的区别

  • sizeof 是 C/C++ 语言的单目运算符,用来计算数据所占内存的大小;而 strlen 是库函数,用来计算字符串的长度。
  • sizeof 所计算的值在编译阶段就能确定,strlen 在运行时才能计算出结果。
  • 求字符串长度时,sizeof 返回的结果包含 ‘\0’,计算的是实际占用内存的大小,而 strlen 不包括,但它也是根据 ‘\0’ 来判断字符串结尾的。
  • sizeof 可以使用类型做参数, strlen 只能使用 char * 类型做参数,并且必须是以 ‘\0’ 结尾。
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值