论文部分内容阅读
【摘 要】C++是在C语言的基础上发展起来的面向过程程序设计和面向对象程序设计的一门通用语言,它不仅引入了类和对象等重要概念,而且对C语言的不足进行了改进。本文结合作者多年教学实践,从函数、引用、I/0、内存分配等方面,对C++在非OOP方面对C的改进进行了详细地分析和总结。
【关键词】C++ OOP 引用
在面向对象的程序设计OOP(Object-Oriented Programming)方法出现以前,我们主要采用面向过程的程序设计方法,C是面向过程的程序设计语言的典型代表。早期的计算机主要用于科学计算等领域,例如计算炮弹的飞行轨迹,主要是设计出一个计算方法或解决问题的过程,所以早期的软件开发所面临的问题比较简单。随着计算机领域的扩展,计算机所处理的问题日益复杂,软件系统的规模和复杂性空前扩大,以至于软件的复杂度和其中所包含的错误让程序员无法控制,所以就产生了60年代初期的软件危机。面向对象的程序设计技术很好的解决了问题,而C++语言正是面向对象思想和技术的具体体现。C++是在C的基础上发展起来的,不仅引入了类和对象、继承、多态等概念,而且在非OOP方面对C也进行了改进和扩充。
一、函数方面
(一)重载/过载(overload)
C++中允许两个或者多个不同的函数可以使用同一个函数名,即一个函数名可以对应多个函数的实现。这是C++增强的功能,C语言中是每个函数必须有唯一的名称。例如可以在一个程序中定义两个同名的函数int s(int x,int y){return x+y}和int s(int x,int y,int z){return x+y+z}。同一函数被多次定义或实现,编译器会根据函数参数个数或参数类型的不同来正确的调用。在使用重载时,需要注意一下四点1.不能因为返回值类型不同而重载。例如:int max(int a,int b)和float max(int a,int b)。2.重载不是重复。例如:int max(int a,int b)和float max(int c,int d)。3.不能因为typedef而重载。如:typedef int INT; int max(int a,int b); float max(INT a,INT b),因为typedef定义的是新的类型的名字,而不是新的类型。4.防止有二义性的调用。如:int fun(int a,int b=0); int fun(int a),用fun(3)去调用。
(二)内联函数(inline function)
因为我们在调用函数时,需要先保存现场状态和返回地址,然后转到子函数的代码起始地址去执行,子函数执行完后,又需要取出先前保存的返回地址和现场状态,再继续执行,这一切都需要时间和空间方面的开销,因此对一些功能简单,规模较小,使用频繁的函数,可以设计为内联函数。声明格式:inline 类型说明 函数名(形参表);内联函数具有一般函数的特性,不同之处在于对函数调用的处理,它不是在函数调用时发生转移,而是在编译时由编译器将函数体嵌入到每一个函数调用的语句处,这样就节省了参数传递和控制转移等开销,从而解决了函数调用的效率问题。因为函数有跳转和返回时,程序执行的效率会急剧下降。他从功能上相当于C中的宏,却没有宏的副作用,即消除了使用宏定义#define带来的不安全性(产生这个问题的原因是:C中宏定义#define的代码是被直接展开的,而C++的内联函数的代码是被替代的)。使用时应该注意:1.内联函数体内不能有循环语句和switch语句。2.内联函数的定义必须出现在第一次被调用之前。3.编译时用函数代码替代了调用语句,增加了目标程序的代码量,虽然不发生跳转了,节省了时间,却增加了空间开销,可见,它是以空间增大的代价来换取时间的节省。
(三)函数原型(function prototype)
C语言建议我们为每个函数建立原型,而C++则要求必须为每个函数建立原型,说明函数的返回值类型、函数名称、参数类型及个数。只要函数调用在自定义函数之前,程序员必须在源代码中说明函数原型。函数原型可不包含形参变量名,只包含形参数类型名。如:int fun(int ,int);等价于int fun(int a,int b);目的是在编译时检查调用函数是否与预先说明的原型一致,以维护程序的正确性。函数原型格式为:返回类型 函数名(参数表);使用函数原型时应注意:1.函数原型是一条语句,必须以分号结束。2.当一个函数的定义在前而调用在后时,可以不写它的原型,因为这时的函数定义的说明部分就起到了函数原型的作用。3.主函数不必说明原型,它被认为是一个自动说明原型的函数,且不存在被调用的问题。4.函数的原型中如果没有写返回类型,则C++的默认返回类型为int。5.如果没有返回值,函数必须声明为void,比如把main()声明为void,则主函数中就不用写有return 0了。
(四)缺省参数(default parameter)
C++中可以在说明函数原型或函数定义时,给一个或多个参数指定缺省值,这样在调用该函数时,如果省略了其中的某个参数,系统会自动以用户指定缺省值作为该参数的值。例如:int f(int x,int y=10);在编程时需要注意:1.当一个函数带有多个参数时,C++没有规定函数调用时实参的求值顺序,而编译器根据对代码进行优化的需要自行规定对实参的求值顺序,有的编译器规定自左向右,有的自右向左,如果实参表达式中带有副作用的运算符(++,--等)时,可能造成二义性。例如:int add_int(int x,int y){return x+y;}void main(){int c=4,d=6;cout<< add_int(++c,c+d)< intfun(int a,int b)不能写成int a,b;int fun(x,y)。而且变量定义的位置不一定在函数的首部,可以在任意位置。C中要求所有局部变量的定义必须在执行语句之前。
二、引用(Reference)
引用是某个变量或者对象的别名。引用的值将随所引用的变量的值而改变。定义格式:<类型>&<引用名>=<初始值>;例如:int m;int &n=m;n就是m的引用。需要注意的是:1.引用不占单独的内存空间, 上面的m和n是同一变量单元。2.声明引用时,必须对它初始化,不能声明完成后再赋值。3.指针是通过地址间接访问变量,引用是通过别名直接访问变量,使用引用可以简化程序。4.引用运算符“&”仅在声明引用时使用,其他时候“&”依然表示地址操作符。引用的主要用途是可以用做函数参数和函数的返回值。
三、其他当面
(一)常量推荐用const代替define
例如:const double pi=3.1415926;const产生一个具有类型的常量。const定义一个局部变量,define范围为整个源文件。使用const定义常量是一个标准说明语句,以分号结束。
(二)动态内存分配时使用new和delete。new和delete操作符是C++语言的一部分,无需包含头文件
从C++的立场来看,不能使用C语言中的malloc()函数的一个原因是,它在分配空间时不能调用构造函数。类对象的建立是分配空间、构造结构以及初始化的三位一体,他们统一由构造函数完成。而用new创建对象时,会自动调用构造函数,用delete删除对象时,也会自动调用析构函数。
(三)I/O流类控制
C语言提供的scanf()和printf()标准输入输出函数存在缺陷:非类型安全,不可扩充。比如C++中大量的类和对象并不是基本数据类型,C语言的输入输出函数根本无法识别,因此C++提供了一个I/O流库,用cin对象来处理标准输入,用cout来处理标准输出。
(四)支持单行注释//
我们可以用C语言中的/*……*/进行大范围注释,而用//……进行单行注释。
四、结论
C++语言是在C语言的基础上发展起来的,它继承了传统C语言的精华,增加了面向对象的特征,还在面向过程方面对C语言进行了许多的扩充和改进。本文从函数、引用、I/0、内存分配等方面,对这些改进进行了详细地分析,希望对C++相关编程人员有所帮助。
参考文献:
[1]吕凤翥.C++语言基础教程(第二版)[M].北京:清华大学出版社,2007.
[2] Bruce Eckel.C++編程思想[M],北京:机械工业出版社,2011.
[3] Stanley B.Lippman.C++Primer(第四版) [M].北京:人民邮电出版社,2008.
作者简介:
张永超(1980-),男,汉族,陕西宝鸡人,吉林化工学院讲师,主要从事计算机高级程序设计与数据库等方面的研究。
【关键词】C++ OOP 引用
在面向对象的程序设计OOP(Object-Oriented Programming)方法出现以前,我们主要采用面向过程的程序设计方法,C是面向过程的程序设计语言的典型代表。早期的计算机主要用于科学计算等领域,例如计算炮弹的飞行轨迹,主要是设计出一个计算方法或解决问题的过程,所以早期的软件开发所面临的问题比较简单。随着计算机领域的扩展,计算机所处理的问题日益复杂,软件系统的规模和复杂性空前扩大,以至于软件的复杂度和其中所包含的错误让程序员无法控制,所以就产生了60年代初期的软件危机。面向对象的程序设计技术很好的解决了问题,而C++语言正是面向对象思想和技术的具体体现。C++是在C的基础上发展起来的,不仅引入了类和对象、继承、多态等概念,而且在非OOP方面对C也进行了改进和扩充。
一、函数方面
(一)重载/过载(overload)
C++中允许两个或者多个不同的函数可以使用同一个函数名,即一个函数名可以对应多个函数的实现。这是C++增强的功能,C语言中是每个函数必须有唯一的名称。例如可以在一个程序中定义两个同名的函数int s(int x,int y){return x+y}和int s(int x,int y,int z){return x+y+z}。同一函数被多次定义或实现,编译器会根据函数参数个数或参数类型的不同来正确的调用。在使用重载时,需要注意一下四点1.不能因为返回值类型不同而重载。例如:int max(int a,int b)和float max(int a,int b)。2.重载不是重复。例如:int max(int a,int b)和float max(int c,int d)。3.不能因为typedef而重载。如:typedef int INT; int max(int a,int b); float max(INT a,INT b),因为typedef定义的是新的类型的名字,而不是新的类型。4.防止有二义性的调用。如:int fun(int a,int b=0); int fun(int a),用fun(3)去调用。
(二)内联函数(inline function)
因为我们在调用函数时,需要先保存现场状态和返回地址,然后转到子函数的代码起始地址去执行,子函数执行完后,又需要取出先前保存的返回地址和现场状态,再继续执行,这一切都需要时间和空间方面的开销,因此对一些功能简单,规模较小,使用频繁的函数,可以设计为内联函数。声明格式:inline 类型说明 函数名(形参表);内联函数具有一般函数的特性,不同之处在于对函数调用的处理,它不是在函数调用时发生转移,而是在编译时由编译器将函数体嵌入到每一个函数调用的语句处,这样就节省了参数传递和控制转移等开销,从而解决了函数调用的效率问题。因为函数有跳转和返回时,程序执行的效率会急剧下降。他从功能上相当于C中的宏,却没有宏的副作用,即消除了使用宏定义#define带来的不安全性(产生这个问题的原因是:C中宏定义#define的代码是被直接展开的,而C++的内联函数的代码是被替代的)。使用时应该注意:1.内联函数体内不能有循环语句和switch语句。2.内联函数的定义必须出现在第一次被调用之前。3.编译时用函数代码替代了调用语句,增加了目标程序的代码量,虽然不发生跳转了,节省了时间,却增加了空间开销,可见,它是以空间增大的代价来换取时间的节省。
(三)函数原型(function prototype)
C语言建议我们为每个函数建立原型,而C++则要求必须为每个函数建立原型,说明函数的返回值类型、函数名称、参数类型及个数。只要函数调用在自定义函数之前,程序员必须在源代码中说明函数原型。函数原型可不包含形参变量名,只包含形参数类型名。如:int fun(int ,int);等价于int fun(int a,int b);目的是在编译时检查调用函数是否与预先说明的原型一致,以维护程序的正确性。函数原型格式为:返回类型 函数名(参数表);使用函数原型时应注意:1.函数原型是一条语句,必须以分号结束。2.当一个函数的定义在前而调用在后时,可以不写它的原型,因为这时的函数定义的说明部分就起到了函数原型的作用。3.主函数不必说明原型,它被认为是一个自动说明原型的函数,且不存在被调用的问题。4.函数的原型中如果没有写返回类型,则C++的默认返回类型为int。5.如果没有返回值,函数必须声明为void,比如把main()声明为void,则主函数中就不用写有return 0了。
(四)缺省参数(default parameter)
C++中可以在说明函数原型或函数定义时,给一个或多个参数指定缺省值,这样在调用该函数时,如果省略了其中的某个参数,系统会自动以用户指定缺省值作为该参数的值。例如:int f(int x,int y=10);在编程时需要注意:1.当一个函数带有多个参数时,C++没有规定函数调用时实参的求值顺序,而编译器根据对代码进行优化的需要自行规定对实参的求值顺序,有的编译器规定自左向右,有的自右向左,如果实参表达式中带有副作用的运算符(++,--等)时,可能造成二义性。例如:int add_int(int x,int y){return x+y;}void main(){int c=4,d=6;cout<< add_int(++c,c+d)<
二、引用(Reference)
引用是某个变量或者对象的别名。引用的值将随所引用的变量的值而改变。定义格式:<类型>&<引用名>=<初始值>;例如:int m;int &n=m;n就是m的引用。需要注意的是:1.引用不占单独的内存空间, 上面的m和n是同一变量单元。2.声明引用时,必须对它初始化,不能声明完成后再赋值。3.指针是通过地址间接访问变量,引用是通过别名直接访问变量,使用引用可以简化程序。4.引用运算符“&”仅在声明引用时使用,其他时候“&”依然表示地址操作符。引用的主要用途是可以用做函数参数和函数的返回值。
三、其他当面
(一)常量推荐用const代替define
例如:const double pi=3.1415926;const产生一个具有类型的常量。const定义一个局部变量,define范围为整个源文件。使用const定义常量是一个标准说明语句,以分号结束。
(二)动态内存分配时使用new和delete。new和delete操作符是C++语言的一部分,无需包含头文件
从C++的立场来看,不能使用C语言中的malloc()函数的一个原因是,它在分配空间时不能调用构造函数。类对象的建立是分配空间、构造结构以及初始化的三位一体,他们统一由构造函数完成。而用new创建对象时,会自动调用构造函数,用delete删除对象时,也会自动调用析构函数。
(三)I/O流类控制
C语言提供的scanf()和printf()标准输入输出函数存在缺陷:非类型安全,不可扩充。比如C++中大量的类和对象并不是基本数据类型,C语言的输入输出函数根本无法识别,因此C++提供了一个I/O流库,用cin对象来处理标准输入,用cout来处理标准输出。
(四)支持单行注释//
我们可以用C语言中的/*……*/进行大范围注释,而用//……进行单行注释。
四、结论
C++语言是在C语言的基础上发展起来的,它继承了传统C语言的精华,增加了面向对象的特征,还在面向过程方面对C语言进行了许多的扩充和改进。本文从函数、引用、I/0、内存分配等方面,对这些改进进行了详细地分析,希望对C++相关编程人员有所帮助。
参考文献:
[1]吕凤翥.C++语言基础教程(第二版)[M].北京:清华大学出版社,2007.
[2] Bruce Eckel.C++編程思想[M],北京:机械工业出版社,2011.
[3] Stanley B.Lippman.C++Primer(第四版) [M].北京:人民邮电出版社,2008.
作者简介:
张永超(1980-),男,汉族,陕西宝鸡人,吉林化工学院讲师,主要从事计算机高级程序设计与数据库等方面的研究。