谭浩强c++第一章课件_第1页
谭浩强c++第一章课件_第2页
谭浩强c++第一章课件_第3页
谭浩强c++第一章课件_第4页
谭浩强c++第一章课件_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C+面向对象程序设计第一章 C+的初步知识C+ 1- 1 第一第一章章 C+C+的初步知识的初步知识第二章第二章 类和对象类和对象第三章第三章 再论类和对象再论类和对象第四章第四章 运算符重载运算符重载第五章第五章 继承与派生继承与派生第六章第六章 多态性与虚函数多态性与虚函数第七章第七章 输入输出流输入输出流第八章第八章 C+工具工具C+ 1- 2 C+ 1- 3 总学时:总学时:6464讲课:讲课:4848学时学时上机:上机:1616学时学时课外上机:每周不少于课外上机:每周不少于4 4学时学时C+ 1- 4 C+ 1- 5 /*This is a simple Cpp program*/

2、#include /文件包含文件包含void main( ) /主函数头主函数头 /主函数体主函数体 double x,y; /变量说明变量说明 cout xy ; /输入数据输入数据 double z=x+y; /定义并赋值定义并赋值 cout x+y= zendl ; /输出数据输出数据任何变量都必须先说明后使用 Enter two float number: 3 4 Enter two float number: 3 4 x+y=7x+y=7C+ 1- 6 lC语言中,用语言中,用#define 定义常量:定义常量:#define PI 3.14159#define R a+b 它只是在

3、预编译时进行它只是在预编译时进行字符置换字符置换,将标识符置换成表达式或数字。预编译,将标识符置换成表达式或数字。预编译后,标识符后,标识符PI,R不再存在。不再存在。PI,R不是变量,没有类型,不占用存储单元,很不是变量,没有类型,不占用存储单元,很容易出错:容易出错:int a=1;b=2;#define PI 3.14159#define R a+bcoutPI * R * R; 输出的不是输出的不是3.14159 * (a+b) * (a+b),而是,而是 3.14159 * a+b * a+b。程序因此出错。程序因此出错。C+ 1- 7 lC+进行了改进,用进行了改进,用 const

4、 定义常变量。如:定义常变量。如:const float PI = 3.14159; 它定义了常变量它定义了常变量PI,有数据类型,占用存储单元,有地,有数据类型,占用存储单元,有地址,可以用指针指向它,只是在程序运行中,此变量的值址,可以用指针指向它,只是在程序运行中,此变量的值固定,不能改变。固定,不能改变。l常变量定义时,常变量定义时,const 与指针结合使用,可以有如下三种与指针结合使用,可以有如下三种不同的定义:不同的定义:uconst float *ptr = 3.14159; /指向常变量的指针,数值指向常变量的指针,数值3.14159不能改变为其它值不能改变为其它值ufloa

5、t const *ptr = 3.14159; /指向变量的常量指针,指指向变量的常量指针,指针地址不能改变针地址不能改变uconst float const *ptr = 3.14159 ; /指向常量的常量指指向常量的常量指针针C+ 1- 8 1.3 函数原型申明函数原型申明lC+强制规定,强制规定,如果函数调用的位置在函数定义之前,则在如果函数调用的位置在函数定义之前,则在调用函数之前必须实现作函数原型申明。调用函数之前必须实现作函数原型申明。这一点与这一点与C不同,不同,C只是建议,而没有强制只是建议,而没有强制l函数申明的一般形式为:函数申明的一般形式为: 函数类型函数类型 函数名(

6、参数表)函数名(参数表); l最后的分号可不能忘了,否则出错!参数表中可以只指定各最后的分号可不能忘了,否则出错!参数表中可以只指定各个参数的类型,而不指定参数名!个参数的类型,而不指定参数名!C+ 1- 9 函数申明和定义的示例函数申明和定义的示例/求圆面积,将函数申明和定义分开,在调用函数前先申明它求圆面积,将函数申明和定义分开,在调用函数前先申明它#include float area( float ); /先申明先申明void main( ) float radius; coutradius; if (radius0) coutarea(radius )endl; /再使用再使用flo

7、at area( float r) /最后定义最后定义 return r * r* 3.14159;C+ 1- 10 程序可以改为如下形式:程序可以改为如下形式:#include float area( float r) return r * r* 3.14159; /先申明先申明main( ) float radius; coutradius; if (radius0) coutarea(radius )”是左移运算符,在是左移运算符,在C+中,有作为输出算中,有作为输出算符;而符;而“*”是乘法算符,也是指针符号。这种一个标识符有是乘法算符,也是指针符号。这种一个标识符有多种含义用途的现象

8、,旧叫多种含义用途的现象,旧叫“重载重载”(overloading)。如果标。如果标识符为运算符,就叫识符为运算符,就叫“运算符重载运算符重载”;如果标识符为函数名;如果标识符为函数名,就叫,就叫“函数重载函数重载”。l什么时候用到重载?什么时候用到重载?用于相类似而又不同的操作用于相类似而又不同的操作。例如,求多个数值的最大。例如,求多个数值的最大数,不同类型的参数,数,不同类型的参数,C语言要编写不同的函数:语言要编写不同的函数:int max1(int a, int b, int c); / 3个整形数值求最大值个整形数值求最大值float max2(float a, float b);

9、 / 2个实形数值求最大值个实形数值求最大值long max3(long a, long b, long c); / 3个长整形数值求最大值个长整形数值求最大值C+ 1- 12 l而而C+的做法是重载:的做法是重载:将这三个函数名取相同的名字将这三个函数名取相同的名字,程序运行时,程序运行时,系统会根据实际参数的不同,调用相近参数的函数:系统会根据实际参数的不同,调用相近参数的函数:#include int max(int a, int b, int c) if (ba) a=b; if (ca) a=c; return a; float max(float a, float b) if (b

10、a) a=b; return a;long max(long a, long b, long c) if (ba) a=b; if (ca) a=c; return a; void main( ) int a, b, c, d; float x, y, z; long m, n, p, q; cinabc; cinxy; cinmnp; d = max (a, b, c); cout “int_d = “dendl; z = max (x,y); cout “float_z = “zendl; q = max (m, n, p); cout “long_q = “qendl;Main函数三次调

11、用函数三次调用max函数,每次实参的个数或类型不同,系统会寻找函数,每次实参的个数或类型不同,系统会寻找与之匹配的函数调用。与之匹配的函数调用。C+ 1- 13 1.5 函数模板函数模板l什么时候使用模板什么时候使用模板?重载函数的不便之处在于,对于同名?重载函数的不便之处在于,对于同名的函数要一个一个地编写,编码量很大。对于有些相同功的函数要一个一个地编写,编码量很大。对于有些相同功能的函数,如果函数个数相同,可以用另外的方法来解决能的函数,如果函数个数相同,可以用另外的方法来解决,这就是模板,这就是模板(Template)。l函数模板的定义形式:函数模板的定义形式:Template 返回类

12、型返回类型 函数模板名函数模板名(数据参数表数据参数表) 函数模板定义体函数模板定义体l示例:将上述重载示例改为函数模板。示例:将上述重载示例改为函数模板。C+ 1- 14 #include using namespace std; /默认使用默认使用std标准库名标准库名template T max (T a, T b, T c) / 建立函数模板时,只需要建立函数模板时,只需要 if (ba) a=b; / 将函数类型、参数类型将函数类型、参数类型 int 换成换成 T 就行。就行。 if (ca) a=c; / 即用虚拟的类型名即用虚拟的类型名T代替实际的类型代替实际的类型 return

13、 a; void main( ) int i = 8, j = 3, k = 4, h; long m = 1, n = 2, p = 3, q; h = max ( i, j, k); q = max ( m, n, p); cout “int_h = “hendl; cout “long_q = “qendl;类型参数可以有多个:类型参数可以有多个:template C+ 1- 15 l由此程序可以看到,函数模板比函数重载更方便,但由此程序可以看到,函数模板比函数重载更方便,但模板只适用于函数的参数个数相同而类型不同,且函模板只适用于函数的参数个数相同而类型不同,且函数体相同的情况。不满足

14、这种情况时,就只能使用函数体相同的情况。不满足这种情况时,就只能使用函数重载。数重载。C+ 1- 16 1.6 有默认参数的函数有默认参数的函数l背景背景:一般情况下,函数调用时,形参从实参那里取得值。因此要求实:一般情况下,函数调用时,形参从实参那里取得值。因此要求实参的个数和类型应该与形参相同。但是,有时候,多次调用同一函数时参的个数和类型应该与形参相同。但是,有时候,多次调用同一函数时用的是同一实参数,或者调用时还不好确定实参数。用的是同一实参数,或者调用时还不好确定实参数。C+提供一个简单提供一个简单的解决办法,即给参数一默认值的解决办法,即给参数一默认值。这样当不提供实参数时,形参就

15、用默。这样当不提供实参数时,形参就用默认参数作为参数值。认参数作为参数值。l示例示例:有一函数声明为:有一函数声明为:float area ( float r=6.5 );调用调用area 函数时,如果不提供实际参数给函数时,如果不提供实际参数给r,r 就以默认数值就以默认数值 6.5 作为参数顶用作为参数顶用area:area ( ); / 相当于相当于 area (6.5 );l注意注意:1) 当有多个参数时,如果只有部分参数有默认值,则指定了默认值的参当有多个参数时,如果只有部分参数有默认值,则指定了默认值的参数必须放在参数表的最右边,否则出错。因为实参与形参的结合是从左数必须放在参数表

16、的最右边,否则出错。因为实参与形参的结合是从左至右顺序进行的,第一个实参必须给第一个形参,第二个实参必须给第至右顺序进行的,第一个实参必须给第一个形参,第二个实参必须给第二个形参二个形参。C+ 1- 17 1.6 有默认参数的函数有默认参数的函数声明:声明: void area (float x1, int x2 = 1, char x3 = a);调用:调用:area ( 1.2, 3, b); / 形参值全部由实参得到形参值全部由实参得到 area (1.2, 3); / 最后一个参数取自默认值最后一个参数取自默认值 area (1.2 ); / 最后两个参数取自默认值最后两个参数取自默认

17、值 area ( ); / 出错,第一个形参没有实参,也没有出错,第一个形参没有实参,也没有默默 认值认值2) 一个函数不能既作为重载函数,又作为默认参数函数。因为一个函数不能既作为重载函数,又作为默认参数函数。因为当调用函数时如果少写一实际个参数,系统无法判断是利用当调用函数时如果少写一实际个参数,系统无法判断是利用重载函数还是利用默认参数函数。重载函数还是利用默认参数函数。C+ 1- 18 1.7 变量的引用变量的引用(reference)l什么叫引用什么叫引用?变量的引用就是变量的别名。建立引用的作用?变量的引用就是变量的别名。建立引用的作用,是为一个变量另取一个名字,以便在需要的时候间

18、接地引,是为一个变量另取一个名字,以便在需要的时候间接地引用该别名。用该别名。l如何使用引用如何使用引用?假如有一个变量?假如有一个变量a , 想给它另取一个别名想给它另取一个别名b ,可以这样写可以这样写:int a ;int &b = a; / 声明声明b 是一个整形变量的引用变量,并且被初始化为是一个整形变量的引用变量,并且被初始化为au此处此处 & 不代表取地址,只是不代表取地址,只是“引用声明符引用声明符”。对一个变量声明一。对一个变量声明一个引用,并不另外开辟内存空间。个引用,并不另外开辟内存空间。b和和a 代表同一个变量单元。代表同一个变量单元。u引用不是独立的变

19、量,编译系统不给它分配存储单元。因此建立引用引用不是独立的变量,编译系统不给它分配存储单元。因此建立引用只有声明,没有定义,只是声明和某一个变量的关系。只有声明,没有定义,只是声明和某一个变量的关系。C+ 1- 19 1.7 变量的引用变量的引用(reference)u声明了一个变量的引用后,在本函数执行期间,该引用一直与代表的声明了一个变量的引用后,在本函数执行期间,该引用一直与代表的变量相联系,不能再作为另一个变量的别名。请看如下示例:变量相联系,不能再作为另一个变量的别名。请看如下示例:int a, b ;int &c = a;int &c = b; / 错误,错误,c

20、已经是已经是a 的引用,不能再作为另一个变量的引用,不能再作为另一个变量b的引用的引用u引用不是独立的数据类型,它必须与某一种类型的数据相联系:引用不是独立的数据类型,它必须与某一种类型的数据相联系:int &x; / 错误,错误, 没有指定没有指定 x 代表哪个变量代表哪个变量C+ 1- 20 l示例:示例:#include using namespace std;void main( ) int a = 10; int &b = a; a = a * a; cout “b = “bendl;运行结果:运行结果:b = 1001.7 变量的引用变量的引用(reference)

21、C+ 1- 21 l将引用作为函数参数将引用作为函数参数:C+之所以增加之所以增加“引用引用”,主要是利用它作为函,主要是利用它作为函数参数,以弥补函数传递参数的不方便的遗憾。也降低了编程难度。数参数,以弥补函数传递参数的不方便的遗憾。也降低了编程难度。u将变量名作为实参将变量名作为实参:这时传给形参的是变量的值,传递是单向的,函:这时传给形参的是变量的值,传递是单向的,函数运行时,形参发生变化,并不回传给实参。因为形参和实参不是同数运行时,形参发生变化,并不回传给实参。因为形参和实参不是同一个存储单元。请看下面示例:一个存储单元。请看下面示例:1.7 变量的引用变量的引用(reference

22、)#include void swap ( int a, int b ) int temp; temp = a; a = b; b = temp;void main( ) int i=3, j=5; swap ( i, j ); couti“,”jendl;运行结果,运行结果,i, j 仍然是仍然是3,5。没有发生交换。没有发生交换。C+ 1- 22 u传递变量的指针传递变量的指针:这时传给形参的是变量的地址,形参得到一个变量:这时传给形参的是变量的地址,形参得到一个变量的地址,即形参指针变量指向实参变量单元。函数中形参发生改变,的地址,即形参指针变量指向实参变量单元。函数中形参发生改变,实际

23、上是改变实参。实际上是改变实参。这种方法实际上仍然是值传递:想指针变量传递地址值。然后通过指针这种方法实际上仍然是值传递:想指针变量传递地址值。然后通过指针变量访问有关变量。变量访问有关变量。“间接地间接地”回传了改变的变量。请看下面示例:回传了改变的变量。请看下面示例:1.7 变量的引用变量的引用(reference)#include void swap ( int *p1, int *p2 ) int temp; temp = *p1; *p1 = *p2; *p2 = temp;void main( ) int i=3, j=5; swap ( &i, &j ); cou

24、ti“,”jendl;运行结果,运行结果,i, j 是是5,3。变量值发生交换。变量值发生交换。C+ 1- 23 u传递变量的别名传递变量的别名:将变量的引用作为函数形参,弥补了上面两种方法:将变量的引用作为函数形参,弥补了上面两种方法的不足。请看下面示例:的不足。请看下面示例:注意:注意:swap函数形参函数形参&a,&b是指定整形变量的引用作为形参,但是指定整形变量的引用作为形参,但引用谁还没定。而引用谁还没定。而main函数中,用一,函数中,用一,i, j的名调用的名调用swap,就是将,就是将i, j的的名字传给引用,这样名字传给引用,这样a就成立就成立i的别名,的别名

25、,b就成立就成立j 的别名。的别名。1.7 变量的引用变量的引用(reference)#include void swap ( int &a, int &b ) int temp; temp = a; a = b; b = temp;void main( ) int i=3, j=5; swap ( i, j ); couti“,”jendl;运行结果,运行结果,i, j 是是5,3。变量值发生交换。变量值发生交换。C+ 1- 24 l如何理解引用?如何理解引用?我们从物理实现上来理解,引用是一个隐性指针,即引我们从物理实现上来理解,引用是一个隐性指针,即引用值是引自所指向的实

26、体。这就是引用的真意。高级编程(面向应用)用值是引自所指向的实体。这就是引用的真意。高级编程(面向应用)多用引用,低级编程(面向机器)多用指针。多用引用,低级编程(面向机器)多用指针。l对引用的说明对引用的说明:u不能建立不能建立void类型的引用。因为任何实际存在的变量都属于非类型的引用。因为任何实际存在的变量都属于非void类类型。型。 void &a = 9; /错误错误u不能对数组名进行引用,因为数组名是首地址本身不占有存储空间。不能对数组名进行引用,因为数组名是首地址本身不占有存储空间。char c6 = “hello”;char &r =c; /错误错误u可以建立指

27、针变量的引用:可以建立指针变量的引用:int i=5;int *p= &i; / 定义指针变量定义指针变量p,指向,指向i int * &t = p; / t 是指向整形变量的指针变量的引用,初始化为是指向整形变量的指针变量的引用,初始化为p.1.7 变量的引用变量的引用(reference)C+ 1- 25 u可以将引用的地址赋给指针。此时,指针指向原来变量:可以将引用的地址赋给指针。此时,指针指向原来变量:int a = 3;int &b = a;int *p = &b; / 指针指针p指向变量指向变量a的引用的引用b,相当与指向,相当与指向au不能定义指向

28、引用类型的指针变量:不能定义指向引用类型的指针变量:int & *p = & a; / 错误错误u可以用常量或表达式对引用初始化,但必须用可以用常量或表达式对引用初始化,但必须用const限定限定:const int &c = 3; /合法合法1.7 变量的引用变量的引用(reference)C+ 1- 26 l引入原因引入原因:目的是为了解决程序中函数调用的目的是为了解决程序中函数调用的效率效率问题。问题。函数调用时需要建立函数调用时需要建立栈栈内存环境,进行参数传递,并产内存环境,进行参数传递,并产生程序执行转移,则都要有时间和空间的代价。生程序执行转移,则都要有时

29、间和空间的代价。而有时一些函数代码很短(行),却有高使用频而有时一些函数代码很短(行),却有高使用频率,造成处理现场的开销巨增。率,造成处理现场的开销巨增。这时若将这时若将函数体嵌入函数函数体嵌入函数调用处,则可避免每次调用函调用处,则可避免每次调用函数的开销,大大提高效率。数的开销,大大提高效率。1.8 内联函数内联函数(inline function)C+ 1- 27 1.8 内联函数内联函数(inline function)l在声明一个函数时,加上限定词在声明一个函数时,加上限定词inline,该函数就成为内联函,该函数就成为内联函数。编译时,系统将调用此函数的地方用函数的原代码替换数。

30、编译时,系统将调用此函数的地方用函数的原代码替换。即以空间代价换取时间。例如:。即以空间代价换取时间。例如:#include inline int power(int x ) / 定义一个内联函数定义一个内联函数 return x*x; void main( ) cout power ( 2 ) endl; / 编译系统展开为编译系统展开为x=2;x*x; cout power ( 1+2 ) endl; / 编译系统展开为编译系统展开为x=1+2;x*x;运行结果:运行结果:49C+ 1- 28 l内联函数还有内联函数还有限制限制:u函数内不能含有循环结构或函数内不能含有循环结构或switc

31、h结构;结构;u不能含有任何静态数据及数组声明。不能含有任何静态数据及数组声明。u不能是递归函数。不能是递归函数。1.8 内联函数内联函数(inline function)C+ 1- 29 l标识符只能在说明它或定义它的范围内是可见的,标识符只能在说明它或定义它的范围内是可见的,而在该范围之外是不可见的。而在该范围之外是不可见的。l大多数标识符的说明与定义是一致的,只有少数例大多数标识符的说明与定义是一致的,只有少数例外。如:函数等。外。如:函数等。l范围有大有小。最大为整个程序,最小为块,中间范围有大有小。最大为整个程序,最小为块,中间有文件和函数。有文件和函数。l每一个变量都有自己的有效范

32、围。我们只能在变量的作用域每一个变量都有自己的有效范围。我们只能在变量的作用域内使用该变量。内使用该变量。不能直接使用其它作用域中的变量不能直接使用其它作用域中的变量。如果要。如果要使用其它作用域中的同名变量,必须使用使用其它作用域中的同名变量,必须使用“作用域运算符作用域运算符”,即,即“:”。1.9 作用域运算符作用域运算符C+ 1- 30 请看示例:请看示例:#include float a=1.5;void main( ) int a = 5; cout a endl; / 输出作用域为输出作用域为main 函数的局部变量函数的局部变量a 的值的值 cout :a endl; / 输出

33、作用域为全局的输出作用域为全局的 全局变量全局变量a 的值的值运行结果:运行结果:5 1.5 注意:不能用作用域运算符注意:不能用作用域运算符“:”访问函数中的局部变量。访问函数中的局部变量。1.9 作用域运算符作用域运算符C+ 1- 31 C+ 1- 32 #includeint i(5); /外部全局变量外部全局变量extern void func( ) cout iendl; void main() int i=3; / 内部局部变量内部局部变量 func( ); cout iendl; 局部变量全局变量蓝色为文件作用域绿色为函数作用域C+ 1- 33 1.10 字符串变量字符串变量C+

34、除了可以使用除了可以使用C语言提供的字符型变量和字符型数组外,还提供语言提供的字符型变量和字符型数组外,还提供了字符串类。这种类可以定义字符串对象。但在文件开头必须包含了字符串类。这种类可以定义字符串对象。但在文件开头必须包含string库:库:#include l字符串定义字符串定义:string s1; / 定义字符串变量定义字符串变量s1string s2 = “China”; / 定义字符串变量定义字符串变量s2并初始化并初始化l字符串赋值字符串赋值:可以对定义了的字符串变量进行赋值:可以对定义了的字符串变量进行赋值:s1 = “Hello”;s2 = s1;s3 = s1+s2; / 字符串连接字符串连接l字符串变量的输入输出字符串变量的输入输出:string c1;cin c1;cout =,= 来进行字符串的比较来进

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论