1、1,第二讲 C+语言的新特性(1),张仕,数学与计算机科学学院 E-mail:,2,教学提纲,一、教学内容: VC+6.0开发环境的使用,C+语言的新特性(与C语言不同的部分)。 二、学时:两课时 三、教学目的和要求 了解VC+ 6.0开发环境的基本使用方法 掌握C+语言与C不同的一些新特性 四、教学重点和难点 重点:函数重载 难点:函数重载,3,五. 教学过程提要,演示安装VS 6.0和MSDN; VC+ 6.0开发环境的初步使用 简单C+控制台程序的编译、调试和运行 C+的关键字 const修饰符 内联函数 带缺省参数的函数 函数重载,4,C+语言的一些新特性,单行注释和新的I/O流 co
2、nst修饰符 内联函数 函数原型 带缺省参数的函数 函数模板 函数名重载 new和delete运算符 引用(reference),5,2.1 VC+的开发环境,2.1.1 VC+简介Visual Studio 6.0的一部分。VC+集编辑、编译、连接、调试等于一体,给编程人员提供了一个完整而又方便的开发界面和许多有效的辅助开发工具。 2.1.2 VC+开发环境的使用这部分的内容参考教材第一章。,6,/example2.1 /在屏幕上显示星号的三角形阵列 #include /预处理 void DoDraw(int num); void main( ) /主函数 int num=5;DoDraw(
3、num); ,【例2.1】简单的C+程序,2.2 C+程序结构,7,注: cout为输出流,类似C语言的printf,endl 表示换行。使用IO流应包括头文件 iostream.h 如果要使用C的函数printf,必须在程序前面加上:#include 才可以将函数printf的原型声明包含进来。,void DoDraw(int num) for(int i=0;inum;i+) for(int j=0;j=i;j+)cout*; coutendl; ,例2.1,8,C程序与C+程序比较,#include “stdio.h“ main( ) char a,b,c; int i=10;a = B
4、; b = O; c = Y; putchar(a);putchar(b); putchar(c); printf(“i=%s”,i); ,#include “iostream.h“ void main( ) char a,b,c; a = B; b = O; c = Y; coutabcendl; int i=10; /变量声明不必放在开始位置cout“i=“i; ,9,【例2.2】 /example2.2,#include /预处理 class test /定义类 testpublic: /定义类的公共部分test(int y) x=y;void print( ) cout x endl;
5、private: /定义类的私有部分int x; ; void main( ) /主函数 test ob(5); /定义具体的对象ob.print( ); /消息激活服务 print;结果:显示 x 的值5,10,演示例题1、2在VC+中的调试、运行和排错。,11,2.3.1 C和C+都有的关键字(常用),int、float、char、struct、union、const、static、long、short、unsigned、signed、void、enum、extern、double、typedef、for、if、else、while、do、switch、case、default、break
6、、continue、return,问题 能否用关键字作标识符?,答案:不能!(为什么?),2.3 C+关键字,12,2.3.2 C+ 特有的关键字 (常用),class 定义类; public, private, protected 定义公共, 私有, 保护属性和服务;friend 定义友元; operator 定义运算符; inline 定义内联函数; virtual 定义虚函数; template 定义模板; new, delete 分配和消除存储空间 this 指向自己的指针,13,2.4 const 存取修饰符,在C中,可以使用#define来定义符号常量 。 #define BUFS
7、IZE 100C+中建议使用一种更灵活、更安全的方式来定义常量,即使用关键字const来定义常量: const int bufsize = 100;,14,2.4.1 常量例子,const double PI = 3.1415926; / PI是一个常量 const int v =1,2,3,4; /数组元素vi是常量 const int x; / error: no initialize /定义常量时应初始化,否则出错。,void fun1( ) v2+; / error ,【例2.3】 /example2.3,15,#include /预处理 #define CP 3/0 int main
8、(int argc, char* argv) int i=10; double x;if (i10)x=i*CP;cout“i=“iendl;return 0; ,16,2.4.2 常量const和指针,(1)指针所指向的对象为常量 Pointer to const(2)指针本身为常量 const pointer,17,指向常量的指针 Pointer to const,const int* u; / pointer to constant const int p=10; u= /error:cannot convert from const int * to int *,18,常指针 cons
9、t pointer (固定指向一个变量),int d = 1,e=2; int* const w = / error: w is const,19,2.4.3 const修饰函数参数,函数的形参也可以声明为常量,const可以阻止参数被函数修改。例如,strcmp函数的原型声明为:int strcmp(const char *, const char *);,作用:将参数声明为常量,使在函数的调用过程中,参数不被改变。在软件的实际开发中很有用。,20,常量类型在其作用域内不能改变,这在大型软件开发中很重要:,为什么:1. 防止在函数体内改变参数的值2. 减小程序出错的可能性3. 提高程序的可维
10、护性,21,例:,int cmp(const int* p, const int* q) *p=20; /error return *p*q?*p:*q; ,22,2.5 内联函数(inline function),在函数声明或定义的前面加上关键字“inline”,该函数就被声明为内联函数。inline int max(int x, int y) / max被说明为内联函数 int z;if(xy) z=x;else z=y;return (z); ,23,当程序编译时,对内联函数在其调用处进行内置替换,将内联函数的代码插入在调用处,从而消除执行过程中的函数调用开销。 内联函数通常用于小而常用
11、的函数,它与带参数的宏替换相似,但其处理方法不同。宏替换由预处理程序进行简单的字符串替换,在替换过程中不进行语法的检查;而内联函数由C+编译器进行处理,在插入代码之前即进行语法检查。,2.5.1 内联函数的原理,24,一般情况下,只有较短的函数才定义为内嵌函数。使用内嵌函数实际上是一种增加空间开销以减小时间开销的方法。 注意: 在C+中,需要定义的内联函数不能含有循环、switch和复杂嵌套的if语句; 递归函数是不能被用来做内联函数的。,25,2.5.2 函数调用时的时间开销,1函数调用时的时间开销:保护现场,恢复现场。 2用关键字inline说明内嵌函数。编译器直接用内嵌函数体的编译代码插
12、入在函数调用语句处,这一过程称为函数的嵌入扩展。利用内嵌函数减少了调用普通函数时的压栈和弹栈操作,从而提高程序的运行速度。,26,2.5.3为什么使用内联函数,Efficiency 效率 在C程序中,可使用宏macros达到同样的目的,但是宏是通过预处理来处理的,不进行类型检查,容易造成难以发现的错误。 宏macros在类的内部不能使用,宏不能作为类的成员。,27,为什么使用内联函数(cont.),为了克服宏的上述缺陷, C+ 引入了内联函数。内联函数具有高效率,而且: 进行类型检查,避免出现类型不匹配的错误。 可以作为类的成员函数。To retain the efficiency of th
13、e preprocessor macro, but to add the safety and class scoping of true functions, C+ has the inline function.,28,2.5.5 How do inline functions work 编译器处理内联函数的过程,类型检查 Type checking (To assure safety ) 将函数代码插入到函数调用处 then substitutes the function body for the function call 这样函数代码将占据更所得存储空间 The inline co
14、de does occupy space The short,small and frequently called functions are suitable for inline functions.,29,在C+语言中,函数参数允许使用缺省值。当函数调用时,若给出的参数个数少于函数表中参数的总数时,则所缺参数自动取函数参数表中设置的缺省值。下面是一个参数缺省的例子:,void f(int x, int y=10) /此处省略函数体内容 ,2.6 缺省参数,30,该程序定义了一个函数f( ),它有两个整形参数,第二个参数缺省值为10。如调用语句:f(2);就相当于f(2,10)。 函数可
15、以有多个缺省参数,但应注意只能从右往左缺省,例如:int f1(int x, int y=0, int z=0); /正确int f2(int x, int y=0, int z); /错误 当函数既有声明又有定义,不能在函数定义中指定默认参数。,31,例:,void delay(int loop=1000); void delay(int loop) ,32,2.7 函数重载,两或两个以上的函数共享同一个名称,就称为函数名重载。 Overloaded Functions Multiple functions can have the same name with different impl
16、ementations. 函数重载简化了函数调用工作。,33,例子,例如,在C语言的数学函数库中,求绝对值的函数有abs、fabs等,分别用于不同类型的参数;而在C+中,对相同功能但参数类型不同的函数可以使用相同的函数名,在调用时无需记忆多个函数名,而由编译器根据参数类型选择。,34,【例2.4】 求两个数中最大值的函数max,不管其参数的整数类型、实数类型、字符串,都可以使用同名函数来实现,调用时只需使用max就可以了,编译器将根据实参的类型判断应该调用哪一个函数。,int max(int a, int b) if(ab)return a;elsereturn b; ,35,float ma
17、x(float a, float b) if(ab)return a;elsereturn b; char * max(char *a, char *b) if(strcmp(a,b)0)return a;elsereturn b; ,36,注意: (1)重载函数必须具有不同的参数个数或不同的参数类型,若只有返值的不同是不行的。 (2)当函数的重载带有默认参数时,应避免二义性。例如int fun(int a,int b=0);int fun(int a); 是错误的。因为如果有函数调用fun(2)时,编译器无法准确地确定应调用哪个函数。,37,作业,1、P672-74题 2、P672-79题 3、 编写一程序,通过重载函数abs(),实现求int和double类型数据的绝对值。,