C和C++的区别和联系(扩展知识)

 复习整理: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++特有输入输出流之类的,很多,下面就不再列出来了; “`

小知识点补充扩展

C/C++学习交流QQ群728483370,大家一起加油!

扩展_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++学习交流QQ群728483370,大家一起加油!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • 几种语言的特性 汇编程序:将汇编语言源程序翻译成目标程序编译程序:将高级语言源程序翻译成目标程序解释程序:将高级语...
    囊萤映雪的萤阅读 2,867评论 1 5
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,084评论 1 32
  • 题目类型 a.C++与C差异(1-18) 1.C和C++中struct有什么区别? C没有Protection行为...
    阿面a阅读 7,631评论 0 10
  • 重新系统学习下C++;但是还是少了好多知识点;socket;unix;stl;boost等; C++ 教程 | 菜...
    kakukeme阅读 19,792评论 0 50
  • 1.在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”? 答:首先,extern是C/C...
    曾令伟阅读 916评论 0 4