C和C++的区别和联系
关于C和C++的区别是面试中经常会被问到的问题,本着即将面试的心态,进行知识整理,并对小知识点进行扩展;
C/C++的联系:
- C++是C的超集,兼容大部分C的语法的结构; 
 联系嘛我只能想到这个,毕竟cplusplus嘛!
C/C++区别:
- 第一点就应该想到C是面向过程的语言,而C++是面向对象的语言,一般简历上第一条都是熟悉C/C++基本语法,了解C++面向对象思想,那么,请问什么是面向对象? 
- C和C++动态管理内存的方法不一样,C是使用malloc/free函数,而C++除此之外还有new/delete关键字;(关于malooc/free与new/delete的不同又可以说一大堆,最后的扩展_1部分列出十大区别); 
- 接下来就不得不谈到C中的struct和C++的类,C++的类是C所没有的,但是C中的struct是可以在C++中正常使用的,并且C++对struct进行了进一步的扩展,使struct在C++中可以和class一样当做类使用,而唯一和class不同的地方在于struct的成员默认访问修饰符是public,而class默认的是private; 
- C++支持函数重载,而C不支持函数重载,而C++支持重载的依仗就在于C++的名字修饰与C不同,例如在C++中函数int fun(int ,int)经过名字修饰之后变为 _fun_int_int ,而C是 
 _fun,一般是这样的,所以C++才会支持不同的参数调用不同的函数;
- C++中有引用,而C没有;这样就不得不提一下引用和指针的区别(文后扩展_2); 
- 当然还有C++全部变量的默认链接属性是外链接,而C是内连接; 
- C 中用const修饰的变量不可以用在定义数组时的大小,但是C++用const修饰的变量可以(如果不进行&,解引用的操作的话,是存放在符号表的,不开辟内存); 
- 当然还有局部变量的声明规则不同,多态,C++特有输入输出流之类的,很多,下面就不再列出来了; “` 
小知识点补充扩展
- 扩展_1: 细数malloc/free和new/delete的十点区别 - malloc是从堆上开辟空间,而new是从自由存储区开辟;(自由存储区是 
 C++抽象出来的概念,不仅可以是堆,还可以是静态存储区);
- malloc/free是函数,而new/delete是关键字; 
- malloc对开辟的空间大小需要严格指定,而new只需要对象名; 
- malloc开辟的空间即可以给单个对象用也可以给数组用,释放的方式都是 
 
free();而new开辟对象数组用的是new[size] ,释放的的时候是 delete[]
(尽管内置类型可能不会引起问题,但是自定义类型的话,delete[]需要知道有
多少个对象,而这个计数就被放在这块空间的头部);
- 返回值问题,malloc开辟成功返回void*,需要强转,失败返回NULL,new
成功返回对象指针,失败抛出异常(这就可能会提到C++的new_handler机
制),虽然为了最大程度的兼容C,C++的new也支持失败返回NULL,但是一般不
被使用,大家可以了解一下;
- 是否调用构造和析构,这点应该放在前面,new和free不但负责开辟空间,
还会调用对象的构造函数和析构函数;最好了解一下new的三种表达形式(new运
算符,operator new(); placement new();)还有定位new表达式的
使用;
- 是否可以相互调用,new的实现可以用malloc,malloc的实现不可以使用
new;
- 是否可以被重载,我们可以重载自己的operator new/delete,但是不可
以重载new/delete/malloc/free;
- malloc开辟 的内存如果太小,想要换一块大一点的,可以调用relloc实
现,但是new没有直观的方法来改变;
- 第十点其实前面已经提到,当new中的底层实现如果获取不到更多的内存,
会触发new_handler机制,留有一个set_new_handler句柄,看看用户是否设
置了这个句柄,如果设置了就去执行,句柄的目的是看看能不能尝试着从操作系
统释放点内存,找点内存,如果实在不行就抛出bad_alloc异常;而malloc就
没有这种尝试了;——-
- 扩展_2 指针和引用的区别 - 1.指针有自己的一块空间,而引用只是一个别名; 
 2.使用sizeof看一个指针的大小是4,而引用则是被引用对象的大小;
 3.指针可以被初始化为NULL,而引用必须被初始化且必须是一个已有对象
 的引用;
 4.作为参数传递时,指针需要被解引用才可以对对象进行操作,而直接对引
 用的修改都会改变引用所指向的对象;
 5.可以有const指针,但是没有const引用;
 6.指针在使用中可以指向其它对象,但是引用只能是一个对象的引用,不能
 被改变;
 7.指针可以有多级指针(**p),而引用至于一级;
 8.指针和引用使用++运算符的意义不一样;
扩展_3 常见关键字的作用
**1.static 关键字:**
    修饰全局变量时,会将变量的链接属性变为内部链接属性,并且变量
    的存储位置变为全局静态区;
    修饰 局部变量,改变局部变量的存储位置为静态存储区,改变局部变
    量的生命周期为整个程序开始到结束;
    修饰类的成员变量和函数:属于类而不属于对象,属于所有实例类;
**2.const关键字**
    修饰全局变量:C/C++略有不同,在上文已经提到,即C++的const修
    饰的全局变量可以作为属组的初始化的大小,而C不可以;同时变量的
    值不能被修改;C++利用const的这一属性,代替C中的define进行
    全局常量的定义;扩展_4会就 define,const,inline进行对比
    和分析;
    修饰局部变量:代表局部变量的值不能被修改;
    修饰指针:这个是经常问道的,我举的例子可能不全面,但是是比较
    常见的例子:
    cons t int *p;  //修饰的是p所指向的内容不能被改变,p可
    以;
    int const *p;  //和上面是一样的;
    int* const p;  //修饰的p指针不能改变;
    修饰类的成员变量:必须在初始化列表初始化,除此之外,必须在初
    始化列表初始化的还有,引用类型的数据成员,没有默认构造函数的
    对象成员,如果存在继承关系,如果父类没有默认的构造函数,则也
    必须在初始化列表中被初始化,初始化列表对数据成员的初始化顺序
    是按照数据成员的声明顺序严格执行的;
    修饰类的成员函数:一般放在成员函数的最后面,修饰的是类的成员
    函数中的隐藏参数this指针,代表不可以通过this指针修改类的数据
    成员,声明形式例如:
    Base::void fun() const;
    关于const还有一个问题就是传参和赋值的问题,一般来说,const
    修饰的变量是安全的,没有const修饰的变量是不安全的,一般在传
    参的时候,非const修饰的的变量可以传给const修饰的,而const
    修饰的不可以传给非const修饰的形参,这就相当于把安全的东西交
    给了不安全的人;而赋值的话更不用说了,const修饰的不可以传给
    没有const修饰的变量;
**3.volatile**
    volatile一般修饰变量,而它存在的原因是因为,我们的程序在进行
    编译的时候,编译器会进行一系列的优化,比如,某个变量被修饰为
    const的,编译器就认为,这个值是只读的,就会在寄存器中保存这
    个变量的值,每次需要的时候从寄存器直接读取,但是有时候,我们
    可能会在不经意间修改了这个变量,比如说我们去了这个变量的地
    址,然后强行改变这个变量在内存中的值,那么编译器并不知道,读
    取还是从寄存器中读取,这就造成了结果的不匹配,而volatile声明
    的变量就会告诉编译器,这个变量随时会改变,需要每次都从内从中
    读取,就是不需要优化,从而避免了这个问题,其实,volatile应用
    更多的场景是多线程对共享资源的访问的时候,避免编译器的优化,
    而造成多线程之间的通信不匹配!;
explicit关键字 
首先需要了解什么是隐式转换,即在你没有进行显示的强转的情况 
下,赋值运算符左右两个类型不一致的对象进行了类型转换;或者 
函数传参的时候进行了类型转换; 而explicit关键字存在的目的就是 
禁止类的构造函数进行隐式的类型转换,常见的就是string类的对象 
就可以隐式类型转换,比如:
 strig  s = "hello world";
    因为string 有一个单参的char*构造函数,所有可以用hello w
    orld构造一个string对象,然后调用string 类的拷贝构造函数;
    有时候我们并不希望这种不是我们预期的情况发生,所以,我们可以
    在类的构造函数之前+explicit关键字。禁止隐式转换;
    ---希望读者提建议继续补充!(补充文章中讲到的所有内容的不足之处)
扩展_4 define /const/inline 对比和分析
define作用于程序的预处理阶段,而预处理阶段做的主要工作为下面几个 
方面:宏替换,去注释以及条件编译; define起作用的地方就在宏替换阶 
段,只是单纯的将宏替换为代码,例如:
#define Add(a+b) a+b
下面这段代码用到了这个宏:
int main()
{
int a = 1; //如果char a = '1';
int b = 2;
cout<<Add(a+b);
/* 替换为cout<<1+2; */
return 0;
}
从上面这个例子我们可以看出define的缺点很明显,首先,define只 是单纯的代码替换,不会进行类型的检查,再者,我们上面的宏定义 也很粗糙,严格点应该定义为: #define Add(a,b) (a)+(b) C++中一般建议使用const,枚举定义常量,这样就会有类型检查; 而宏定义也可以定义出和函数一样的功能: #define Swap(type,a,b) {type tmp, tmp = a; a = b; b = tmp;} 其实就算这样写,也还是存在上面提到的问题,并且这样还不能进行调 试,因为宏在预处理阶段就替换了;
于是C++中又提供了一个inline内联关键字 ,可以实现和define相同的 
功能,并且支持类型检查和调试,一般声明在函数的定义的前面,不过, inline只是对编译器的一种建议,一般如果代码在3-5行左右,且没有复 杂的逻辑结构,例如循环啊,递归啊,就可以声明为inline,inline也 
是在函数调用的地方替换代码块,所以代码太长的话,容易造成程序膨胀,那么inline为什么可以支持调试呢?
其实支持调试也只是在dbug模式下,inline真正起作用是在release模 
式,正好和assert相反;
提到inline,就不得不提friend友元;被一个类中声明为友元的非本类函数和类,可以访问本类的私有成员,这个关键字的存在感觉有些破坏类的封 
装性,而且,友元属性不能被传递和继承;(但是实际中在有些编译器下友元函数被子类继承了,我也很纳闷,读者可以自己验证一下,留言!)
C和C++的区别和联系的更多相关文章
- c#与java的区别
		经常有人问这种问题,用了些时间java之后,发现这俩玩意除了一小部分壳子长的还有能稍微凑合上,基本上没什么相似之处,可以说也就是马甲层面上的相似吧,还是比较短的马甲... 一般C#多用于业务系统的开发 ... 
- jquery和Js的区别和基础操作
		jqery的语法和js的语法一样,算是把js升级了一下,这两种语法可以一起使用,只不过是用jqery更加方便 一个页面想要使用jqery的话,先要引入一下jqery包,jqery包从网上下一个就可以, ... 
- 【原】nodejs全局安装和本地安装的区别
		来微信支付有2年多了,从2年前的互联网模式转变为O2O模式,主要的场景是跟线下的商户去打交道,不像以往的互联网模式,有产品经理提需求,我们帮忙去解决问题. 转型后是这样的,团队成员更多需要去寻找业务的 ... 
- 探究@property申明对象属性时copy与strong的区别
		一.问题来源 一直没有搞清楚NSString.NSArray.NSDictionary--属性描述关键字copy和strong的区别,看别人的项目中属性定义有的用copy,有的用strong.自己在开 ... 
- X86和X86_64和X64有什么区别?
		x86是指intel的开发的一种32位指令集,从386开始时代开始的,一直沿用至今,是一种cisc指令集,所有intel早期的cpu,amd早期的cpu都支持这种指令集,ntel官方文档里面称为&qu ... 
- Java中Comparable与Comparator的区别
		相同 Comparable和Comparator都是用来实现对象的比较.排序 要想对象比较.排序,都需要实现Comparable或Comparator接口 Comparable和Comparator都 ... 
- MySQL中interactive_timeout和wait_timeout的区别
		在用mysql客户端对数据库进行操作时,打开终端窗口,如果一段时间没有操作,再次操作时,常常会报如下错误: ERROR (HY000): Lost connection to MySQL server ... 
- 设置line-height:1.5和line-height:150%或者line-height:150px的区别
		直接正题: 看一下line-height可能的值: 其实可以分为两类: (1)不带单位的(如line-height:1.5),这种是推荐使用的: (2)带单位的(如line-heigth:30px/1 ... 
- C#中Length和Count的区别(个人观点)
		这篇文章将会很短...短到比你的JJ还短,当然开玩笑了.网上有说过Length和count的区别,都是很含糊的,我没有发现有 文章说得比较透彻的,所以,虽然这篇文章很短,我还是希望能留在首页,听听大家 ... 
- select、poll、epoll之间的区别总结
		select.poll.epoll之间的区别总结 05/05. 2014 select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪 ... 
随机推荐
- .NET 使用 RabbitMQ 图文简介
			前言 最近项目要使用RabbitMQ,园里里面已经有很多优秀的文章,Rabbitmq官网也有.net实例.这里我尝试下图文并茂之形式记录下使用的过程. 安装 RabbitMQ是建立在erlang OT ... 
- HTML  页面的  批量删除的按钮
			function delAll(){ var sid=""; $("[name='ids']:checked").each(function(){ sid+=$ ... 
- Java微信二次开发(三)
			各种类型消息的封装 第一步:找到com.wtz.message.response包,新建类Image.java package com.wtz.message.response; /** * @aut ... 
- codeforces437C
			The Child and Toy CodeForces - 437C On Children's Day, the child got a toy from Delayyy as a present ... 
- Markdown 文件转化为work文档
			1. 电脑安装pandoc 链接:https://pan.baidu.com/s/12H5wLO0JWph5TjrbeJI6mg 密码:ssgs 下载安装包解压即可用.记得配置系统环境变量 2.命令行 ... 
- ansible系列4-关闭ssh首次连接时提示
			在ansible配置文件中找到 /etc/ansible/ansible.cfg 方法1 在配置文件中找到 了解到问题原因为,我们了解到进行ssh连接时,可以使用-o参数将StrictHostKeyC ... 
- Codeforces Round #337 (Div. 2) B. Vika and Squares
			B. Vika and Squares time limit per test 2 seconds memory limit per test 256 megabytes input standard ... 
- MT【42】抛物线不常见性质1.
			评:特别的,当$PP'$为切线时,$\angle PSK=90^0$ 注:S为抛物线焦点. 
- LOJ #6436. 「PKUSC2018」神仙的游戏(字符串+NTT)
			题面 LOJ #6436. 「PKUSC2018」神仙的游戏 题解 参考 yyb 的口中的长郡最强选手 租酥雨大佬的博客 ... 一开始以为 通配符匹配 就是类似于 BZOJ 4259: 残缺的字符串 ... 
- 2.9 C++使用默认参数的构造函数
			总结: 默认参数的构造函数,其默认参数必须置于参数列表的结尾. 设计类的构造函数的时候最好不要同时是用构造函数的重载和带参数的构造函数. 我们可以想象一个这样的场景:某一天书店整理库存,发现了一些非常 ... 
