




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、掌握C+言语在构造化程序设计(非面向对象)方面对C言语扩展的性能,为编写面向对象的C+程序打下根底。2.1 C+的特点的特点2.2 C+言语的文件扩展名言语的文件扩展名2.3 注释符注释符2.4 名字空间名字空间2.5 C+言语的输入输出言语的输入输出2.6 变量的定义变量的定义2.7 强迫类型转换强迫类型转换2.8 动态内存的分配与释放动态内存的分配与释放2.9 作用域运算符作用域运算符:2.10 援用援用2.11 const修饰符修饰符2.12 字符串字符串2.13 C+言语中函数的新特性言语中函数的新特性习题习题2.1 C+的发明人的发明人 Bjarne Stroustrup(本贾尼斯特
2、劳斯特卢普)博士,C+言语之父,1950年出生于丹麦,1979年在英国剑桥大学获得计算机科学博士学位,AT&T、贝尔实验室和ACM成员。1979年,B. S开场开发一种言语,当时称为“C with Class,1983年演化为C+。2019年,ANSI/ISO C+规范建立,同年,B. S推出了其经典著作The C+ Programming Language的第三版。 Stroustrup博士是C+言语的设计者和第一位实现者,该言语业已成为世界上最通用的支持面向对象技术的程序设计言语。2.1 C+开发工具的历史开发工具的历史90年代初的年代初的Turbo C+2.1 C+开发工具的历史
3、开发工具的历史90年代中期的年代中期的Borland C+ for dos 2.1 C+开发工具的历史开发工具的历史90年代中期的年代中期的Borland C+ Builder for Win 2.1 C+开发工具的历史开发工具的历史21世纪的世纪的visual C+ 6.0 2.1 C+开发工具的历史开发工具的历史visual studio 2019 2.1 C+的特点的特点 C+言语既保管了言语既保管了C言语的有效性、灵敏性、言语的有效性、灵敏性、便于移植等全部精华和特点,又添加了面向对象便于移植等全部精华和特点,又添加了面向对象编程的支持,具有强大的编程功能,可方便地构编程的支持,具有强
4、大的编程功能,可方便地构造出模拟现实问题的实体和操作;编写出的程序造出模拟现实问题的实体和操作;编写出的程序具有构造明晰、易于扩展等优良特性,适宜于各具有构造明晰、易于扩展等优良特性,适宜于各种运用软件、系统软件的程序设计。用种运用软件、系统软件的程序设计。用C+编写编写的程序可读性好,生成的代码质量高,运转效率的程序可读性好,生成的代码质量高,运转效率仅比汇编言语慢仅比汇编言语慢10%20%。 为了使编译器可以区别是为了使编译器可以区别是C C言语还是言语还是C+C+言语,言语,C+C+言语体系规定用言语体系规定用“.cpp“.cpp( (意即意即C Plus-Plus)C Plus-Plu
5、s)作为作为C+C+言语源文件的扩展名以区别于言语源文件的扩展名以区别于C C言语用的言语用的“.C“.C文件扩展名。虽然仅差两个字母,但编译文件扩展名。虽然仅差两个字母,但编译时的处置却相差甚远。时的处置却相差甚远。 “cpp “cpp的文件扩展名与的文件扩展名与操作系统无关。与操作系统无关。与C+C+言语源文件相关的头文件扩言语源文件相关的头文件扩展名普通仍用展名普通仍用“.h“.h,但有些操作系统也有规定,但有些操作系统也有规定运用运用“.hpp“.hpp充任头文件扩展名的。充任头文件扩展名的。 1. 1. 段注释:段注释: / /* * */ / 2. 2. 单行注释:单行注释:/ /
6、 当只做单行注释时便当只做单行注释时便可用可用“/“/符号表示从此符号起至行尾均符号表示从此符号起至行尾均为行注释内容。为行注释内容。 3. 3. 程序编译时将忽略一切的注释内容。程序编译时将忽略一切的注释内容。 名字空间域是随规范名字空间域是随规范C+C+而引入的。它相当而引入的。它相当于一个更加灵敏的文件域全局域,可以用于一个更加灵敏的文件域全局域,可以用花括号把文件的一部分括起来,并以关键字花括号把文件的一部分括起来,并以关键字namespacenamespace开头给它起一个名字:开头给它起一个名字:namespace ns1namespace ns1 float a,b,c; flo
7、at a,b,c; fun1() fun1() 花括号括起来的部分称声明块。声明块中可以包括:花括号括起来的部分称声明块。声明块中可以包括:类、变量带有初始化、函数带有定义等。在域外类、变量带有初始化、函数带有定义等。在域外运用域内的成员时,需加上名字空间名作为前缀,后面加运用域内的成员时,需加上名字空间名作为前缀,后面加上域操作符上域操作符“:“: 。这里添加了名字空间称号的成员名。这里添加了名字空间称号的成员名被称为限定修饰名。如:被称为限定修饰名。如:ns1:ans1:a,ns1:fun1()ns1:fun1()等等。等等。 最外层的名字空间域称为全局名字空间域最外层的名字空间域称为全局
8、名字空间域global global namespace scopenamespace scope,即文件域。,即文件域。名字空间域可分层嵌套,同样有分层屏蔽作用。例如:名字空间域可分层嵌套,同样有分层屏蔽作用。例如:namespace n1namespace n1 namespace n2 namespace n2 / / 名字空间嵌套名字空间嵌套 class matrix class matrix / / 名字空间类成员名字空间类成员matrixmatrix 访问访问matrixmatrix,可写:,可写:n1:n2:matrix n1:n2:matrix 。运用运用usingusing声
9、明可只写一次限定修饰名。声明可只写一次限定修饰名。usingusing声明以关键声明以关键字字usingusing开头,后面是被限定修饰的开头,后面是被限定修饰的qualifiedqualified名字空名字空间成员名,例如:间成员名,例如:using n1:n2:matrix;using n1:n2:matrix;/ / 名字空间类成员名字空间类成员matrixmatrix的的usingusing声明声明以后在程序中运用以后在程序中运用matrixmatrix时,就可以直接运用成员名,而时,就可以直接运用成员名,而不用运用限定修饰名。不用运用限定修饰名。运用运用usingusing指示符可以
10、一次性地使名字空间中一切成员都指示符可以一次性地使名字空间中一切成员都可以直接被运用,比可以直接被运用,比usingusing声明方便。声明方便。usingusing指示符以关键指示符以关键字字usingusing开头,后面是关键字开头,后面是关键字namespacenamespace,然后是名字空间,然后是名字空间名。名。 规范规范C+C+库中的一切组件都是在一个被称为库中的一切组件都是在一个被称为stdstd的名字空间中声明和定义的。在采用规范的名字空间中声明和定义的。在采用规范C+C+的平台上运用规范的平台上运用规范C+C+库中的组件,只需写库中的组件,只需写一个一个usingusing
11、指示符:指示符: using namespace std; using namespace std; 就可以直接运用规范就可以直接运用规范C+C+库中的一切成员。库中的一切成员。 留意:假设运用了名空间留意:假设运用了名空间stdstd,那么在运用,那么在运用#include#include编译预处置命令包含头文件时,必需编译预处置命令包含头文件时,必需去掉头文件的扩展名去掉头文件的扩展名.h.h,否那么会出错。,否那么会出错。C+言语另外定义了一套流对象与运算符来替代言语另外定义了一套流对象与运算符来替代C言语中对规范输入输出函数言语中对规范输入输出函数scanf和和printf的援用。的援
12、用。C+言语的保管字为:言语的保管字为:cout“输出内容输出内容“输入内容输入内容;/cin为规范输入流对象为规范输入流对象(默许从键盘输入默许从键盘输入)#include 输入重定向输入重定向【例【例2.1】C+的输入输出举例。的输入输出举例。#include / 运用名空间运用名空间std,那么必需去掉,那么必需去掉.h扩展扩展名名using namespace std; void main() char name10; int age; coutname; coutage; coutname is nameendl; coutage is ageendl;补充补充(写出程序执行结果,假
13、定输入写出程序执行结果,假定输入1和和2)#include / 运用名空间运用名空间std,那么必需去掉,那么必需去掉.h扩展扩展名名using namespace std; void main() char ch1,ch2;int n1,n2;cinch1ch2;n1=ch1-0;n2=n1*10+(ch2-0);coutn2;补充补充(写出程序执行结果写出程序执行结果)#include / 运用名空间运用名空间std,那么必需去掉,那么必需去掉.h扩展扩展名名#includeusing namespace std; void main() int n,count=0;for(n=1;n=1
14、00;+n)coutsetfill(*)setw(10)n;count+;if(count%5=0) coutendl;程序执行结果程序执行结果 在在C C言语中,部分变量阐明必需置于可执行代码段之前,言语中,部分变量阐明必需置于可执行代码段之前,不允许部分变量声明和可执行代码混合在一同。但不允许部分变量声明和可执行代码混合在一同。但C+C+在变量的定义上作了两种较大的改动,一是允许变量的在变量的定义上作了两种较大的改动,一是允许变量的定义语句可以出如今程序的任何位置,使得部分变量的定义语句可以出如今程序的任何位置,使得部分变量的定义点与运用点不至于离得太远,加强程序的可读性,定义点与运用点不
15、至于离得太远,加强程序的可读性,而且也不用在编写某一程序块的开场时就思索要用到哪而且也不用在编写某一程序块的开场时就思索要用到哪些变量;二是允许直接运用构造体名定义变量,这种扩些变量;二是允许直接运用构造体名定义变量,这种扩展为程序员在编程中提供了不少方便。类似地在展为程序员在编程中提供了不少方便。类似地在C+C+言言语中结合名、枚举名也可在定义后独立地作为类型名运语中结合名、枚举名也可在定义后独立地作为类型名运用。用。格式:格式:(数据类型数据类型) (表达式表达式)数据类型数据类型 (表达式表达式)(1) (1) 经过强迫类型转换,得到一个所需类型的中间值,经过强迫类型转换,得到一个所需类
16、型的中间值,该中间值被援用后即自动释放。原来表达式的值类型并该中间值被援用后即自动释放。原来表达式的值类型并未改动。如以下代码段:未改动。如以下代码段:int b;float f;f=float(b);int b;float f;f=float(b);/ / 此时变量此时变量b b依然为依然为intint类型。类型。(2) (2) 强迫类型转换符优先级较高,只对紧随其后的表达强迫类型转换符优先级较高,只对紧随其后的表达式 起 作 用 , 而 对 其 他 部 分 不 起 作 用 。 如 表 达 式式 起 作 用 , 而 对 其 他 部 分 不 起 作 用 。 如 表 达 式float(i)flo
17、at(i)* *f f的含义是先将变量的含义是先将变量i i强迫类型转换为强迫类型转换为floatfloat类类型,然后与变量型,然后与变量f f运算。运算。(3) (3) 强迫类型转换该当用在不做转换将影响表达式结果强迫类型转换该当用在不做转换将影响表达式结果的正确性或精度,或不能完成相应运算的场所。而对于的正确性或精度,或不能完成相应运算的场所。而对于系统可以自动转换类型的场所,那么没有必要运用。系统可以自动转换类型的场所,那么没有必要运用。栈内存与堆内存栈内存与堆内存栈空间是编译时分配的固定大小的内存。用于存放函栈空间是编译时分配的固定大小的内存。用于存放函数调用者的地址、前往值、保管的
18、机器形状用于前数调用者的地址、前往值、保管的机器形状用于前往、函数参数、部分变量和暂时变量等往、函数参数、部分变量和暂时变量等堆内存是程序运转时分配的大小可变的内存,也称为堆内存是程序运转时分配的大小可变的内存,也称为动态内存动态内存C+C+提供了两种方法进展内存动态分配和释放提供了两种方法进展内存动态分配和释放malloc()malloc()和和free()(free()(从从C C规范库中承继包含规范库中承继包含malloc.h)malloc.h)newnew和和deletedelete1.new运算符运算符 指针变量指针变量 = new 数据类型数据类型; new从堆内存中为程序分配可以
19、保管某种类型从堆内存中为程序分配可以保管某种类型数据的一块内存空间,并前往指向该内存的首数据的一块内存空间,并前往指向该内存的首地址,该地址存放于指针变量中。地址,该地址存放于指针变量中。 堆内存可以按照要求进展分配,程序对内存堆内存可以按照要求进展分配,程序对内存的需求量随时会发生变化,有时程序在运转中的需求量随时会发生变化,有时程序在运转中能够会不再需求由能够会不再需求由new分配的内存空间,而且分配的内存空间,而且程序还未运转终了,这时就需求把先前占用的程序还未运转终了,这时就需求把先前占用的内存空间释放给堆内存,以后重新分配,供程内存空间释放给堆内存,以后重新分配,供程序的其它部分运用
20、。序的其它部分运用。2.delete运算符运算符运算符运算符delete用于释放用于释放new分配的内存空间,它的分配的内存空间,它的运用方式为:运用方式为:delete 指针变量;指针变量;其中的指针变量保管着其中的指针变量保管着new动态分配的内存的首地动态分配的内存的首地址。址。3. 留意:留意:(1) 用用new获取的内存空间,必需用获取的内存空间,必需用delete进展释放;进展释放;(2) 对一个指针只能调用一次对一个指针只能调用一次delete;(3) 用用delete运算符作用的对象必需是用运算符作用的对象必需是用new分配的分配的内存空间的首地址。内存空间的首地址。#incl
21、ude using namespace std;void main()int *p;p=new int; / 分配内存空间分配内存空间*p=5;cout*p;delete p; / 释放内存空间释放内存空间【例【例2.3】new与与delete运用举例。运用举例。(分析运转结果分析运转结果)在用在用new分配内存的同时进展初始分配内存的同时进展初始化。运用方式为:化。运用方式为:指针变量指针变量 = new 数据类型数据类型(初始值初始值);例如上例中的:例如上例中的:p=new int;*p=5;也可写成:也可写成:p=new int(5); 指针变量指针变量 = new = new 数据类
22、型数据类型 数组大小数组大小 ;此时指针变量指向第一个数组元素的地址。运此时指针变量指向第一个数组元素的地址。运用用newnew分配数组时,不能提供初始值。运用分配数组时,不能提供初始值。运用newnew建立的数组变量也由建立的数组变量也由deletedelete释放。其方式为:释放。其方式为:delete delete 指针变量;或指针变量;或delete delete 指针变量;指针变量;同样,也可以用同样,也可以用newnew来为多维数组分配空间,但来为多维数组分配空间,但是除第一维可以为变量外,其它维数都必需是是除第一维可以为变量外,其它维数都必需是常量。常量。4用用new建立数组类型
23、的变量建立数组类型的变量 留意在运用留意在运用delete时,不用思索数组的维数。时,不用思索数组的维数。有时,并不能保证一定可以从堆内存中获得所需空间,有时,并不能保证一定可以从堆内存中获得所需空间,当不能胜利地分配到所需求的内存时,当不能胜利地分配到所需求的内存时,new前往前往0,即空,即空指针。因此我们可以经过判别指针。因此我们可以经过判别new的前往值能否为的前往值能否为0,来,来得知系统中能否有足够的空闲内存来供程序运用。例如:得知系统中能否有足够的空闲内存来供程序运用。例如:int *p= new int100;if(p=0)cout cant allocate more mem
24、ory,terminating. endl;exit(1);其中其中exit函数的作用是终止程序运转。函数的作用是终止程序运转。#include using namespace std;void main() int n; / 定义数组元素的个数定义数组元素的个数 int *p; coutn; if(p=new intn)=0) cout cant allocate more memory,terminating. endl; exit(1); / 分配内存空间分配内存空间 for( int i=0;in;i+) pi= i *2; coutNow output the array : end
25、l; for( i=0;in;i+) coutpi ; coutendl; delete p; / 释放内存空间释放内存空间【例【例2.4】从堆内存中获取一个整型数组,赋值后并打印出来。】从堆内存中获取一个整型数组,赋值后并打印出来。 通常情况下,假设全局变量与部分变量同通常情况下,假设全局变量与部分变量同名,那么部分变量在其作用域内具有较高的优名,那么部分变量在其作用域内具有较高的优先权。先权。C C言语规定只能在变量的作用域内运用该言语规定只能在变量的作用域内运用该变量,不能运用其他作用域中的变量,可采用变量,不能运用其他作用域中的变量,可采用C+C+中提供的作用域运算符中提供的作用域运算
26、符:,它能指定所需求,它能指定所需求的作用域。的作用域。 留意:不能用留意:不能用:访问函数中的部分变量。访问函数中的部分变量。在在C+C+言语中作用域运算符言语中作用域运算符:还用来限定类的成还用来限定类的成员,员, #include using namespace std;float a=2.4; / 全局变量全局变量void main() int a=8; / 部分变量部分变量coutaendl;cout:aendl; / :a表示全局作用域中的变量表示全局作用域中的变量a #include void main() int x10,i,j; j=0; /计数器初值赋计数器初值赋0 cou
27、tinput 10 numbers:endl; for(i=0;ixi; for(i=0;i0) j+; coutj=j;从键盘上输入从键盘上输入1010个整数,统计其中的正整数的个数个整数,统计其中的正整数的个数 程序运转结果:程序运转结果:(从键盘输入:从键盘输入:-2 3 4 -5 -3 9 -23 0 -1 21)输出:输出:j=4 用冒泡排序法对用冒泡排序法对10个数按从小到大的顺序输出个数按从小到大的顺序输出思想:冒泡法的根本思想是对数组元素做假设干次思想:冒泡法的根本思想是对数组元素做假设干次的的遍历调整,每次遍历都是对相邻的两个数两两比较遍历调整,每次遍历都是对相邻的两个数两两
28、比较并调整,将小的调到前头,大的调到后面。并调整,将小的调到前头,大的调到后面。4739147391437914379143719第一趟循环4次43719347193471934179第二趟循环3次341793417931479第三趟循环2次3147913479第四趟循环1次5 5个数个数#include void main()int a11; int i,n,t; /i表示数组下标,表示数组下标,n表示遍历次数,表示遍历次数,t用来交换数据用来交换数据 coutinput 10 numbers:endl; for(i=1;iai; coutendl; for(n=1;n=9;n+) for(
29、i=1;iai+1) t=ai;ai=ai+1;ai+1=t; coutthe sorted numbers:endl; for(i=1;i11;i+) coutai ; coutendl;程序运转结果:程序运转结果:input 10 numbers:1 32 13 0 23 9 45 8 19 -7 the sorted numbers:-7 0 1 8 9 13 19 23 32 45#include #include void main() char str20; int i,j; cin.get(str,20); j=strlen(str);for(i=j-1;i=0;i-)cout.
30、put(stri); 从键盘上输入一个字符串,然后将其逆序输出从键盘上输入一个字符串,然后将其逆序输出运转的结果是:运转的结果是:从键盘输入:从键盘输入:abcdefg gfedcbal运用字符串常量来对字符数组初始化。例如lchar str10=student;l或者直接将花括号省略,写成如下的方式lchar str10=student;l留意: l字符串常量所占的空间一定不能超越字符数组的长度。假设字符串常量占用的空间小于数组的长度,那么后面的元素自动的赋值为0 l用cout输出。格式为:lcout字符串或字符数组名;l用cout流对象的put。格式为:lcout.put(字符或字符变量)
31、;l这种方法,每次只能输出一个字符;要输出整个字符串,应采用循环的方法 #include void main()char s20=This is a string.;int i=0;while(si!=0)cout.put(si);i+;l用cout流对象的write方法。格式为:lcout.write(字符串或字符数组名,个数n);l其作用是输出字符数串中的前n个字符。 #include void main()char s20=This is a string.;cout.write(s,4);分析该程序的输出结果l利用cin直接输入。格式为:lcin字符数组名;l用这种方法输入字符串时,c
32、in只能接纳空格之前的部分。也就是说,当字符串中有空格时,用这种方法无法接纳全部的字符串。l利用cin流对象的getline方法。格式为:lcin.getline(字符数组名,输入字符串的最大长度n);l参数“字符数组名是存放字符串的数组称号l参数“输入字符串的最大长度n包括了字符串终了标志0在内 l字符串的衔接函数strcatl调用的普通方式:strcat(char ,const char );#include #include void main() char st120=qing,st2=huadaxue; strcat(st1,st2); cout字符串2,前往值0; l字符串1字符串
33、2,前往值0 l字符串、字符串2可以是字符数组也可以是字符串常量。 l字符串的比较不能运用以下的方式: l if(s1=s2) coutyes;l 只能运用该函数来进展比较。所以应该写成:l if(strcmp(s1,s2)=0) coutyes;#include #include void main()char str120,str220,str350; cin.getline(str1,20); cin.getline(str2,20); if (strcmp(str1,str2)0)strcpy(str3,str1); strcat(str3,str2); else strcpy(str
34、3,str2); strcat(str3,str1); coutstr3; 程序运转结果:从键盘输入:China 那么输出:BeijingChinal定义的普通方式为l类型阐明符 数组名常量表达式1常量表达式2 l例:int a53;l 表示a为整型二维数组,其中第一维有5个下标04,第二维有3个下标02,数组的元素个数为15,可以用于存放5行3列的整型数据表格。lC+言语中,二维数组在内存中默许情况下采用行优先存储(对float a23画存储表示图) l二维数组的初始化 l分行对二维数组赋初值。如l int a23=1,2,3,4,5,6; l对一切数据一同赋值,放在一个花括号中。如:l i
35、nt a23=1,2,3,4,5,6;l部分元素赋值 ,如:l int a23=1,2,4; l数组的元素全部赋值时,可以省略数组的第一维长度 #include void main() int i,j,a23=3,0,1,10,-4,9; for(i=0;i=1;i+) for(j=0;j=2;j+) coutendlaij=aij;程序运转结果:程序运转结果:a00=3a01=0a02=1a10=10a11=-4a12=9编写程序,将一个二维数组中行和列元素互换,存到另编写程序,将一个二维数组中行和列元素互换,存到另一个二维数组中。设数组:一个二维数组中。设数组:思想:需求定义两个数组思想:
36、需求定义两个数组行列交换本质上是将数组元素的行列下标相互交换行列交换本质上是将数组元素的行列下标相互交换二维数组,必需求逐个的进展交换,所以要用到了双重二维数组,必需求逐个的进展交换,所以要用到了双重循环语句循环语句 a= b=159268862951#include void main() int a23=1,5,9,2,6,8; int b32,i,j; coutArray a: endl; /输出原来数组的数据输出原来数组的数据 for(i=0;i2;i+) for(j=0;j3;j+) coutaij ; bji=aij; /将两个数组元素相互交换将两个数组元素相互交换 coutend
37、l; coutArray b:endl; /输出交换后的数据元素输出交换后的数据元素 for(i=0;i3;i+) for(j=0;j2;j+) coutbij ; coutendl; 程序运转结果:Array a:1 5 92 6 8Array b:1 25 69 8#include void main() int i,j; float a1010,sum=0,x; coutinput n*n Matrix:endl; for(i=0;i10;i+) for(j=0;jx;aij=x; for(i=0;i10;i+) sum=sum+aii+ai9-i; coutthe sum is:sum
38、endl;一条对角线元素的下标特点是:行列下标相等。另一一条对角线元素的下标特点是:行列下标相等。另一条对角线下标特点是:行列下标之和等于条对角线下标特点是:行列下标之和等于9。在每一行的每一列中找出这样的元素然后把它加到变在每一行的每一列中找出这样的元素然后把它加到变量量sum中去。中去。程序运转结果:程序运转结果:input 3*3 Matrix:1 3 52 4 6 7 8 9the sum is: 30从键盘输入一个字符串判别能否为从键盘输入一个字符串判别能否为“回文回文比如:比如:ABCBAABCBA#include #include void main()char str60;in
39、t i,j;cin.get(str,60);i=0;j=strlen(str)-1;while(stri=) i+; /寻觅前面第一个不是空格的字符寻觅前面第一个不是空格的字符 while(strj=) j-; /寻觅后面第一个不是空格的字符寻觅后面第一个不是空格的字符 while(ij & stri=strj)/前后对应逐个的比较前后对应逐个的比较 i+;j-;if(ij) coutNoendl;elsecoutYesendl;程序运转结果:从键盘输入:程序运转结果:从键盘输入:studeduts输出的结果:输出的结果:Yesj从字符串的最后一个从字符串的最后一个元素开场,所以初值元
40、素开场,所以初值为为strlen(str)-1 开场比较时,将字符开场比较时,将字符串前后的空格过滤掉串前后的空格过滤掉 援用是援用是C+言语的一个特殊的数据类型描画,用于言语的一个特殊的数据类型描画,用于在程序的不同部分运用两个以上的变量名指向同一地在程序的不同部分运用两个以上的变量名指向同一地址,使得对其中任一个变量的操作实践上都是对同一址,使得对其中任一个变量的操作实践上都是对同一地址单元进展的。在这种两个以上变量名的关系上,地址单元进展的。在这种两个以上变量名的关系上,被声明为援用类型的变量名那么是实践变量名的别名。被声明为援用类型的变量名那么是实践变量名的别名。援用运算符为援用运算符
41、为&,声明援用的普通方式为:,声明援用的普通方式为:数据类型数据类型 &援用变量名援用变量名 = 变量名;变量名;或或 数据类型数据类型& 援用变量名援用变量名 = 变量名;变量名;或或 数据类型数据类型 & 援用变量名援用变量名 = 变量名;变量名; 对援用进展操作,实践上就是对被援用的变量进展对援用进展操作,实践上就是对被援用的变量进展操作。援用不是值,不占存储空间,声明援用时,目操作。援用不是值,不占存储空间,声明援用时,目的的存储形状不会改动。援用一旦被初始化,就不能的的存储形状不会改动。援用一旦被初始化,就不能再重新赋值。再重新赋值。 【例【例2.5】
42、援用举例。】援用举例。(图示变量及其援用并分析运转结果图示变量及其援用并分析运转结果)#include void main() int num=50;int &ref=num;ref+=10;coutnum=numendl;cout ref=refendl; num+=40;cout num=numendl;coutref=refendl;阐明:阐明:(1) 在一行上声明多个援用型变量在一行上声明多个援用型变量(函数函数)名时,要在每名时,要在每个变量个变量(函数函数)名前都冠以名前都冠以“&符号。符号。(2) 援用不是变量,所以援用本身不能被修正,在程序援用不是变量,所以援用
43、本身不能被修正,在程序中对援用的存取都是对它所援用的变量的存取。中对援用的存取都是对它所援用的变量的存取。(3) 一个变量被声明为援用时必需进展初始化,除非这一个变量被声明为援用时必需进展初始化,除非这个援用是用作函数的参数或前往值,为援用提供的初始个援用是用作函数的参数或前往值,为援用提供的初始值应为变量值应为变量(包括对象包括对象)。援用一旦被初始化。援用一旦被初始化,就不能再重就不能再重新赋值。如新赋值。如ref=&j;但但ref=j是允许的。是允许的。(4) 由于援用不是变量,所以,不能阐明援用的援用,由于援用不是变量,所以,不能阐明援用的援用,也不能阐明数组元素的类型为援用数
44、组,或指向援用的也不能阐明数组元素的类型为援用数组,或指向援用的指针。例如:指针。例如:int &a5; / 错误错误int &*p;/ 错误错误由于指针也是变量,因此可以阐明对指针变量的援用。由于指针也是变量,因此可以阐明对指针变量的援用。例如:例如:int *a; int *&p=a; int b; p=&b; / a指向变量指向变量b(5) 援用与指针不同。指针的内容或值是某一变量的内援用与指针不同。指针的内容或值是某一变量的内存单元地址,而援用那么与初始化它的变量具有一样的存单元地址,而援用那么与初始化它的变量具有一样的内存单元地址。指针是个变量,可以把
45、它再赋值成其它内存单元地址。指针是个变量,可以把它再赋值成其它的地址,然而,建立援用时必需进展初始化并且决不会的地址,然而,建立援用时必需进展初始化并且决不会再指向其它不同的变量。再指向其它不同的变量。地址地址(6) 要留意区分援用运算符和地址运算符的区别。例要留意区分援用运算符和地址运算符的区别。例如:如:int num=50;int &ref=num;int *p=&ref; /&在赋值号右边为地址运算符在赋值号右边为地址运算符(7) 可以用一个援用初始化另一个援用。例如:可以用一个援用初始化另一个援用。例如:int num=50;int &ref1=num
46、;int &ref2=ref1;ref2=100;/ num被修正为被修正为100其中其中ref2也是对也是对num的援用。的援用。(8)可以把函数的参数阐明成援用以建立函数参数的援用传送方式可以把函数的参数阐明成援用以建立函数参数的援用传送方式益处:益处:C+的援用传送方式的实参和形参指向同一内存地址,的援用传送方式的实参和形参指向同一内存地址,减少值传送引起的数据堆栈复制减少值传送引起的数据堆栈复制防止地址传送引起的地址溢出错误防止地址传送引起的地址溢出错误C+提供援用的主要用途就是建立函数参数的援用传送方式提供援用的主要用途就是建立函数参数的援用传送方式C言语的函数参数传送只能采
47、用值传送和地址传送言语的函数参数传送只能采用值传送和地址传送三种传送方式比较的例子三种传送方式比较的例子交换两个数交换两个数用普通变量作为参数交换两个数用普通变量作为参数交换两个数采用传值方式采用传值方式#include #include void swap(int x,int y)void swap(int x,int y) int t; int t; t = x; t = x; x = y; x = y; y = t; y = t; void main()void main() int a = 1,b = 2; int a = 1,b = 2; cout cout交换前交换前,a=a,a=
48、a,b=bendl;b=bendl; swap(a,b); swap(a,b); cout cout交换后交换后,a=a,a=a,b=bendl;b=bendl; 运转结果:运转结果:交换前交换前,a=1,b=2交换后交换后,a=1,b=2交换功能未实现。交换功能未实现。阐明采用传值方式时,实参不受影响阐明采用传值方式时,实参不受影响 用指针变量作为参数交换两个数用指针变量作为参数交换两个数采用传址方式采用传址方式#include #include void swap(int void swap(int * * x,int x,int * * y) y) int t; int t; t = t
49、 = * *x;x; * *x = x = * *y;y; * *y = t;y = t; void main()void main() int a = 1,b = 2; int a = 1,b = 2; cout cout交换前交换前,a=a,a=a,b=bendl;b=bendl; swap(&a,&b); swap(&a,&b); cout cout交换后交换后,a=a,a=a,b=bendl;b=bendl; 运转结果:运转结果:交换前交换前,a=1,b=2交换后交换后,a=2,b=1采用传地址方式传送参数。采用传地址方式传送参数。在函数中改动了形参,就
50、是改动了实参,由于他们是在函数中改动了形参,就是改动了实参,由于他们是指向同一地址的指针变量。指向同一地址的指针变量。因此交换功能实现因此交换功能实现用援用作为参数交换两个数用援用作为参数交换两个数采用传援用方式采用传援用方式#include #include void swap(int & x,int & y)void swap(int & x,int & y) int t; int t; t = x; t = x; x = y; x = y; y = t; y = t; void main()void main() int a = 1,b = 2; int
51、a = 1,b = 2; cout cout交换前交换前,a=a,a=a,b=bendl;b=bendl; swap(a,b); swap(a,b); cout cout交换后交换后,a=a,a=a,b=bendl;b=bendl; 运转结果:运转结果:交换前交换前,a=1,b=2交换后交换后,a=2,b=1采用传援用方式传送参数。采用传援用方式传送参数。函数中的形参是主调函数中实参的援用。函数中的形参是主调函数中实参的援用。在函数中改动了形参,就是改动了实参,由于他们指在函数中改动了形参,就是改动了实参,由于他们指向同一地址。向同一地址。因此交换功能实现因此交换功能实现地址传送和援用传送的比
52、较。地址传送和援用传送的比较。援用作为参数,主调函数可直接运用变量名援用作为参数,主调函数可直接运用变量名地址作为参数,主调函数要将变量地址传送过去地址作为参数,主调函数要将变量地址传送过去援用作为参数,函数可对形参变量直接操作援用作为参数,函数可对形参变量直接操作地址作为参数,函数需经过指针对地址间接操作地址作为参数,函数需经过指针对地址间接操作(9) 有空指针,无空援用有空指针,无空援用(10) 援用不能用数据类型来初始化。如:援用不能用数据类型来初始化。如: int&ref=int; / error(11) 函数调用可以作为左值函数调用可以作为左值(函数前往值为援用类型函数前往值
53、为援用类型) 援用表达式是一个左值表达式,因此它可以出如今形、实参数援用表达式是一个左值表达式,因此它可以出如今形、实参数的任何一方。假设一个函数前往了援用,那么该函数的调用也可以的任何一方。假设一个函数前往了援用,那么该函数的调用也可以被赋值。普通说,当前往值不是本函数内定义的部分变量时就可以被赋值。普通说,当前往值不是本函数内定义的部分变量时就可以前往一个援用。在通常情况下,援用前往值只用在需对函数的调用前往一个援用。在通常情况下,援用前往值只用在需对函数的调用重新赋值的场所,也就是对函数的前往值重新赋值的时候。防止将重新赋值的场所,也就是对函数的前往值重新赋值的时候。防止将部分作用域中变
54、量的地址前往,就使函数调用表达式作为左值来运部分作用域中变量的地址前往,就使函数调用表达式作为左值来运用。用。函数前往值为援用类型表示该函数前往值是一个变量的别名,故可函数前往值为援用类型表示该函数前往值是一个变量的别名,故可将函数调用作为一个变量运用而进展赋值将函数调用作为一个变量运用而进展赋值【例【例2.82.8】统计学生中】统计学生中A A类学生与类学生与B B类学生各为多少个。类学生各为多少个。A A类学生的规类学生的规范是平均分在范是平均分在8080分以上,其他都是分以上,其他都是B B类学生。类学生。【补充例子】【补充例子】#include int & min(int &a
55、mp; i,int & j) if(i=j) return i; else return j;void main() int a = 3, b= 4; couta=a b=bendl; min(a,b)=5; couta=a b=bendl; min(a,b) = 0; couta=a b=bendl;【补充例子】【补充例子】#include int & min(int & i,int & j)/此函数的前往值是对参数此函数的前往值是对参数i和和j中小的那个变量的援用中小的那个变量的援用 if(i=j) return i; else return j;void
56、main() int a = 3, b= 4; couta=a b=bendl; min(a,b)=5; /由于函数的前往值为援用类型,所以可以为函数调用赋值由于函数的前往值为援用类型,所以可以为函数调用赋值 /为函数赋的值赋给两个参数中的小者,所以为函数赋的值赋给两个参数中的小者,所以a变为变为5,b仍为仍为4 couta=a b=bendl; min(a,b) = 0; /a不变,不变,b变为变为0 couta=a b=bendl;(12)定义前往援用的函数时,留意不要前往对该函数内定义前往援用的函数时,留意不要前往对该函数内部分变量的援用。部分变量的援用。为什么为什么?由于部分变量的生存
57、期局限于函数内部,函数前往时部分变量由于部分变量的生存期局限于函数内部,函数前往时部分变量消逝,导致函数前往一个无效的援用。消逝,导致函数前往一个无效的援用。故函数前往的援用是对某一个函数参数的援用且这个参数本身故函数前往的援用是对某一个函数参数的援用且这个参数本身也是援用类型也是援用类型【例【例2.9】前往的部分作用域内的变量,函数作为左值。】前往的部分作用域内的变量,函数作为左值。#define PI 3.1415926const float PI=3.1415926; 这个常量是有类型的,它有地址,可以用这个常量是有类型的,它有地址,可以用指针指向这个值,但不能修正它。指针指向这个值,但
58、不能修正它。C+建议用建议用const取代取代#define定义常量。定义常量。 (1) 运用运用const修饰符定义常量时,必需初始化;修饰符定义常量时,必需初始化;(2) 常量一旦被定义,在程序中任何地方都不能常量一旦被定义,在程序中任何地方都不能 再更改。再更改。(3) 假设用假设用const定义的是一个整型常量,定义的是一个整型常量,int可以可以省略。省略。(4) 与与#define定义的常量有所不同,定义的常量有所不同,const定义的定义的常量可以有本人的数据类型,这样常量可以有本人的数据类型,这样C+编译编译程序可以进展更加严厉的类型检查,具有良程序可以进展更加严厉的类型检查,
59、具有良好的编译时的检测性。好的编译时的检测性。 (5) 函数参数也可以用函数参数也可以用const阐明,用于保证明参在阐明,用于保证明参在该函数内部不被改动,大多数该函数内部不被改动,大多数C+编译器能对具有编译器能对具有const参数的函数进展更好的代码优化。例如,经过参数的函数进展更好的代码优化。例如,经过函数函数max求出整型数组求出整型数组a100中的最大值,函数原型中的最大值,函数原型应该是:应该是: int max(const int *pa); 这样做的目的是确保原数组的数据不被破坏,即在这样做的目的是确保原数组的数据不被破坏,即在函数中对数组元素的操作只许读,不许写。函数中对数
60、组元素的操作只许读,不许写。 除了计算外,文本处置也是编程过程中除了计算外,文本处置也是编程过程中一个非常重要的方面。在一个非常重要的方面。在C言语中运用字符数言语中运用字符数组和字符指针实现字符串,但是在组和字符指针实现字符串,但是在C+中提供中提供了一种既方便又好用的了一种既方便又好用的string类型。下面经过一类型。下面经过一个简单的例子阐明个简单的例子阐明string类型的运用。类型的运用。【例【例2.10】字符串类】字符串类string的运用。的运用。【例【例2.10 】#include #include /运用字符串运用字符串string类型的程序应包含头文件类型的程序应包含头文件using namespace std;void main()string s,t;cout请输入一个字符串请输入一个字符串:s; / 由键盘输入一行文本,并把它赋给由键盘输入一行文本,并把它赋给sring类型的变量类型的变量s,留意:
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 走进生命花园
- 青协会长述职报告
- 教育科技产业在线教育产品开发与实践方案设计
- 电子商务市场营销策略测试卷
- 养老服务管理与护理技术作业指导书
- 足球场人造草更换施工方案
- 股份制改革操作指南
- 苏州橡塑减速带施工方案
- 支气管哮喘防治指南(2024年版)解读
- 教育用房砖混基础施工方案
- T-ISEAA 001-2020 网络安全等级保护测评高风险判定指引
- 交通工程安全台帐
- 幼儿园:《桔子和苹果》主题审议
- 中小学课堂游戏刮刮卡
- 医院医疗设备科副科长竞聘演讲稿
- GB/T 15965-2008手工地毯绒头长度的测定方法
- GB/T 15171-1994软包装件密封性能试验方法
- 数字电路设计及verilog-hdl实现康磊课后答案
- 青岛版科学(2017)六三制六年级下册1-5《触觉》课件
- 建筑用砂标准及特点-课件
- 水轮发电机讲义课件
评论
0/150
提交评论