《C与C的区别》PPT课件.ppt

上传人:za****8 文档编号:12668555 上传时间:2020-05-13 格式:PPT 页数:48 大小:293.51KB
返回 下载 相关 举报
《C与C的区别》PPT课件.ppt_第1页
第1页 / 共48页
《C与C的区别》PPT课件.ppt_第2页
第2页 / 共48页
《C与C的区别》PPT课件.ppt_第3页
第3页 / 共48页
点击查看更多>>
资源描述
C语言是结构化和模块化的面向过程的语言C+是面向对象的程序设计语言,由C语言扩展而来,保留了C语言的优点,添加了面向对象编程的支持,具有面向对象的程序设计语言的三大特性:封装性、继承性和多态性。带有面向对象功能的C语言增强版本含类的C,第1章C与C+的区别,变量定义位置与作用域名字空间结构体变量输入输出动态内存分配(new和delete)引用const修饰符函数原形内联函数带缺省参数的函数函数重载函数模板类和对象,变量定义位置与作用域,C+中,允许变量定义语句在程序中的任何地方,只要在是使用它之前就可以;而C语言中,必须要在函数开头部分。而且C+允许重复定义变量,C语言也是做不到这一点的。通常情况下,如果全局变量与局部变量同名,那么局部变量在其作用域内具有较高的优先权。访问被屏蔽的全局变量使用作用域操作符“:”,名字空间:面向对象程序设计的重要概念。它为用户提供一个空间,在里面可定义自己的函数或类,当定义的函数或类和他人定义的重名时,可用名字空间来区分。名字空间用花括号把文件的一部分括起来,并以关键字namespace开头。,名字空间,namespacens1floata,b,c;fun1(),花括号括起来的部分称声明块。声明块中可包括:类、变量、函数等。在域外使用域内成员时,需加上名字空间名作为前缀,后面加上域操作符“:”。最外层的名字空间域称为全局名字空间域,即文件域。名字空间域可分层嵌套,同样有分层屏蔽作用。,namespacen1namespacen2/名字空间嵌套classmatrix/名字空间类成员matrix/访问matrix,可写:n1:n2:matrix。,标准C+库中的所有组件都是在一个被称为std的名字空间中声明和定义的。使用标准C+库中的组件,只要写一个using指示符:usingnamespacestd;注意:如果使用了名空间std,则在使用#include编译预处理命令包含头文件时,必须去掉头文件的扩展名.h,否则会出错。,结构体变量,在C+中,struct结构体支持成员函数的定义,C中不行如果在C的struct中定义函数,编译时会显示一个“fieldfunctionnamedeclaredasfunction”错误在C语言中,声明一个结构体类型A之后,使用下面的语句来定义结构体变量a:structAa;而C+中可以省略structC+中联合名、枚举名也可在定义后独立地作为类型名使用,/*ch3_10.c*/structAinta;intb();intmain()structAc;c.a=2;return0;编译错误:“ch3_10.c:5:error:fieldbdeclaredasafunction”C+标准可以通过编译,输入输出,C中用scanf(),printf()来完成输入输出操作inta;scanf(%d,C+中全局对象cin、cout来输入输出,比C更方便,而且类型检查机制更加完善cout“输入内容”;/cin为标准输入流对象(默认从键盘输入),C+中的使用方式new申请delete释放C中的使用方式malloc()申请free()释放使用:int*p=(int*)malloc(sizeof(int);int*p=newint;,动态内存分配,new运算符指针变量=new数据类型;如:int*p;p=newint;new从堆内存中为程序分配一块内存空间,并返回指向该内存的首地址,该地址存放于指针变量中。堆内存可以按照要求进行分配,若程序在运行中不再需要由new分配的内存空间,则可把先前占用的内存空间释放。,delete运算符delete指针变量;如:deletep;(1)用new获取的内存空间,必须用delete进行释放;(2)对一个指针只能调用一次delete;(3)用delete运算符作用的对象必须是用new分配的内存空间的首地址,用new建立数组类型的变量,指针变量=new数据类型数组大小;如:int*p=newint5;此时指针变量指向第一个数组元素的地址。使用new分配数组时,不能提供初始值。使用new建立的数组变量由delete释放。delete指针变量;如:deletep;,在C+中引用用于在程序的不同部分使用两个以上的变量名指向同一地址,使对其中任一变量的操作实际上都是对同一地址单元进行的。被声明为引用类型的变量名是实际变量名的别名。引用运算符为int/num被修改为100,其中ref2也是对num的引用。,(5)可把函数的参数说明成引用以建立函数参数的引用传递方式。(6)有空指针,无空引用(7)函数调用可以作为左值引用表达式是一个左值表达式,因此它可以出现在形、实参数的任何一方。若一个函数返回了引用,那么该函数的调用也可以被赋值。一般说,当返回值不是本函数内定义的局部变量时就可以返回一个引用。在通常情况下,引用返回值只用在需对函数的调用重新赋值的场合,也就是对函数的返回值重新赋值的时候。避免将局部作用域中变量的地址返回,就使函数调用表达式作为左值来使用。,引用举例,#includevoidmain()intnum=50;int,(回顾)函数的参数传递当函数未被调用时,C+编译系统并没有给函数的形参分配相应的内存空间,函数的形参更不会有实际的值。只有在函数被调用时,C+编译系统这时才为形参分配实际的存储单元,并将实参与形参结合。实参可以是常量、变量或表达式,其类型必须与形参相符。函数的参数传递,指的就是形参与实参结合(简称形实结合)的过程。形实结合的方式有传值调用,传地址调用和引用调用三种。,1.传值调用值调用是指当发生函数调用时,编译系统为形参分配相应的存储空间并且直接将实参的值复制给形参,这样形参和实参就各自拥有不同的存储单元,且形参是实参的副本。因此,值调用过程是参数值的单向传递过程,一旦形参获得了与实参相同的值就与实参脱离关系,以后不论形参发生多大的改变,都决不会反过来影响到实参。,2.地址传递。所谓地址传递,即指针变量作为函数参数。主调函数中实参的内容是某一变量的内存地址,被调函数的形参必须是与实参相同类型的指针变量,用以接受由实参传过来的地址。这样实参与形参指向相同的内存单元,一旦被调函数中形参所指内容发生变化,意味着实参所指内容也发生相应的变化,函数返回后主调函数就可获得变化后的结果。,3.引用调用引用是一种特殊类型的变量,可以被认为是某一个变量的别名。通过引用名与通过被引用的变量名访问变量的效果是一样的。这就是说,对形参的任何操作也就直接作用于实参。如果我们想使子函数中对形参所做的任何更改也能及时反映给主函数中的实参(即希望形参与实参的影响是互相的或称是双向的),还可以采用第三种参数传递方式引用调用。,#definePI3.1415926/C中的做法constfloatPI=3.1415926;/C+中的做法这个常量是有类型的,它有地址,可用指针指向这个值,但不能修改它。C+建议用const取代#define定义常量。,const修饰符,注意:(1)使用const修饰符定义常量时,必须初始化;(2)常量一旦被定义,在程序中任何地方都不能再更改。(3)与#define定义的常量有所不同,const定义的常量可以有自己的数据类型,这样C+编译程序可以进行更加严格的类型检查,具有良好的编译时的检测性。(5)函数参数也可以用const说明,用于保证实参在该函数内部不被改动。例如,通过函数max求出整型数组a100中的最大值,函数原型应该是:intmax(constint*pa);这样做的目的是确保原数组的数据不被破坏,即在函数中对数组元素的操作只许读,不许写。,(1)指向常量的指针指向常量的指针是指一个指向常量的指针变量。constchar*pc=abcd;声明指向常量的指针变量pc,它指向一个字符串常量由于使用了const,不允许改变指针所指的常量,因此以下语句是错误的:pc3=x;但是由于pc是一个指向常量的普通指针变量,不是常指针,因此可以改变pc的值。例如以下语句是允许的:pc=jkkk;,const与指针组合使用,(2)常指针常指针是指指针本身,而不是它指向的对象声明为常量。例如:char*constpc=abcd;/常指针这个语句的含义为:声明一个名为pc的指针变量,该指针是指向字符型数据的常指针,用“abcd”的地址初始化该常指针。创建一个常指针,就是创建不能移动的固定指针,但是它所指的数据可以改变。例如:pc3=x;/合法pc=dfasdfa;/不合法,(3)指向常量的常指针整个指针本身不能改变,它所指向的值也不能改变。要声明一个指向常量的常指针,二者都要声明为const。例如:constchar*constpc=abcd;/指向常量的常指针这个语句的含义为:声明一个名为pc的指针变量,它是一个指向字符型常量的常指针,用“abcd”的地址初始化该指针。以下两个语句都是错误的:pc3=x;/错误,不能改变指针所指的值pc=dfasdfa;/错误,不能改变指针本身,const与引用组合使用,只有一种情况:指向常量的引用不能通过引用修改它所引用的变量。例如:inta=3;constintra=5;/错误,不能通过常引用改变所引用的变量的值a=4;/正确,a仍是变量,函数原型,C+要求为每一个函数建立原型,用以说明函数的名称、参数个数及类型和函数返回值的类型。其主要目的是让C+编译程序进行类型检查,即形参与实参的类型匹配检查,以及返回值是否与原型相符,以维护程序的正确性。所以应养成将声明与定义分别编写的编程习惯。函数原型与函数的定义要在函数的返回类型,函数名和参数的类型及数量这三条线上保持一致。在写函数原型时,可以省略形参的名字,因为参数名对编译器没有意义,但如果取名恰当的话,这些名字可以起到提示参数用途的作用。,在执行程序过程中如果要进行函数调用,则系统要将程序当前的一些状态信息存到栈中,之后进行虚实结合,同时转到函数的代码处去执行函数体语句,这些参数保存与传递的过程中需要时间和空间的开销,使得程序执行效率降低,特别是在程序频繁地进行函数调用以及函数代码段比较少时,这个问题会变得更为严重。为了解决这个问题,C+引入了内联函数机制。使用内联函数是一种用空间换时间的措施,若内联函数较长,且调用太频繁时,程序将加长很多。因此,通常只有较短的函数才定义为内联函数,对于较长的函数最好作为一般函数处理。,内联函数,使用内联函数正是解决这一问题的手段。内联函数不是在调用时发生转移,而是在编译时将函数体嵌入在每一个调用语句处。这样就相对节省了参数传递、系统栈的保护与恢复等的开销。内联函数在定义时使用关键字inline区别于一般函数,其语法形式如下:(含类型说明的形参表)函数体,例如:inlineintmul(inta,intb)returna*b;当程序中出现mul(2+3,4)的函数调用时,编译程序就会将其扩展为(2+3)*4。关键字inline是一个编译命令,编译程序在遇到这个命令时将记录下来,在处理内联函数的调用时,编译程序就试图产生扩展码。这样从使用者的角度来看,内联函数在语法上与一般函数没有什么区别,只是在编译程序生成目标代码时才区别处理。,一般情况下,我们对内联函数做如下的限制:(1)不能有递归(2)不能包含静态数据(3)不能包含循环(4)不能包含switch和goto语句(5)不能包含数组若一个内联函数定义不满足以上限制,则编译系统把它当作普通函数对待。,带缺省参数的函数,如果在函数说明或函数定义中为形参指定一个缺省值,则称此函数为带缺省参数的函数。当函数调用发生后,在形参表中等号后的各“缺省值”将起实参的传递作用。如果在函数原型的声明中设置了函数参数的缺省值,则不可再在函数定义的头部重复设置,否则编译时将出现错误信息。指定默认参数值可以使函数的使用更为简单,同时也增强了函数的可重用性。,注意:默认形参值必须按从右向左的顺序定义。在有默认值的形参右面,不能出现无默认值的形参。因为在调用时,实参初始化形参是按从左向右的顺序。例如:voidtry(intj=3,intk)/非法voidtry(intj,intk=2,intm)/非法voidtry(intj,intk=7)/合法voidtry(intj,intk=2,intm=3)/合法voidtry(intj=3,intk=2,intm=3)/合法,默认形参值应该在函数原型中给出。例如:intmulti(intx=2,inty=5);/默认形参值在函数原型中给出voidmain()multi();/并非无参调用,而是采用默认值,x取值2,y取值5intmulti(intx,inty)return(x*y);,在相同的作用域内,默认形参值的说明应保持唯一。但如果在不同的作用域内,允许说明不同的默认形参。这里的作用域是指直接包含着函数原型说明的大括号所界定的范围。例如:intadd(intx=2,inty=5);/全局默认形参值voidmain()intadd(intx=1,inty=9);/局部默认形参值add();/此处调用时,采用局部默认形参值,x取值1,y取值9voidfunc(void)add()/此处调用时,采用全局默认形参值,x取值2,y取值5,C+允许为两个或两个以上的函数取相同的函数名,但是形参的个数或者形参的类型不应相同,编译系统会根据实参和形参的类型及个数的最佳匹配,自动确定调用哪一个函数,这就是所谓的函数重载。函数重载无需特别声明,只要所定义的函数与已经定义的同名函数形参形式不完全相同,C+编译器就认为是函数的重载。,函数重载,对于没有重载机制的C语言,每个函数必须有其不同于其它函数的名称,即使操作是相同的,仅仅数据的类型不相同,也需要定义名称完全不同的函数,这样就显得重复且效率低下。例如,定义求平方函数,就必须对整数的平方、浮点数的平方以及双精度数的平方分别用不同的函数名:intisq(intx,inty);floatfsq(floatx,floaty);doubledsq(doublex,doubley);,程序在调用这三个不同类型的函数时,是以名字加以区别的,需要记住并区别它们的名称。显然,这样就造成了代码的重复,使用起来也不方便,更不利于代码的维护。对于具有重载机制的C+语言,允许功能相近的函数在相同的作用域内以相同函数名定义,因而使函数方便使用,便于记忆,也使程序设计更加灵活。仍以上例而言,在C+中只要用一个函数名即可,如square(),然后以赋给此函数的参数类型来决定是要计算int型、float型,还是double型的数的平方。,上例在C+中的定义形式如下:intsquare(intx);floatsquare(floatx);doublesquare(doublex);square(3),C+自动使用第一种形式;square(3.25),C+自动使用第三种形式;square(3.25f)时,C+自动使用第二种形式。,比较C形式:intintisq(intx,inty);floatfsq(floatx,floaty);doubledsq(doublex,doubley);,在使用重载函数时要注意:不可以定义两个具有相同名称、相同参数类型和相同参数个数,只是函数返回值不同的函数。intfunc(intx);floatfunc(intx);如果某个函数参数有缺省值,必须保证其参数缺省后调用形式不与其它函数混淆。intf(inta,floatb);voidf(inta,floatb,intc=0);函数调用语句:f(10,2.0);具有二义性,既可以调用第一个函数,也可以调用第二个函数,编译器不能根据参数的形式确定到底调用哪一个。,C+中可以使用模板来避免在程序中多次书写相同的代码。所谓模板是一种使用无类型参数来产生一系列函数或类的机制。它的实现方法方便了更大规模的软件开发。模板是以一种完全通用的方法来设计函数和类,而不必预先说明将被使用的每个对象的数据类型。通过模板可以产生类或函数的集合,使它们操作不同的数据类型,从而避免为每一种数据类型产生一个单独的类或函数。模板分为函数模板和类模板,C+提供的函数模板可以定义一个对任何类型变量进行操作的函数,从而大大增强了函数设计的通用性。这是因为普通函数只能传递变量参数,而函数模板提供了传递类型的机制。使用函数模板的方法是先说明函数模板,然后实例化成相应的模板函数进行调用执行。,函数模板,intsmall(intx,inty)returnxy?x:y;doublesmall(doublex,doubley)returnxy?x:y;考察以上两个函数,有如下特点:只有参数类型不同,返回值类型不同,功能则完全一样。类似这样的情况,可以使用函数模板,从而避免函数体的重复定义。,函数模板的一般说明形式如下:template(模板函数形参表)/函数定义体尖括号中不能为空,参数可以有多个,用逗号分开。模板参数主要是模板类型参数。模板类型参数(templatetypeparameter)代表一种类型,由关键字class或typename后加一个标识符构成,在这里两个关键字的意义相同,它们表示后面的参数名代表一个基本数据类型或用户定义的类型。,注意:如果类型形参多于一个,则每个类型形参都要使用class或typename。中的参数必须是唯一的,而且中至少出现一次。如:template,则“T”可以在程序运行时被任何C+支持的数据类型所取代。如有两个以上的模板参数时,使用逗号分隔,如:“template”。由于模板是专门为函数安排的,所以模板声明语句必须置于与其相关的函数声明或定义语句之前,但附于函数声明语句和定义语句前的模板参数表的替代类型标识符可以不一致。函数模板定义不是一个实实在在的函数,编译系统不为其产生任何执行代码。该定义只是对函数的描述,表示它每次能单独处理在类型形式参数表中说明的数据类型。,函数模板只是说明,不能直接执行,需要实例化为模板函数后才能执行。当编译系统发现有一个函数调用:;时,将根据中的类型生成一个重载函数,即模板函数。该模板函数的定义体与函数模板的函数定义体相同,而的类型则以的实际类型为依据。模板函数有一个特点,虽然模板参数T可以实例化成各种类型,但是采用模板参数T的各参数之间必须保持完全一致的类型。模板类型并不具有隐式的类型转换,例如在int与char之间、float与int之间、float与double之间等的隐式类型转换。函数模板方法克服了C语言用大量不同函数名表示相似功能的坏习惯;克服了宏定义不能进行参数类型检查的弊端;克服了C+函数重载用相同函数名字重写几个函数的烦琐。,当模板函数与重载函数同时出现在一个程序体内时,C+编译器的求解次序是先调用重载函数;如果不匹配,则调用模板函数;如果还不匹配则进行强制类型转换,前面几种方法都不对,则最后报告出错。,函数模板与重载函数,
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!