C对C性能的扩充

上传人:痛*** 文档编号:233653254 上传时间:2023-10-12 格式:PPTX 页数:61 大小:320.43KB
返回 下载 相关 举报
C对C性能的扩充_第1页
第1页 / 共61页
C对C性能的扩充_第2页
第2页 / 共61页
C对C性能的扩充_第3页
第3页 / 共61页
点击查看更多>>
资源描述
11.行注释在C+中,新增了行注释/sum.cpp/sum.cpp#include#include /编译预处理命令编译预处理命令using namespace std;using namespace std;/使用命令空间使用命令空间stdstdint main()int main()/主函数首部主函数首部 int x,y,sum;int x,y,sum;/定义定义3 3个整型变量个整型变量 coutPlease input two integers:n;coutPlease input two integers:x;/cinx;/从键盘输入变量从键盘输入变量x x的值的值 ciny;/ciny;/从键盘输入变量从键盘输入变量y y的值的值 sum=x+y;sum=x+y;/将将x+yx+y的值赋给整型变量的值赋给整型变量sumsum coutx+y=sumendl;coutx+y=sumendl;/输出两个整数的和输出两个整数的和sumsum return 0;return 0;/如程序正常结束如程序正常结束,/向操作系统返回一个数值向操作系统返回一个数值0 0 第1页/共61页2C C语言中我们用库函数语言中我们用库函数printfprintf和和scanfscanf对基本变量进行输对基本变量进行输入输出。如下程序:入输出。如下程序:2.数据的输入和输出数据的输入和输出#include void main()int a;scanf(%d,&a);printf(a=%dn,a);C+C+扩展了扩展了C C的输入输出,不但可用的输入输出,不但可用printfprintf、scanfscanf函数,还函数,还可以用输入输出流。可以用输入输出流。第2页/共61页3C+C+输入输出标准流流名流名含义含义默认设备默认设备流名流名含义含义默认设备默认设备cincin标准输入标准输入键盘键盘coutcout输出输出屏幕屏幕以上标准流为利用以上标准流为利用面向对象方法设计的输入输出流类面向对象方法设计的输入输出流类的对象的对象.使用使用cincin的格式的格式:cincin变量名变量名11变量名变量名22变量名变量名nn 使用使用coutcout的格式:的格式:coutcout表达表达11表达式表达式22n 第3页/共61页4#include int main()for(int i=1;i=3;i+)coutcount=iafc;couta=af=fc=cendl;return 0;例如:注:使用cin与cout必须在程序开头包含iostream头文件!第4页/共61页5C+C+输入输出流的优点简单易用,根据操作对象自适应,无需指定变量的类型;可对自定义的类型进行输入输出;提高了安全性和可扩展性。第5页/共61页63.数据类型枚举类型枚举类型 一般形式:enum 枚举类型名枚举列枚举变量表 C+中定义枚举变量时,不必在枚举名前加标识符enum 共用体类型共用体类型 同结构体类型,联合类型一旦定义,就可以直接使用联合名同结构体类型,联合类型一旦定义,就可以直接使用联合名定义变量,而不用在联合体名前加标识符定义变量,而不用在联合体名前加标识符unionunion。结构体类型:结构体类型:C+C+语言,结构体一旦定义,则可以直接使用该结构体名定义变量,语言,结构体一旦定义,则可以直接使用该结构体名定义变量,不需在结构体前加不需在结构体前加structstruct标识。如:标识。如:struct studentxxx;struct studentxxx;student stu;student stu;另外,另外,C+C+中的结构体类型所有的属性和方法都是公有的。中的结构体类型所有的属性和方法都是公有的。新增类类型新增类类型 C+中的中的struct作为特殊的类类型中不仅有属性数据还有成作为特殊的类类型中不仅有属性数据还有成员函数,但是所有访问属性都是公有。员函数,但是所有访问属性都是公有。第6页/共61页7C语言中我们都是用语言中我们都是用字符数组来表示字符串字符数组来表示字符串的,在的,在C+除了可以除了可以用字符数组表示外,我们还可以用用字符数组表示外,我们还可以用string类型来更方便的表示字符类型来更方便的表示字符串,串,string实质上是实质上是C+标准库标准库(stl)中用面向对象方法定义的字符串中用面向对象方法定义的字符串类,它并不是类,它并不是C+提供的基本类型。提供的基本类型。#include#include#include /#include /必须包含此头文件必须包含此头文件必须包含此头文件必须包含此头文件using namespace std;using namespace std;void main()void main()string str1;string str1;str1=abcdefg;str1=abcdefg;string str2=str1;/string str2=str1;/用一个字符串给另一个赋值用一个字符串给另一个赋值用一个字符串给另一个赋值用一个字符串给另一个赋值 coutstr1endl;/coutstr1endl;/对字符串进行输入输出对字符串进行输入输出对字符串进行输入输出对字符串进行输入输出 coutstr15endl;/coutstr15endl;/操作字符串中的单个字符操作字符串中的单个字符操作字符串中的单个字符操作字符串中的单个字符 str15=k;str15=k;coutstr1endl;coutstr1,=等运算符对字等运算符对字符串进行操作。符串进行操作。#include#include#include /#include /必须包含此头文件必须包含此头文件必须包含此头文件必须包含此头文件using namespace std;using namespace std;void main()void main()string str1=abcd;string str1=abcd;string str2=efgh;string str2=efgh;cout coutstr1+str2str1+str2endl;/endl;/字符串连接字符串连接字符串连接字符串连接 /字符串比较字符串比较字符串比较字符串比较 if(if(str1str2str1str2)coutstr1)coutstr1小于小于小于小于str2endl;str2endl;else coutstr1 else coutstr1大于等于大于等于大于等于大于等于str2endl;str2endl;第8页/共61页94.变量正确理解C中的变量的定义要求:一般应该集中定义出,不能在语句块中定义。程序例:void main()1.int x=1;/正确2.for(int i=0;i10;i+)/错误3.4.int y=2;5.6.第9页/共61页10(1)C+变量定义规则u可以采用“随用随定义”的方式定义出变量,即变量的块内定义uC+中允许变量在使用之前的任一语句块中定义出来,包括 for循环中何为块?块:C+语言把括起来的一块区域称为块。块变量:块变量:定义在某个块中的变量。块作用域:块作用域:变量定义的由花括号括起来的范围,块变量在其作用域可见,而在作用域外不可见。第10页/共61页11例如:1.#include2.void main(void)3.4.int x=1;/局部变量 5.6.int y;/块内变量 7.8.x=3;y=4;9.10.couty=yendl;11.void main(void)for(int i=1;i10;i+)int z=1;/块内变量 coutz=z;第11页/共61页12正确理解C+中的变量的各种作用域 文件域文件域全局变量全局变量(其作用域为从定义点到当前文件(其作用域为从定义点到当前文件结束有效)。结束有效)。函数域函数域局部变量局部变量(其作用域为本函数内有效)。(其作用域为本函数内有效)。函数原型域函数原型域函数的形参,为局部变量,只在该函数函数的形参,为局部变量,只在该函数体内有效。体内有效。块内域块内域块内定义的变量块内定义的变量(比局部变量的作用域更小)(比局部变量的作用域更小),块内定义的变量的作用域为从定义点到当前块内有,块内定义的变量的作用域为从定义点到当前块内有效,语句块执行完毕,自动释放。效,语句块执行完毕,自动释放。第12页/共61页13例如:1.int X=1;2.void Function(int a)3.int b=a;4.X=b;5.Y=X;6.7.void main()8.int Y=2;9.X=2;10.Function(X);11.for(int i=0;i10;i+)12.X=2;13.int C=0;14.15.X=2,Y=3;16.C=X;a=3;b=4;17./错误错误/正确正确/正确正确/正确正确/正确正确/错误错误 /全局变量全局变量 /函数的形参函数的形参 /局部变量局部变量/局部变量局部变量 /块定义的变量块定义的变量 /块定义的变量块定义的变量第13页/共61页14语句块内变量的应用目的 通过缩小变量的作用域来缩短变量的生存期,充分通过缩小变量的作用域来缩短变量的生存期,充分利用内存空间,优化内存的使用利用内存空间,优化内存的使用void main()int X;/局部变量 for(X=1;X10;X+)/在此时X才被释放void main()for(int X=1;X10;X+)/块内变量/在此时X就被释放第14页/共61页15(2)作用域运算符与命名空间C C语言中变量命名的要求:语言中变量命名的要求:在同一个程序中应该尽可能保持变量名的唯一性,最好不要同名。在同一个程序中应该尽可能保持变量名的唯一性,最好不要同名。#include iostream.hinclude iostream.hint X=1;int X=1;void main()void main()int X=2;int X=2;cout X;cout X;相同吗?此此时时输输出出的的X X值值是是为为“1 1”还是还是“2 2”系统系统采用同名覆盖原则采用同名覆盖原则决定,输出为决定,输出为2 2如果要输出全局变量如果要输出全局变量X X的值,怎么办的值,怎么办?第15页/共61页16C+中的全局作用域限定符 作用:作用:它能使程序员它能使程序员访问在某外部块中所访问在某外部块中所定义的全局变量定义的全局变量,以,以免被同名的局部变量免被同名的局部变量所覆盖。所覆盖。访问规则:访问规则:有有:限定限定的同名符号是全局变的同名符号是全局变量,无量,无:限定的同名限定的同名符号是局部变量。符号是局部变量。#include include int X=1;int X=1;void main()void main()int X=2;int X=2;cout cout local X=local X=Xendl;Xendl;/未限定时的符号名为局部未限定时的符号名为局部 /符号名符号名 cout global X=:X;cout global X=:X;/采用采用“:”限定时的符号名为全限定时的符号名为全/局符号名局符号名 第16页/共61页17全局作用域限定符的编程规则(1 1)只能将只能将“:”放在具有全局符号名说明的变量名之前,不能放在放在具有全局符号名说明的变量名之前,不能放在无全局符号名说明的局部变量名之前。无全局符号名说明的局部变量名之前。int X=1;int X=1;void main(void)void main(void)int X=2;int X=2;int Y=3;int Y=3;:X=10;:X=10;/正确,因为有同名的全局符号名说明正确,因为有同名的全局符号名说明 :Y=4;Y=4;/错误,因为无同名的全局符号名说明错误,因为无同名的全局符号名说明 全局作用域限定符全局作用域限定符“:”不仅可以限定变量,也可以用来限定函不仅可以限定变量,也可以用来限定函数数第17页/共61页18名字空间-解决解决不同模块相同名字冲突问题不同模块相同名字冲突问题。一个名字空间可以看作一个比程序模块更大的包一个名字空间可以看作一个比程序模块更大的包。格式:格式:Namespace ModuleNameNamespace ModuleName 注:注:一个给定名字空间的所有代码可以位于同一个文件中,一个给定名字空间的所有代码可以位于同一个文件中,也可以分布在多个文件中,但是在每一个文件中代码都要按照也可以分布在多个文件中,但是在每一个文件中代码都要按照上述语句格式进行封装。上述语句格式进行封装。其作用域有两方面的含义:其作用域有两方面的含义:(1 1)同一个名字空间作用域内不允许存在同名标识符;)同一个名字空间作用域内不允许存在同名标识符;(2 2)不同名字空间作用域内的标识符不能直接调用,)不同名字空间作用域内的标识符不能直接调用,需要需要添加名字空间的作用域限定运算符添加名字空间的作用域限定运算符。第18页/共61页19例如:/a.h#includenamespace A 函数f1 函数f2变量s;若要在若要在A A名字空间外,调用名字空间外,调用f1f1、f2f2函数和函数和变量变量s s,如何表达?如何表达?方法方法1 1:A:f1();A:f1();方法方法2 2:#include“A.h”#include“A.h”void main()void main()using namespace A;using namespace A;f1();/f1();/名字空间名字空间A A中的函数中的函数 第19页/共61页20(3 3)用)用constconst关键字定义常变量关键字定义常变量在在C语言中我们用语言中我们用#define宏命令来定义常量,宏命令来定义常量,define只是在编译时进行字符串替换,只是在编译时进行字符串替换,运行时系统不为其分配内存空间运行时系统不为其分配内存空间。用它有时。用它有时会出现意想不到的错误。如下所示:会出现意想不到的错误。如下所示:#include#define PI 3#define R a+bint main()int a=2;int b=3;coutPI*R*R;return 1;程序输出程序输出15而不是想要的而不是想要的75的结构。的结构。因为因为PI*R*R被展开为了被展开为了3*a+b*a+b=15。因此因此C+提供了提供了const关键字来定义常关键字来定义常变量,用变量,用const定义的常变量具有变量定义的常变量具有变量量的一些属性。(有数据类型、占用量的一些属性。(有数据类型、占用内存空间、具有地址、可以用指针来内存空间、具有地址、可以用指针来指向它等),唯一和变量不同的是它指向它等),唯一和变量不同的是它的值的值只能在定义时指定只能在定义时指定。以后就不能。以后就不能通过任何形式改变。通过任何形式改变。第20页/共61页21#include#define PI 3 /没有类型,不占用存储单元没有类型,不占用存储单元const int R=2+3;/有类型,有存储单元有类型,有存储单元int main()int a=2;int b=3;coutPI*R*Rendl;return 1;改进:改进:第21页/共61页22#include const float PI=3.1415926f;int main()float r;cout请输入圆的半径值:请输入圆的半径值:(负值退出负值退出)r;while(r=0)cout半径为半径为r的圆的面积为:的圆的面积为:PI*r*r,周长为:周长为:2*PI*rendl;cout请输入圆的半径值:请输入圆的半径值:(负值退出负值退出)r;return 1;例:例:分析如下程序的功能分析如下程序的功能第22页/共61页23const定义常量constconst 类型类型 常量名常量名=表达式表达式;或或 类型类型 const const 常量名常量名=表达式表达式;例如:例如:constconst double pi=3.14;double pi=3.14;和和 double double constconst pi=3.14;pi=3.14;两者两者等价等价!constconst定义数组常量定义数组常量:const int a5=1,2,3,4,5;const int a5=1,2,3,4,5;注:注:const定义常量必须初始化。定义常量必须初始化。第23页/共61页24常量与指针一起使用 (1 1)指向常量的指针)指向常量的指针 const char*name=chen;name2=i;?name=stu;?(2 2)常指针)常指针char*const name=chen例如:name=stu;name1=2;第24页/共61页25常量与指针一起使用(3)指向常量的常指针注:const定义一个整型常量,关键字int可以省略。const char*const name=”chen”;name2=i;?name=”stu”;?第25页/共61页26区分C语言中的#define与C+中的const的不同 1.由#define所定义的符号名为全局性常量,因而在整个程序中应保持符号名的唯一性;2.const可以说明一个局部或全局性同名常量(据此可以改变const符号名之值)。3.另外在语法方面,#define为编译预处理命令,而const为定义符,语句以“;”结束。#define Min 1const int Max=100;void main(void)#define Min 2 /错误,不能再定义同名常量 const int Max=200;/可以再定义同名局部常量 第26页/共61页27(4)函数形式上的转换任何系统定义的基本数据类型或用户自定义的任何系统定义的基本数据类型或用户自定义的数据类型数据类型的名字,的名字,都可作为都可作为函数函数使用,从而把变量(常量)从一种数据类型转换使用,从而把变量(常量)从一种数据类型转换到另一种数据类型。到另一种数据类型。例如:例如:int i=20;float x;x=int(i);int i=20;float x;x=int(i);(在(在C语言中则错误)语言中则错误)第27页/共61页28 C C语言要求如果函数调用在函数定义之前,则应在函数调用之前对所调用的函语言要求如果函数调用在函数定义之前,则应在函数调用之前对所调用的函数进行函数声明,但如果函数的返回值为整型,也可以不进行声明。如下例所示:数进行函数声明,但如果函数的返回值为整型,也可以不进行声明。如下例所示:#include int max(int a,int b);/函数声明函数声明void main()int a=max(2,3);printf(%d,a);int max(int a,int b)if(a=b)return a;else return b;int max(int a,int b);就是对后面就是对后面max函函数的声明。由于数的声明。由于max函数的返回值为整型,函数的返回值为整型,所以这里的声明也可以不要。但如果所以这里的声明也可以不要。但如果max的返回值不是整型,这必须对其进行声明。的返回值不是整型,这必须对其进行声明。声明可以采用以下几种形式:声明可以采用以下几种形式:int max(int a,int b);/原型声明原型声明int max();/无参声明无参声明max();/无参无返回值声明无参无返回值声明5.函数第28页/共61页29(1)C+中的函数声明中的函数声明在在C+如果函数调用在函数定义之前。则必须在如果函数调用在函数定义之前。则必须在调用之前对其进行的函数声明调用之前对其进行的函数声明(返回值为返回值为int的函数也必须声明的函数也必须声明)。而且必须采用函数原型声明的形式。而且必须采用函数原型声明的形式。#include int max(int a,int b);int main()int a=max(2,3);couta=b)return a;elsereturn b;C+C+中函数声明必须采用函数中函数声明必须采用函数原型的形式:原型的形式:返回值返回值 函数名函数名(形参表形参表);但在但在C+C+中函数的声明可以只中函数的声明可以只有形参类型,而没有形参。如左有形参类型,而没有形参。如左边的例子中也可将函数申明写为:边的例子中也可将函数申明写为:int max(int int);int max(int int);要区分函数的要区分函数的定义定义、声明声明和和调调用用以及它们的作用。以及它们的作用。第29页/共61页30(2)C+中函数的重载中函数的重载函数重载:函数重载:C+C+中允许在同一作用域中用中允许在同一作用域中用同一函数名定义多个函数同一函数名定义多个函数(C C语语言中不可以)言中不可以)。这些函数的。这些函数的参数个数和参数类型不同参数个数和参数类型不同。例例1 1:跟据参数类型的不同进行重载:跟据参数类型的不同进行重载#include int max(int a,int b)if(a=b)return a;else return b;float max(float a,float b)if(a=b)return a;else return b;int main()int ia,ib;float fa,fb;ciniaib;coutmax(ia,ib)fafb;coutmax(fa,fb)endl;第30页/共61页31例例2:跟据参数个数的不同进行重载:跟据参数个数的不同进行重载#include using namespace std;int max(int a,int b)if(a=b)return a;else return b;int max(int a,int b,int c)if(ba)a=b;if(ca)a=c;return a;int main()int ia,ib,ic;ciniaibic;coutmax(ia,ib)endl;coutmax(ia,ib,ic)endl;由以上两个例子的分析可以得出:由以上两个例子的分析可以得出:对重载的函数进行调用时,主对重载的函数进行调用时,主要根据函数参数类型和个数的不同来确定具体应该调用那一个函数要根据函数参数类型和个数的不同来确定具体应该调用那一个函数。重载的函数能否仅仅只有返回值不同而形参完全相同?重载的函数能否仅仅只有返回值不同而形参完全相同?调用重载函数时,函数返回值类型不在参数匹配检查之列调用重载函数时,函数返回值类型不在参数匹配检查之列 第31页/共61页32(3)默认参数的函数)默认参数的函数C C语言,函数调用时传给函数的语言,函数调用时传给函数的实参个数必须与形参的个数相同实参个数必须与形参的个数相同,但,但C+C+可以让形可以让形参带有默认的值参带有默认的值,从而可以让传递给函数的形参个数少于实参的个数。称为从而可以让传递给函数的形参个数少于实参的个数。称为默认参数默认参数。这种机制有时候给我们带来很大的方便。尤其是在面向对象编程时类的构造函数。这种机制有时候给我们带来很大的方便。尤其是在面向对象编程时类的构造函数。#include void GetDate(int day,int month=3,int year=2011)coutyear/month/dayendl;int main()GetDate(20);GetDate(20,5);GetDate(20,5,2012);return 1;程序输出:程序输出:2011/3/202011/5/202012/5/20第32页/共61页33实参与形参的结合是以实参与形参的结合是以从左到右从左到右的顺序进行的,第一个实参的值必须传递给第的顺序进行的,第一个实参的值必须传递给第一个形参,第二个实参必然与第二个形参相结合。所以带函数的默认参数必须按从一个形参,第二个实参必然与第二个形参相结合。所以带函数的默认参数必须按从右右到左到左的顺序进行默认。例如如下的函数默认参数是错误的。的顺序进行默认。例如如下的函数默认参数是错误的。Fun(int a,int b=2,int c,int d=3);Fun(int a,int b=2,int c,int d=3);/错误错误默认参数的次序默认参数的次序由以上的讨论我们可以发现,由以上的讨论我们可以发现,在有默认参数的函数中,实参的个数可以少于形在有默认参数的函数中,实参的个数可以少于形参的个数,但实参的个数不能少于形参中没有默认的参数的个数。参的个数,但实参的个数不能少于形参中没有默认的参数的个数。带默认值的函数的功能可以由函数的重载来实现!带默认值的函数的功能可以由函数的重载来实现!第33页/共61页34使用带默认参数的函数时应注意的问题使用带默认参数的函数时应注意的问题(1 1)如果函数的定义在函数的调用之前,则应在)如果函数的定义在函数的调用之前,则应在函数的定义中给出形函数的定义中给出形参的默认值参的默认值。如果函数的定义在函数的调用之后,则应在函数声明中给出参。如果函数的定义在函数的调用之后,则应在函数声明中给出参数的默认值,而在函数的定义中可以给出也可以不给出(视编译器而定,例数的默认值,而在函数的定义中可以给出也可以不给出(视编译器而定,例如如VC6.0VC6.0中则中则只能在函数声明中给出,而在函数定义中不能给出默认参数只能在函数声明中给出,而在函数定义中不能给出默认参数)。)。为了避免混淆,我们为了避免混淆,我们最好只在函数声明中给出默认参数最好只在函数声明中给出默认参数。(2 2)函数名重载时最好不要用缺省参数,否则会引起二义性函数名重载时最好不要用缺省参数,否则会引起二义性。例如:。例如:GetDate(int day,int month=4,int year=2008);GetDate(int day,int month=4,int year=2008);GetDate(int day);GetDate(int day);则如果有一个函数调用则如果有一个函数调用GetDate(20),GetDate(20),系统无法判断应该调用哪一个函数系统无法判断应该调用哪一个函数(编译报错编译报错)。但如果第二个函数改为:)。但如果第二个函数改为:GetDate(int dat,int month,int year,int hour);GetDate(int dat,int month,int year,int hour);则不会出现以上混淆。则不会出现以上混淆。第34页/共61页35(4)内联函数(内置函数)内联函数(内置函数)对函数的调用需要一定的时间和空间开销,对于有些需要频繁调用的对函数的调用需要一定的时间和空间开销,对于有些需要频繁调用的函数这种开销会累积起来。函数这种开销会累积起来。C+C+对此提供了一种解决方法对此提供了一种解决方法内联函数内联函数。内联函数:内联函数:在编译时将被调函数的代码嵌入到主调函数中。这种嵌入在编译时将被调函数的代码嵌入到主调函数中。这种嵌入到主调函数中的函数称为内联函数。定义内联函数只需在函数定义的前面到主调函数中的函数称为内联函数。定义内联函数只需在函数定义的前面加上关键字加上关键字 inlineinline.#include#include using namespace std;using namespace std;inlineinline int max(int a,int b);int max(int a,int b);void main()void main()int a=max(2,3);int a=max(2,3);coutaendl;couta=b)return a;if(a=b)return a;else return b;else return b;第35页/共61页36使用内联函数应注意:内联函数必须在函数第一次出现时由内联函数必须在函数第一次出现时由inlineinline指定;指定;内联函数代码不宜太大,原则上适宜内联函数代码不宜太大,原则上适宜1-51-5行代码的小函数;行代码的小函数;不能含有复杂的分支和循环等语句。不能含有复杂的分支和循环等语句。递归调用函数不能定义为内联函数。递归调用函数不能定义为内联函数。i;p=(int*)malloc(sizeof(int)*i);void main()f();for(int j=0;ji;j+)pj=j*10;coutpjendl;free(p);6.6.动态分配动态分配/撤销内存的运算符撤销内存的运算符newnew和和deletedeleteC C语言中动态内存的分配与使用语言中动态内存的分配与使用(堆区堆区)/分配单个堆区变量分配单个堆区变量#include#includevoid main()int*p;p=(int*)malloc(sizeof(int);*p=4;cout*pendl;free(p);第37页/共61页38动态分配动态分配/撤销内存的运算符撤销内存的运算符new和和deleteC C语言中使用库函数语言中使用库函数mallocmalloc和和freefree,进行内存分配和撤销,进行内存分配和撤销,mallocmalloc只能由用户给出大小来分配内存只能由用户给出大小来分配内存而不能自己确定数据类型,而不能自己确定数据类型,所以不适合面向对象自定义类型,所以不适合面向对象自定义类型,C+C+提供了提供了newnew和和deletedelete运算符运算符来来对内存进行动态分配和撤销(任兼容对内存进行动态分配和撤销(任兼容C C语言的语言的mallocmalloc和和freefree函数)。函数)。new和和delete的用法:的用法:#include using namespace std;void main()int*p;p=new int;*p=4;cout*pi;p=new inti;void main()f();for(int j=0;ji;j+)pj=j*10;coutpjendl;deletep;第38页/共61页397.引用类型引用类型引用:引用:就是给变量起一个别名,别名的定义,同一实体,两个不同的名称。就是给变量起一个别名,别名的定义,同一实体,两个不同的名称。C+中的引用中的引用:同一内存单元两种不同的变量名。:同一内存单元两种不同的变量名。通过引用,可以实现在不同的作用域内访问同一内存单元。通过引用,可以实现在不同的作用域内访问同一内存单元。第39页/共61页40void main()int x=1;fun(x);void fun(int&a)a=3;您知道x与a是什么关系吗?第40页/共61页41引用定义的语法q类型定义符类型定义符&变量名原变量名;变量名原变量名;int a=3;int&ra=a;(声名声名ra为为a的引用,的引用,ra就是就是a,a就是就是ra.改变改变了了ra就改变了就改变了a,改变了改变了a也就改变了也就改变了ra);即即ra与与a为为同同一一个个变变量量,但但在在不不同同的的应应用用场场合合下下(作用域内)以不同的变量名出现。(作用域内)以不同的变量名出现。第41页/共61页42必须定义的同时使之初始化必须定义的同时使之初始化。引用并不另开辟内存空间引用并不另开辟内存空间。声明了一个变量的引用后,就声明了一个变量的引用后,就不能在将其改为别的变量的引用不能在将其改为别的变量的引用。如下。如下程序。程序。#include using namespace std;int main()int a=2,b=3;int&ra=a;ra=b;/?b=6;couta=aendlb=bendlra=raendl;声明 对一个一般变量的引用第42页/共61页43引用实际上是一隐指针,是对变量的间接引用,但引用实际上是一隐指针,是对变量的间接引用,但不必加运算符不必加运算符“*“*“。引用不同于其他变量。引用不同于其他变量。不能定义引用数组不能定义引用数组;如:如:int&x10int&x10错误。错误。不能建立指向引用的指针不能建立指向引用的指针;如:;如:int&*pint&*p错误。错误。不能建立引用的引用不能建立引用的引用;如:如:int&xint&x;错误。;错误。int i;int&j=i;int*p=&j;?第43页/共61页44为什么要提供引用操作符 C+中的引用主要是用来解决函数调用中中的引用主要是用来解决函数调用中形参为形参为指针型的参数时其函数体时的不安全性(易出指针型的参数时其函数体时的不安全性(易出错),错),使得操作更加简单、安全。使得操作更加简单、安全。例如:第44页/共61页45 int add(int&X,int&Y)X=X+Y;return X;void main()int a=1,b=2;add(a,b);int add(int*X,int*Y)int add(int*X,int*Y)*X=*X+*Y;*X=*X+*Y;return*X;return*X;void main()void main()int a=1,b=2;int a=1,b=2;add(&a,&b);add(&a,&b);改进为第45页/共61页46引用调用的优点 通过引用调用可以提高调用速度,因为通过引用调用可以提高调用速度,因为只需要传送地址只需要传送地址而不需要直接将大量数据拷贝,因而特别适用于形参而不需要直接将大量数据拷贝,因而特别适用于形参为大量数据的应用场合。为大量数据的应用场合。struct Datastruct Data int a1000;int a1000;AData;AData;void fun(struct Data X)void fun(struct Data X)struct Datastruct Data int a1000;int a1000;AData;AData;void fun(struct Data&X)void fun(struct Data&X)改进为改进为您知道为什么要这您知道为什么要这样做呢?样做呢?第46页/共61页47正确区分传值调用与传地址调用 C语言中,函数参数传递有两种方式:语言中,函数参数传递有两种方式:变量名作实参变量名作实参和和变变量地址作实参量地址作实参。C+中有扩充了一种中有扩充了一种变量引用作实参变量引用作实参。下面分。下面分别回顾一下:别回顾一下:(1 1)变量名作实参变量名作实参 变量名作实参变量名作实参就是直接将变量或变量的值传递给函就是直接将变量或变量的值传递给函数的形参。这种方式在函数栈中为形参分配空间。并将实参数的形参。这种方式在函数栈中为形参分配空间。并将实参的值复制到该空间中的值复制到该空间中,因为因为实参和形参在不同的空间实参和形参在不同的空间,所以传,所以传递是递是单向单向的。只能由实参将值复制给形参,形参的改变不影的。只能由实参将值复制给形参,形参的改变不影响实参的值。响实参的值。第47页/共61页48例如:例如:#include#include void swap(int a,int b);void swap(int a,int b);int main()int main()int a=2,b=4;int a=2,b=4;swap(a,b);swap(a,b);couta=ab=bendl;couta=ab=bendl;return 1;return 1;void swap(int a,int b)void swap(int a,int b)int temp=a;int temp=a;a=b;a=b;b=temp;b=temp;程序输出:程序输出:a=2 b=4;a=2 b=4;可见可见swapswap函数并不能实现将实参交换的作用。函数并不能实现将实参交换的作用。第48页/共61页49(2 2)变量地址作实参变量地址作实参 变量地址作实参变量地址作实参是将函数的参数定义为是将函数的参数定义为指针类型指针类型,调用函数的时候将变量的地址作为实参传递给函数。这种传调用函数的时候将变量的地址作为实参传递给函数。这种传值方式也是单向传递,但和变量名作实参不同的是值方式也是单向传递,但和变量名作实参不同的是它将实参它将实参变量的内存地址复制给形参变量的内存地址复制给形参。所以可以在函数栈中直接通过。所以可以在函数栈中直接通过变量地址来改变实参的值。变量地址来改变实参的值。第49页/共61页50#include#include using namespace std;using namespace std;void swap(int*a,int*b);void swap(int*a,int*b);int main()int main()int a=2,b=4;int a=2,b=4;swap(&a,&b);/swap(&a,&b);/传递变量地址传递变量地址传递变量地址传递变量地址couta=a b=bendl;couta=a b=bendl;return 1;return 1;void swap(int*pa,int*b)void swap(int*pa,int*b)int temp=*pa;int temp=*pa;*pa=*pb;*pa=*pb;*pb=temp;*pb=temp;程序输出:程序输出:a=4 b=2;a=4 b=2;可见可见swapswap函数实现了将实参交换的作用。函数实现了将实参交换的作用。间接间接的实现了的实现了函数传参的双向传递函数传参的双向传递。第50页/共61页51()()变量引用作实参变量引用作实参 变量引用作实参变量引用作实参是将函数的参数定义为引用类型,是将函数的参数定义为引用类型,调用函数的时候将变量名作为调用函数的时候将变量名作为实参传递给函数实参传递给函数。这种传值方。这种传值方式是式是双向传递双向传递,实参和形参共享同一内存空间。,实参和形参共享同一内存空间。改变了形参改变了形参也就改变了实参也就改变了实参。第51页/共61页52#include#include using namespace std;using namespace std;void swap(int&a,int&b);void swap(int&a,int&b);int main()int main()int a=2,b=4;int a=2,b=4;swap(a,b);swap(a,b);couta=a b=bendl;couta=a b=bendl;return 1;return 1;void swap(int&a,int&b)void swap(int&a,int&b)int temp=a;int temp=a;a=b;a=b;b=temp;b=temp;程序输出:程序输出:a=4 b=2;a=4 b=2;可见可见swapswap函数实现了将实参交换的作用。这种函数实现了将实参交换的作用。这种传参方式和变量名作参数的唯一不同是定义函数时传参方式和变量名作参数的唯一不同是定义函数时将形参声名为引用类型。将形参声名为引用类型。其余都和变量名作参数完全相同其余都和变量名作参数完全相同。第52页/共61页53区分引用在如下两种场合的差别 (1)对一般的变量进行引用对一般的变量进行引用:如引用的变量不是用作函数如引用的变量不是用作函数的形参或返回值,则声明时的形参或返回值,则声明时必须加以初始化以指明它的必须加以初始化以指明它的同地址变量。同地址变量。void main(void)int X=3;int&refX=X;fun(refX);cout X;/X的值被改变为的值被改变为4 void fun(int&a)a+;/a为为refX的引用的引用 第53页/共61页54int add(int&X=1,int&Y=2)X=X+Y;return X;正确的参数声正确的参数声明明错误的参数声明错误的参数声明(2)函数的形参为引用函数的形参为引用:如引用的变量用作函数的形参或返:如引用的变量用作函数的形参或返回值,则说明时回值,则说明时不要不要加以初始化以指明它的同地址变量,此加以初始化以指明它的同地址变量,此时形参为实参的引用。时形参为实参的引用。int add(int&X,int&Y)X=X+Y;return X;第54页/共61页55函数形参定义为引用参数时的调用要求 int add(int&a,int&b)return a+b;void main()int X=1,Y=2;add(X,Y);/调用正确调用正确 add(1,2);/调用错误调用错误 您知道为什您知道为什么错误吗?么错误吗?调用时实参调用时实参不能为常量而必须不能为常量而必须为赋已知值的变量为赋已知值的变量。因为编译。因为编译器无法为常量(无内存地址)器无法为常量(无内存地址)建立内存地址,从而无法产生建立内存地址,从而无法产生引用。引用。同时在函数调用时系统将同时在函数调用时系统将实参实参地址地址拷贝到形参,从而使形参拷贝到形参,从而使形参即为实参,但在函数体内采用即为实参,但在函数体内采用形参名来访问它。形参名来访问它。第55页/共61页56函数形参为引用参数时的编程效果#include iostream.hvoid IncValue(int&X);void main()int A=1;IncValue(A);cout The Value of A Is:Aendl;void IncValue(int&X)X=X+1;/表面上为改变表面上为改变 X的值,其实是改变的值,其实是改变 /了了main()内的内的A的值的值?其一其一能在一能在一个函数体内个函数体内访问或修改访问或修改另一个函数另一个函数体内定义的体内定义的变量的值变量的值第56页/共61页57其二是能使某一函数间接实现“多个返回值”(因为在正常情况下,函数只能实现返回一个值)#include void Calculate(int R,float&Len,float&Area);void main()int R=10;float Length,Area;/定义时未赋值 Calculate(R,Length,Area);coutCircle Length=Length;/经调用后它们被赋值 coutCircle Area=Area;void Calculate(int R,float&Len,float&Area)Area=3.1415*R*R;/Area引用到Area Len=2*3.1415*R;/Len引用到Length 第57页/共61页58函数的返回值也可以声明为引用#include iostream.hint&fun(int Num,int array)/函数的返回值声明为引用函数的返回值声明为引用 int&ref=arrayNum;/获取对数组中的指定元素值的引用获取对数组中的指定元素值的引用 return ref;void main()int A5=1,2,3,4,5;/A2的值为的值为3 fun(2,A)=55;/将将A2的值改变为的值改变为55 cout fun(2,A);/显示显示A2的值为的值为55您知道为什么值为您知道为什么值为55吗?吗?C+中不仅中不仅函数的形参函数的形参可以定义为可以定义为引用,而且引用,而且函数的返回函数的返回值也可以声值也可以声明为引用,明为引用,这可以使函这可以使函数调用的表数调用的表达式用于左达式用于左值。值。第58页/共61页59本章小结行注释行注释输入输出输入输出数据类型数据类型:重点学会重点学会stringstring类型的使用类型的使用变量:重点掌握命名空间与作用域变量:重点掌握命名空间与作用域函数:函数:函数原型、重载、缺省参数、内联函数函数原型、重载、缺省参数、内联函数newnew与与deletedelete运算符运算符引用类型:引用类型:扩展视野,试着掌握它,会带来事半功倍扩展视野,试着掌握它,会带来事半功倍的的效果效果第59页/共61页60本章课外作业1.15-1.18第60页/共61页61感谢您的观赏!第61页/共61页
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


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

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


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