公务员期刊网 精选范文 c语言函数范文

c语言函数精选(九篇)

c语言函数

第1篇:c语言函数范文

关键词:函数;C语言;程序

中图分类号:TP312.1 文献标识码:A文章编号:1007-9599 (2011) 12-0000-02

Study on the C Language Function Parameters Application

Lin Lifen

(Fujian Polytechnic of Information Technology,Fuzhou350003,China)

Abstract:The function is the core of C language program design,function of the parameters of the status is more important,this article from the C language using the parameters of grammar,pointer parameters,the array parameter and return value of function of several methods discussed in the C language function parameter of the use of technology,for the C language teaching and C language program design reference.

Keywords:Function;C Language;Program

C语言是一门应用范围很广的学科。它与PASCAL语言本质的区别在于它来源于应用,由此决定了它的实用性很强,语言非常灵活,在教学实践中采取不断地将C语言课程所涉及的内容前后进行比较,更好地领会和吸收所学的知识。下面就以C语言中的难点之一:函数返回值和函数参数返回值为例,谈谈二者之间的区别和函数间参数传递几种常用的方法。

C语言的核心是函数,是以函数为基本模块而构架成的。函数的大量使用,必然要涉及到函数间参数的传递。众所周知,函数间参数的传递是值的传递,其函数参数在被另一函数调用后参加运算时,若其值发生改变,在返回调用函数时,是不会将改变后的值带回调用函数的。

例如,我们设计一个函数,求两个整数之和,函数及调用函数如下:

sum(int a,int b,int s){s=a+b;}

main()

{int x=5,y=7,z=0;

sum(x,y,z);printf("%d+%d=%d\n",x,y,z); }

则程序运行结果并不是5+7=12,而是5+7=0。这是因为函数main中的实际参数x、y、z在传递过程中仅将数值5、7、0单向传递给函数sum中的形式参数a、b、c,并未接受函数sum在运行过程中改变后的值,而造成z值不正确。其解决办法有

(1)将变量z设为外部变量,程序如下

int z=0;

sum(int a,int b) {z=a+b;}

main()

{int x=5,y=7;sum(x,y);printf("%d+%d=%d\n",x,y,z);}

程序运行结果:5+7=12

这种方法能正确解决将函数sum的运算结果返回到调用函数main中,但其缺点是因为选择了外部变量,将使得函数的独立性受到外部变量的限制与约束,与模块化程序设计思想相悖。

(2)将变量z设为函数的返回值,程序如下

int sum(int a,int b){int s;s=a+b;return(s);} }

main()

{int x=5,y=7,z=0;z=sum(x,y);printf("%d+%d=%d\n",x,y,z);} }

程序运行结果:5+7=12

这种方法也能很好的解决将函数sum的运算结果返回到调用函数main中的问题,并且没有破坏函数的独立性。但函数的返回值只能是一个,若函数中有一个以上的参数被修改且需要返回时,用这种函数返回值的方法就无法实现。如下例是将两个整数值进行交换

main()

{int m,n;

scanf("%d%d",&m,&n);if(m

printf("两数中大者是%d,小者是%d\n",m,n);} }

函数swap要求将实际参数m与n所对应的形式参数的值进行交换后返回调用函数,这时用函数返回值的方法就无法实现两个值的返回,所以函数返回值的使用具有一定的局限性。

(3)为解决多个值返回的问题,可采用将变量z设为指针类型的变量,程序如下

sum(int a,int b,int*s) {*s=a+b;}

main()

{int x=5,y=7,k=0;int*z=&k;

sum(x,y,z);printf("%d+%d=%d\n",x,y,*z);}

程序运行结果:5+7=12

函数的参数传递仍为值传递,但在函数sum中,a+b的和并没有送给形式参数s,而是送给了指针s所对应的整型变量k。在返回调用函数时,形式参数s被释放了,但整型变量k的值却保留住了a与b的和。

这种使用指针变量作为函数形式参数的方法保证了函数中模块的独立性。设若干个指针变量就能使得函数中多个参数值被修正后仍然能准确的带回调用函数,所以不失为一种较好的参数传递的方法。但是,当函数只需要一个返回值时,用函数返回值进行传递更直观,也易于与初等数学的概念接轨,所以第二种方法也常常被应用。

函数参数的传递除以上三种外,还可以用数组名以及指向数组元素的指针变量作为参数进行传递。

上面所提到的函数返回值或函数参数返回值只能返回一个或少数几个值,若函数中有一批数据需要返回,则需要设一批指针,这样使用很不方便,这时我们可选择用数组名或指向数组元素的指针变量作为函数的参数进行传递,举例如下:设函数conver是将10个数逆转,并将逆转后所改变的值返回调用函数。我们可采用下面(4)和(5)两种方法

(4)函数的参数用数组名表示,程序如下:

conver(int a[],int n)

{int i=0,j=n-1;

while(i

main()

{int s[10],i;

for(i=0;i

conver(s,10);for(i=0;i

程序运行结果:9,8,7,6,5,4,3,2,1,0,

这是因为C语言规定,当数组名作为函数的参数时,并不是把实际参数中数组元素s[0]...s[9]的值传递给形式参数中数组元素a[0]...a[9],而是将实际参数的起始地址传递给形式参数,也即数组a并没有在内存中开辟存储单元,而是与实参数组s共享同一段存储单元,数组a在函数conver中的变化实际上也是对数组s的改变,当函数conver结束返回调用函数时,形参数组a被释放,但实参数组s却保留了函数改变后的值,也即将函数运算结果返回了调用函数。

(5)函数的参数用指向数组元素的指针变量表示,程序如下:

conver(int*a,int n)

{int*b;

b=a+n;while(a

调用函数同上,程序运行结果:9,8,7,6,5,4,3,2,1,0,

我们知道,指针变量存放的是另一个存储单元的地址,当用数组名作为参数时,实际上是将数组s的首地址进行传递,形参是指针变量a,接收的是数组s的首地址,则*a与s[0]是同一个存储单元;当执行a++后,*a与s[1]是同一个存储单元。所以在函数conver中,指针所指对象*a与*b的交换实际上就是数组元素s[0]与s[9],s[1]与s[8]...的交换,当函数结束返回调用函数时,形参a,b被释放,但实参中的值已经被改变。

第2篇:c语言函数范文

关键词:函数调用;地址传递;数组;指针;C语言程序

中图分类号:TN919-34

1 函数之间数据传递方式分类

C语言程序是由函数组成的。设计C语言程序时,通常将一个大的程序按功能分成若干个较小的模块,每个模块编写成结构清晰、接口简单、容易理解的程序段,即函数。这种方法可建立公用模块,消除重复工作,提高程序开发效率。[1]从函数的形式来看,函数可分为无参函数和有参函数。在调用有参函数时,主调函数与被调用函数之间有数据传递,也就是说,主调函数可以将数据传递给被调函数使用,被调函数中的数据也可以带回来给主调函数使用。

值传递:数据只能从实参单向传递给形参,称为“按值”传递。当基本类型变量作为实参时,在函数调用过程中,形参和实参占据不同的存储空间,形参的改变对实参的值不产生任何影响[2]

引用传递:使实参和形参共用一个地址,即所谓“引用传递”。这种传递方式,无论对哪个变量进行修改,都是对同一地址内存空间的内容进行修改,其实参变量与它的引用即形参变量,总是具有相同的值。例如程序:

2 函数之间的地址传递[3]

2.1 形参为指针变量时函数之间的数据传递。如果函数的形参为指针类型时,对应的实参类型必须与形参的基类型相同。

例如程序:调用swap函数,用指针传递的方式交换主函数中变量x和y中的数据。

函数之间值的传递是单向传递,也就是说函数只能通过实参把值传递给形参,若形参值改变,对实参不会产生影响;把数据从被调函数返回到主调函数的唯一途径就是通过return语句,且只能返回一个数据。若是采用以上通过传递地址值的方式,可以在被调用函数中对主调函数中的变量进行引用,通过改变形参的值而让实参的值得到相应改变,这样就可以实现把多个数据从被调用函数返回到主调用函数。

2.2 一维数组名作实参时函数之间的数据传递。函数之间在进行数据传递时,数组元素可以作为实参传递给形参,这时的数组元素与普通变量一样,这种传递实际上就是值的传递。在C语言中,一维数组是由若干类型相同的数组元素组成的,因为数组名本是一个地址值,通常可以把数组名作为实参传送,对应的形参就用指针变量,其基类型与数组的类型要求一致。在函数间进行数据传递时,可以通过此指针变量来引用主调函数中对应的数组元素,从而可以实现对主调函数中对应的数组元素进行数据处理。

当数组名作为实参时,函数调用arrin(a)对应的形参除了指针外,对应函数首部还可以写成arrin(int pa[])和arrin(int pa[N])两种形式。虽然说明的形式与数组的说明相同,但C编译程序时都把pa处理成以上的指针形式。另外,上例中被调用函数除了通过指针引用数组元素*(pa+i)外,还可以写成pa[i]的形式。

2.3 二维数组名作实参时函数之间的数据传递。当二维数组名作为实参时,被调函数的形参必须是一个行指针变量。例如,若主函数有以下二维数组定义:double a[M][N];则被调函数fun的首部可以是以下三种形式之一:(1)fun ( double (*pa)[N]);(2)fun (double pa[M][N]);(3)fun ( double pa[ ][N])。以上无论哪种形式,与一维数组数据传递一样,系统都将把pa处理成一个指针,但是一个行指针。其处理方式一样,系统只为形参开辟一个存放地址的存储单元。

2.4 指针数组作实参时函数之间的数据传递。当指针数组作为实参时,对应的形参应当是一个指向指针的指针。因为函数传递的是一维数组指针数组名,所以参数的定义与2.2中的一维数组名作实参的形式类似。[4]

3 结束语

引用传递虽然可以通过改变形参的值而影响实参,操作比较灵活,但进行批量数据传递有明显缺陷。对数组多个元素以及规模较大的结构体数据进行操作,只能选用地址传递的方式,这种传递方式只需在被调函数中开辟一个存放地址的4字节的存储空间,不需要另外开辟形参的存储空间,实际参数和形式参数对应于相同的内存单元,因此,对形式参数的操作也就是对实际参数的操作。这种传递方式效率高,应用灵活,功能强大。

参考文献:

[1]王明福.C语言程序设计教程[M].北京:高等教育出版社,2004(06):126.

[2]杨战海,薛苏秦,张晓光.基于C语言函数参数传递规律的探讨[J].现代电子技术,2008(16).

[3]Paul.J.Deitel.C++大学教程[M].北京:电子工业出版社,2010(10):278-292.

[4]教育部考试中心.C语言程序设计[M].北京:高等教育出版社,2013(05):130.

第3篇:c语言函数范文

【关键词】函数;返回;多值;方法

在C语言中,一般情况下函数的返回值是通过函数中的return语句来实现的,每调用一次return语句只能从函数中返回一个值。但在实际很多应用中,我们需要从函数中返回多个值,那我们可以用什么方法实现呢?此时我们可以用三种方法来实现。

方法一:设置全局变量

全局变量是在函数外部定义的全局变量,它不属于任何一个函数,其作用域是从变量的定义处开始,到本程序文件的结尾。在此作用域内,全局变量可为各个函数所引用。当我们需要函数返回多个值时,除了函数体中的return语句返回其中一个之外,其它的返回值我们可以通过定义全局变量来处理。因为根据全局变量的特点,在被调用函数中改变了多个全局变量和值,相当于其主调函数全局变量的值也发生了变化,也就相当于返回了多个值。

例如:利用一个函数求出正方形的周长和面积。

#include

double l=0;//定义全局变量l为正方形周长

void f(double a)//定义求面积和周长的函数

{

double s;

s=a*a;//求面积

l=6*a;//求周长,并赋给全局变量l

return s;//仅返回面积的值

}

void main()

{

double a,area;

printf(“请输入边长:");

scanf("%f",&a);

area=f(a);//面积的值通过调用f函数返回值

printf(“面积为:%5.2lf\n”,area);

printf(“周长为:%5.2lf\n”,l);//周长即为全局变量l在f函数中改变后的值

}

上面的例子即用全局变量实现了函数中返回多值的情况,这种方式易懂。但是全局变量用多了会破坏代码的安全性,结构性,这主要是全局变量在所有函数中都可以使用,从而其值的变化不确定,所以我们要慎用。

方法二:使用数组名或指针作为函数的形参

数组名或者指针实际为地址,而数组一般都包括多个元素,指针也可以指向一组数据的着地址,把数组名或者指针作为函数形参,实际上相当于主调函数的实参与形参共用地址,所以在函数中的数组元素发生改变即是实参也随之改变。也相当于在调用函数时多个值返回给主调函数。

例如:

#include

void a(int array[]);

int main()

{

int array[5]={1,2,3,4,5},i;

a(array);

for(i=0;i

printf(“%d”,array[i]);

}

void a(int array1[])

{

int i;

for(i=0;i

array1[i]++;

}

在此程序中,当在主函数中调用a函数时,函数a中的形参数组array1与主函数中的实参数组array实际上共用地址,当函数a中的形参数组array1中的元素改变时,也就是实参数组array中的元素也发生了改变,从效果上看相当于形参把改变后的值传递给实参,而且是改变了多个值。但是这种数组名作为参数时,要求数组元素的类型相同,也就是说用这种方法返回多个值时,要求这多个值的类型必须一样,所以此方法仅适用于返回相同类型的多个值。

方法三:用结构体作为函数的形参

在上述方法二中用数组返回函数多个值的情况,根据数组的特点要求返回的多个值必须是类型相同的数据,但是在实际应用过程中,有时返回值的类型不一定相同,那么我们有不有新的方法来处理这种情况?实际上在C语言中包含多个元素的构造类型除了数组之外,还有结构体和共用体。其中数组的元素类型必须相同,但是结构体和共用体的元素类型可以不相同。而结构体和共用体又有区别,在任何同一时刻,共用体只存放了一个被选中的成员,而结构体的所有成员都存在。因此,当函数需要返回多个不同类型的值时,用结构体来实现是比较函数的多值返回比较合理。例如:

#include

#include

#include

typedef struct student

{

char name[10];

int age;

}Student;

Student*fun1()

{

Student*ps=new Student;

strcpy(ps->name,"zhong");

ps->age=0x100;

return ps;

}

void main()

{

*ps=fun1();

printf(“name:%s\tage:%d”,ps->name,ps->age);

}

上例中fun1函数返回了name和age两个不同类型的值,分别是字符数组和整型,这两个不同的值是被封装在结构体Student中,这样就通过结构体的方式同时返回多个函数值。

以上三种方法都可以解决C语言中返回函数多个值的问题,但是这三种方法的侧重点是有区别的,所以在选择多值返回的方法时要根据实际问题进行合理的分析和选择。

第4篇:c语言函数范文

【关键词】C语言 函数 类比教学法

【基金项目】防灾科技学院重点教研项目2012A04;防灾科技学院第一批精品建设课程。

【中图分类号】G42 【文献标识码】A 【文章编号】2095-3089(2013)06-0165-02

形象类比法属于讲授教学方法的一种,即借助于两类不同本质事物之间的相似性,通过比较,形象地将一种已经熟悉或掌握的特殊对象推移到另一种新的特殊对象上去的推理手段,也是教学中创设真实生动情景的有效工具之一。

C语言对于初学者而言,有一定的难度,学生在学习计算机方面存在比较大的弱点,思维逻辑能力不够强,空间视觉不够敏感。书中涉及到的一些抽象的理论知识,学生理解起来很难。为了帮助学生更好的理解抽象理论知识,在教学过程中,恰当的采用一些类比实例来帮助学生理解并提高学习的兴趣。

在C语言学习过程中,从前面简单的结构化思想转化到函数的模块化设计思想,因为知识的抽象性,学到函数这一章,很多同学反映学起来很困难,有一部分同学从这一章开始“知难而退”,放弃继续学习C语言。结合自己的多年实践教学经验,试从几个形象的例子类比来阐述如果理解复杂抽象的函数理论概念。

一、函数的概念

模块化编程是指将一个庞大的程序划分为若干个功能独立的模块,对各个模块进行独立开发,每一个模块用来实现一个特定的功能,然后再将这些模块统一合并为一个完整的程序。模块化编程使程序易于维护和提高程序段的利用率,这是C语言面向过程的编程方法,可以缩短开发周期,提高程序的可读性和可维护性。模块的功能,在C语言中,由函数完成。函数的工作原理:分而治之!一个C程序可由一个主函数main和若干个函数构成。

一个C程序的执行:从主函数开始,在main函数中调用其他函数,其他函数也可以互相调用。主函数一般都很简单,起到“驱动”的作用,把功能的实现都放在子函数里,一个子函数能做一件或者更多的事,可以说“主函数就是驱动程序,是用来驱动其它子程序(函数),更是整个完整程序的入口。”如果你要进入一个房子,你就必须先找到门,从门里才能进到屋子里去。C语言的主函数,就是你要运行的程序的“门”,不经过它,你就进不了房子。

music( )//音乐播放

{……}

movie( )//影视播放

{……}

online( )/*等等一序列子程序,这些子程序都需要main( )函数来驱动*/

{……}

void main( )

{

music( );

movie( );

online( );

}

程序模块化,使程序开发更容易管理,函数把较大的任务分解成较小的任务。比如:以前作坊式的制衣流程:先纺纱织布,然后剪裁制衣,之后制作扣子缝制完成制衣。这些工作由一个家庭作坊独立完成。类似于在C语言中由主函数完成所有的工作。现在的制衣流程:专业的织布公司、专业的制衣公司、生产加工扣子、拉链等辅料的公司。每一个公司类似于一个独立的“子函数”。

二、向函数传递值

如果函数的参数是基本类型变量和构造类型变量,则传递值的拷贝。

例如制衣公司现在需要1万条白色长30cm的铜拉链,他将把这些数值告诉加工辅料公司,加工辅料公司进行加工生产,即制衣公司“调用”加工辅料公司。这里的1万条、白色、30cm及铜质这四个信息属于传递的“参数”。这些参数对于制衣公司来说属于是“实参”,对于加工辅料公司来说属于“形参”。参数相当于公司之间的一份协议,它们的数据类型必须是一致的。制衣公司因为需求可以改变“实参”,例如改成加工2万条白色长30cm的铜拉链,这时“实参”改变的时候,“形参”也跟着改变;但是,加工辅料的公司没有自行改变制衣公司实参的权利,这就是函数的“形参”改变,“实参”不变的原则。

void Clothing_com( )//制衣公司

{

……

Accessories_com (1000,white,30,copper);//实参

……

}

void Accessories_com (int num,char color[10],float lenth,char quality[10])

//辅料公司,形参num:拉链数量;color:拉链颜色;lenth:拉链长度;quality:拉链质地

{ …… }

void main( )

{

Clothing_com( );

}

同一个函数可以被一个或多个函数调用任意多次,如加工辅料的公司可以和很多不同制衣公司合作。

三、向函数传递地址

如果参数是数组和指针变量,即地址,则传递地址值。

例如学校要铺草坪,即学校“调用”草坪公司。一种方法是让草坪公司在自己公司内种植草坪,草坪成熟后送到学校来,学校自己完成草坪铺种。一种方法是由草坪公司直接把草坪种植到校园里。

第一种方法,学校需要明确告诉草坪公司需要多大面积的草坪数,函数传递值的拷贝。

char *Lawn_Com(float area)//草坪公司

{

char col_lawn[100];

for(int i=0;i

col_lawn[i]='*';//用*代表种植的草坪

return col_lawn;

}

void college( )//学校

{

char *college_lawn;

college_lawn=Lawn_Com(30);//30是形参,草坪公司把成熟的草坪送到学校的college_lawn。

}

void main( )

{

college( );

}

第二种方法里,学校需要明确告诉草坪公司在学校的哪个位置种植草坪,草坪公司直接派遣工作人员去“实参”所指示的“地址”种植草坪就可以了,函数参数传递的是地址。当函数参数传递的是地址值时,通过地址找到实参,然后直接对实参进行操作。

void Lawn_Com(char col_lawn[30])//草坪公司

{

for(int i=0;i

col_lawn[i]='*';//用*代表种植的草坪

}

void college( )//学校

{

char college_lawn[30];

Lawn_Com(college_lawn);//草坪公司到学校的college_lawn

}

void main( )

{

college( );

}

四、函数的返回值

函数的返回值就是把函数执行完之后的结果带回给主调函数。函数可以有返回值,也可以没有返回值。

如学校“调用”草坪公司铺设草坪,在第一种方法中,学校要求草坪公司在其公司内部铺种草坪,把铺种成熟后草坪作为“返回值”送到学校,学校自己把草坪种到校园里,这是有返回值的函数。而在第二种方法中,学校要求草坪公司直接把草坪种到校园里,草坪种完就完成任务,草坪公司就不要再提交学校返回值了。

再如制衣公司“调用”辅料加工公司,辅料加工公司按照“实参”的要求把加工完的拉链成品作为“返回值”提交给制衣公司。

五、结束语

除了函数这一章外,笔者在C语言程学设计其他章节内容的教学中均尝试采用了形象的类比教学法,效果显著。类比教学法要求教师具有高度的概括能力,将知识进行归纳总结,在教学过程中,让学生将实际应用和生活所熟悉的事物与枯燥、抽象的概念理论进行类比,培养学生分析和解决问题的能力,提高学生的学习兴趣,让学生喜欢C语言,学好C语言。

参考文献:

[1]谭浩强.C程序多设计.第3版.清华大学出版社,2005

[2]韩莹,丰继林,单维锋.C语言实训教程.第1版.清华大学出版社,2013.1

第5篇:c语言函数范文

1构造函数和析构函数

(1) 从C的构造函数SetString到C++的转换缺省构造函数的过程是,将指针参量s改名为this后隐藏,给参数c加上缺省值,去掉返回值类型说明。[2]

构造函数实质上是初始化语言的推广,经过C描述的结构,到C++阶段达到了和语言内部类型的初始化语句统一的形式。例如:

String S("ok");

等价于

String S="ok";

和语言内部类型变量的初始化语句的形式统一,例如:

float f=5;

给用户定义的类的对象初始化,一般不仅需要传递初始值,还要定义初始化过程,特别是当这个类含有指针成员的时候,所以构造函数保留了参数表和函数体。之所以去掉返回值类型说明,是因为初始化过程是在构造函数体内完成的,不是由构造函数的返回值完成的。

语言内部类型变量还有复制初始化语句:

float f=5;

float g=f;

所以用户类型,特别是含有指针成员的类型,需要增加复制构造函数:

String::String(const String& cs); //复制构造函数

应用举例:

String S="ok";

String T(S);

等价于

String T=S;

相应的,语言内部类型也增加了等价的初始化语句形式:

float f(5); //float f= 5;

float g(f); //float g=f;

复制构造函数调用语句所具有的初始化赋值形式决定了其参数应该是引用型。[2]

(2) 对语言内置类型之间的转换,编译器自有转换机制,依据“升格”原则自动转换。例如实行下面的语句

float f=5;

就是自动转换,把整数5转换为单浮点型赋给f。

但是用户类型之间的转换,用户类型和内置类型之间的转换,需要用户定义转换函数。编译器遇到非内置类型之间的转换,就会去寻找相应的转换函数。当构造函数仅有一个参数,或仅有第一个参数没有默认值,而且这个参数是不同于该类的另一种数据类型,这个构造函数就叫转换构造函数。因此,串类的缺省构造函数

String(const char *c="");

也是转换构造函数。实行下面的语句

String S="ok"; //String S("ok");

就需要隐式调用转换构造函数,我们称之为隐式转换。

这种隐式转换经常发生在函数调用中,如表2所示。

也有这样的时候,一个类不允许隐式调用转换构造函数,这就要在转换构造函数声明前加关键字explicit,即显式调用转换构造函数:

String S=String("ok"); //显式调用转换构造函数

String S=(String) "ok"; //显式调用转换构造函数

表2中的调用语句

func1("ok");

要改进为:

func1(String("ok"));//或func1((String) "ok");

以前我们是这样解释return语句的:假设函数返回值类型是类串,那么

return("ok");

相当于

String _temp="ok"; //系统根据返回值类型创建一个临时变量

但是有了explicit修饰符,这样的解释就不够了。这需要隐式类型转换,而如果串类的转换构造函数有explicit修饰,这就是非法的。因此对含有用户类型的调用,需要重新解释return的内部实现过程如下:

String _temp=String("ok"); //显式调用转换构造函数

类似的形式还有:

String T=String(S); //显式调用拷贝构造函数

相应的,对语言固有类型也需要引入相应的初始化形式,以达到统一。例如

float _temp=int(5);

float g=float(f);

(3) 在C++中,析构函数是构造函数的逆运算,名称是构造函数名前加“~”,如~String。结束生命周期时,系统自动调用析构函数。一个类,若含指针成员,且指向动态空间,则必须创建析构函数。

运算符new在隐含调用构造函数时需要传递的参数在其后加括号给出。

String *pS;

pS=new String("ok");

运算符delete与free的主要区别是,前者在释放pS指向的空间之前,负责调用析构函数。

2成员赋值运算符函数

一个C结构串或C串,不能通过赋值运算符“=”,只能通过赋值函数给另一个结构串赋值,原因是结构串含有指针成员。现在C++允许把成员赋值函数扩展为成员赋值运算符函数operator=,使赋值函数形式与赋值运算符形式等价。

C++串类的应用举例:

String S,T,Y,W;

W="work"; //W.operator=("work");

Y=W; //Y.operator=(W);

S=T=Y; //S.operator=(T.operator=(Y));

(S=T)=Y;//(S.operator=(T)).operator=(Y);

(S="hard")=Y;//(S.operator=("hard")).operator=(Y);

对应的C串结构应用举例:

String S,T,Y,W;

SetString(&S,""), SetString(&T,""), SetString(&Y,""), SetString(&W,"");

CStrAssign(&S,"work");

StrAssign(&Y,&W);

StrAssign(&S,StrAssign(&T,&Y);

StrAssign(StrAssign(&S,&T),&Y);

StrAssign(CStrAssign(&S,"hard"),&Y);

(1) 复制赋值运算符函数和转换赋值运算符函数有区别:前者是用一个类串修改另一个类串;后者是用一个C串修改一个类串:

String S,T,W ("work");

S=W; //调用拷贝赋值运算符函数

T="work"; //调用转换赋值运算符函数

(2) 赋值运算符函数与构造函数有区别:前者是用一个已存在的串修改另一个已存在的串,而且有返回值;后者是用一个已存在的串创建一个串:

String T="study", W="work"; //调用缺省构造函数,用C串创建类串

String S=W; //调用拷贝构造函数,用类串创建类串

T=W; //调用拷贝赋值运算符函数,用类串修改类串

T="work"; //调用转换赋值运算符函数,用C串修改类串

(3) 如果没有转换赋值运算符函数,那么C++编译器会通过转换构造函数和拷贝赋值运算符函数联合实现其功能:先调用转换构造函数,生成临时匿名对象,再调用拷贝赋值运算符函数,将临时对象赋值。例如:

T="work";

C++编译器将其转换为:

T.operator=String("work");

String _temp="work"; //调用转换构造函数,生成临时匿名对象,假设为temp

T=_temp; //调用拷贝赋值运算符函数,用临时对象赋值

概括起来:

转换赋值运算符函数=转换构造函数+赋制赋值运算符函数

3成员转换函数

与转换构造函数和转换赋值函数的转换方向相反,C++成员转换函数把类对象转换为他类对象(见表5)。

应用举例:

String S("work"),T("hard");

char *c1=S; //char* c1=S.operator char*();

char *c2=(char*)S; //char* c2=S.operator char*();

c1=T; //c1=T.operator char*();

c2=(char*)T; //c2=T.operator char*();

4结束语

把C作为C++的元语言,这时C++的概念就可以用C程序严格地描述,避免C++解释中的歧义性和模糊性,有利于理解;而且对C++,我们就不必从开头讲起,可以直接讲授C++相对C的修正和补充部分,有利于深入。另外,C++的新标准包含数据结构,说明C++和数据结构是一个整体,而C语言作为元语言,其教学内容也应该包含数据结构,但是包含多少为宜,根据Occam原理“每一个公理系统都是可以改进的,但改进不能超过其必要性。”[1]还有许多需要我们大家共同研究的地方。

参考文献:

第6篇:c语言函数范文

关键词:.NET ;C#语言;构造函数

中图分类号:TP311文献标识码:A 文章编号:1009-3044(2008)27-1994-02

Analysis of Constructor Function in C#

XIA Qing-Lin

(Lujiang County, Anhui Province Management of Public Housing Management Personnel,Lujiang 231500,China)

Abstract:Constructors function in the C# language is a very important way, this article briefly introduced the concept of constructor function and role of a system introduced in all types of structural function of the use of C# language, and in the process of using a number of issues need attention.

Key words: .NET; C#Language; constructor

1 引言

微软公司于2002年了.NET平台,它集成了各种软件、技术、组件和服务,随着.NET平台的微软也同时推出了一种新的语言――C#。C#不仅从C++语言吸取了语言简单、优雅的优点,而且具有同JAVA语言类似的完全面向对象和与平台无关等优点,此外C#与WEB紧密结合,且对XML提供了很好的支持,因此使用C#不仅可以很快捷地开发Windows应用程序和WEB应用程序,也可以方便地开发XML Web Services应用程序,所以C#语言一经推出,立刻在业界引起轰动,目前它已成为众多软件开发人员的首选语言之一。

C#是一种完全面向对象的语言,不仅提供了高度的抽象、封闭、继承、多态等特性,而且同样提供了构造函数用来完成对象的初始化等工作,相对于C++和JAVA,C#中的构造函数提供了更加强大的功能,具有自身的特色。

2使用实例构造函数创建对象

在各种面向对象语言中,类都是一个是最基本和最重要的概念。类是一种自定义的数据类型,是现实世界中各种实体的抽象,在类中可以封装各种数据及操作,可以包含各种成员,比如在C#语言中,可以有成员变量、成员方法、属性、索引器、委托等等。构造函数就是类中一种特殊的成员方法,它会在创建类的对象实例时被系统自动调用执行,人们调用构造函数来为类对象分配空间,给它的数据成员赋初值,以及其它请求资源的工作。

在C#中实例构造函数又分为默认构造函数和非默认构造函数,默认构造函数由系统自动提供,没有参数和函数体语句,当我们没有显式定义构造函数时,系统会自动生成,实际上它仅负责创建对象,而不做任何初始化工作。如果我们想在对象创建时被自动初始化类中的成员数据或执行某些操作,可以使用非默认构造函数,它具有以下几个特点:(1)访问修饰符一般总为public(也可以为private,此时该构造函数称为私有构造函数,不能用于对象的初始化,一般为另一个公开的构造函数所调用);(2)构造函数名与类名相同;(3)没有返回值类型,如下例所示:

using System;

class Point

{

public intx, y;

//下面为实例构造函数的定义

public Point(int x , inty)

{

this.x = x;

this.y = y;

}

//类中其它成员的定义

}

当我们使用new运算符来实例化对象时,系统会自动调用其构造函数来生成对象,并在堆上为其分配内存空间,然后进行初始化操作,如可用下面的系列语句来生成一个位于(10,10)位置的点对象a:

class Test

{

pulic static void Main()

{

Point a = new Point(10, 10); // 自动调用构造函数来初始化对象

}

}

3 重载构造函数

在C#中方法是可以重载的,通过使用方法重载,可以实现静态的多态性,通过引用相同的方法名和不同的参数来执行类似的功能。由于构造函数是类中一种特殊的方法,所以它也可以进行重载,通过重载构造函数可以实现对象初始化的多样化。

与方法的重载相似,当我们在类中定义两个或两个以上的构造函数,它们的函数名称相同(由于构造函数与类名相同,所以必然相同),而函数的参数不同(或参数个数不同,或参数类型不同),就实现了构造函数的重载。当我们使用new操作符来实例化对象时,系统会自动根据实参的个数及类型来寻找并调用与之相匹配的构造函数。如下例所示:

using System;

class Triangle

{

doublies;

//构造函数1:已知三角形三边,根据海伦公式求面积

public Triangle(doulue a,double b,double c)

{

doublep=(a+b+c)/2;

s=Math.Sqrt(p*(p-a)*(p-b)*(p-c));

}

//构造函数2:已知三角形的底和高求面积

public Triangle(double l,double h)

{

s=l*h/2;

}

}

由于在该类中定义了两个构造函数,具体调用哪个将由参数来决定,如下例代码所示:

Triangle t1 = new Triangle(3,4,5);//系统自动调用构造函数1

Triangle t2 = new Triangle(4,5);//系统自动调用构造函数2

4 静态构造函数

在类中不仅有实例变量,还可能会有静态变量,前已述及实例变量可以使用实例构造函数进行初始化,与之相对应C#中可以使用静态构造函数来对类中静态变量进行初始化。静态构造函数在该类被第一次使用(使用静态成员或调用其实例构造函数)之前被自动调用,且只调用一次。显而易见,如果一个类中既有实例构造函数,又有静态构造函数,必然会先调用实例构造函数。

此外还必须要注意的是静态构造函数只能对静态数据成员进行初始化,而不能对非静态数据成员进行初始化;而实例构造函数既可以对静态数据成员赋值,也可以对非静态数据成员赋值。静态构造函数的定义是非常简单的,只要在定义时前加static修饰符即可,如下例所示:

using System;

classPerson

{

static strint nation;//静态数据成员

stringname; //非静态数据成员

//静态构造函数的定义

static Person()

{

nation= "CHINA";

}

//实例构造函数的定义

Person(string sname)

{

name = sname;

}

}

5 结束语

构造函数看似简单,实示上它是C#中极其重要的一种函数,灵活而正确的使用构造函数能够帮助你编制更有效的程序、更好的理解CLR的内存管理机制,以及更好的管理系统中的资源。

参考文献:

[1] 微软公司.C#程序设计语言[M].北京:高等教育出版社,2003.

第7篇:c语言函数范文

一般进入大学后,学生才会逐渐的接触到计算机C语言,计算机C语言是一门新的计算机语言,其主要是进行计算机编程,这些计算机程序在实际工作中有很大的作用。虽然计算机C语言现已广泛流行,有很大的作用,但是对于学生而言仍然是一门很难的学科,学生很难对C语言进行掌握,不理解C语言,但是学生一旦学会C语言,就会进行各种程序的编写,发现C语言的魅力。在本文中,我们对C语言编写程序的技巧进行学习。

一、计算机C语言内容

想要学习计算机C语言并不是一件很难的事情,C语言编写程序是一件水到渠成的事情,C语言主要课可以分成这几个模块:(1)语言运算符和运行顺序。(2)C语言的基本程序结构,顺序、选择以及循环。(3)数组。(4)函数。(5)指针。(6)结构体和共用体。(7)文件。C语言的运算符和运算顺序是学习计算机C语言的基础,也是计算机C语言的独特之处,计算机C语言的运算非常的灵活,运用也非常的丰富,当一个运算中出现多种运算时,在组合运算表达式中,就会出现优先运算顺序和结合规则。计算机C语言是三种基本程序的结构,这三种程序结构是学习计算机C语言必须掌握的程序结构,所有的程序结构都是按照执行顺序进行的,在执行程序的过程中,会根据输入的任务选择结构,并不断的执行相关的任务指导满足选择结构的条件[1]。数组其实就是一组数据的有序结合,在计算机C语言编写程序中需要对有共同性质的数据进行处理,根据数组维数的不同,将其分为一维数组和多维数组,在计算机C语言编写程序中,对数组的引用,可以为某些编程提供更为方便的环境。函数是计算机C语言的重要组成部分,在计算机C语言中每一个函数都有特定的单一功能,通过函数模块的调用将其特定的功能实现。在计算机C语言编写程序时,引入函数主要是为了将其中出现的重复代码解决以及满足编写程序的结构化和模块化等需求,根据不同的使用方法可以将函数分成不同的种类,从定义上分,可以将函数分成有返回值函数和无返回值函数,从作用上分,可以将函数分成内部函数和外部函数,从使用上分,可以将函数分为用户函数和系统函数。在计算机C语言编写程序的过程中,应用作为广泛的一种数据类型就是指针,指针是计算机C语言的精华部分,指针也是计算机C语言编写程序的一个特征。通过指针变量获取各种数据结构,将数组和字符的使用简化。计算机C语言编写程序中经常使用的一种数据类型是结构体和共用体,主要是对多个不同的数据组成的实体进行描述,其中每一个数据项就是一个实体,将这些数据项结合在一起就形成了一个特定的单元,也就是结构体。结构体和共同体可以将计算机C语言编程中的数据类型和数组类型结合成一个整体。计算机C语言编程中文件是相关数据的有序结合,从用户的角度,可以将文件分为设备文件和普通文件,从储存方式上进行分类,可以将文件分成二进制码文件和ASCII码文件,当然从文件的读写方式进行分类,可以将文件分成非缓冲文件系统和缓冲文件系统[2]。

二、计算机C语言编写程序技巧

计算机C语言最好的学习方法就是练习,也就是说要多上机,只有在计算机上运行出来的程序,才是正确的程序,否则将是不正确的C语言编写程序,学习计算机C语言编写程序的主要技巧有:

1.根据示例程序,注重示例程序。从示例开始学习计算机C语言编程,是学习新知识的开始,通过对示例的练习,逐渐形成自己的思考模式。在进行数据结构编程时,需要对相关的程序进行编写,这时对每一种数据结构都有了一定的了解,这是运用数据结构进行编程的基础,熟练的运用数据结构是对数据结构有了深刻的理解和透彻的领悟。在学习计算机C语言编程之前,通过对示例的模仿,了解编程的基本步骤,帮助进行程序的编写。

2.多练习程序编写。程序编写不能停留在对理论知识的掌握上面,需要通过实践进行锻炼和提升,想要提高计算机C语言编程能力,就需要多进行上机练习。上机可以将学生的动手操作能力提升,在实践中将学习到的理论知识进行运用,通过上机,将自己在理论知识学习中的薄弱之处进行指出,然后进行改进,实现计算机C语言编程的效果,提高实际操作动手能力。

3.在编程时,注重综合知识的运用。计算机C语言编程需要大量的运用综合知识,包括C语言的7项基本内容,同时还要执行不同的程序结构。综合知识的运用,有利于编写出优秀的计算机C语言程序,将理论知识运用到实际的编程中,将编程效果提升。

4.掌握计算机C语言基础知识。编写的计算机C语言程序,虽然可以在计算机上运行,但是,掌握住扎实的理论知识是基础,在计算机C语言编程中应该明白掌握基础知识对于对于上机的重要性,没有基础知识作为上机的前提,上机操作编程工作是没有办法进行的,所以需要掌握住扎实的理论知识[3]。

三、小结

随着信息化脚步的加快,计算机C语言在生活中得到普遍的应用,在工作有着重要的意义,在计算机C语言编写程序中,掌握相应的技巧,是学习计算机C语言编程的基础也是可靠保证,掌握住基础理论知识,和上机技术,在计算机C语言编写程序中有不可替代的作用。

参考文献:

[1]任国英.计算机C语言编辑程序技巧探讨[J].赤峰学院学报(自然科学版),2012;01

[2]秦兴.探究计算机C语言编辑程序技巧[J].信息与电脑(理论版),2012;6

第8篇:c语言函数范文

关键词:C语言; 编程; 函数; 指针

中图分类号: TP312 文献标识码: A 文章编号:

Analysis of several issues for C language beginners

WU Peng

(School of Electronic information , Yangtze University , Jingzhou, 434023, China)

Abstract: C language is the most important programming language, several problems have been summarized which should take care for beginners from four aspects such as grammar, reading programs, strengthening commissioning training, breaking through heavy difficulties, so that beginners can be accomplished with half the effort.

Keywords: C language; programming; function; pointer

1 引言

C语言是当前功能最强的编程语言之一,在信息类专业中有着举足轻重的地位。然而,在C语言学习过程中,很多人会遇到各种问题。特别是初学者,在刚开始学习时,遇到这些问题就会影响学习的兴趣。

怎样才能快速突破C语言呢?这是很多初学者经常问到的问题。笔者从多年的C语言教学中,总结出了初学者应注意的4个问题,同时也是笔者学习C语言的切身体会。如果初学者能加以重视并按要求去做,可以获得较好的效果。

2 不要花费太多的时间在语法上

语法是对某类语言规则的描述或总结,通常写得比较抽象和全面。通过对C语言语法的学习,可以比较快速地了解C语言的规则,为阅读和编写C语言程序打下良好的基础。不过,对于初学者,如果一开始就想对语法的各个方面都搞得很透彻再去编程的话,往往会搞得一头雾水,极大地削弱了学习的积极性。因此,建议初学者对于课本开始几章的语法知识,作一定程度的理解即可,不必面面俱到。如掌握一些常用的语法,能够理解课本中典型的例题即可。这样,不光使学习效率有较大提高,还让学生保持高涨的积极性,实现快速入门。

3 多阅读一些好的示例程序

用C语言解决实际问题时,通常包含很多技巧,甚至还需要相关的专业知识。这些技巧如果让初学者自己去摸索的话,将是非常耗时的,有时还不一定能想得出来。一个非常好的做法是,通过大量阅读一些好的示例程序。不仅熟悉了C语言的语法,而且从这些示例程序中,尝到了课本中没有涉及到的方法和技巧,以及要求解问题相关的专业知识。

比如,如何判断一个数为奇数或完全平方数?如何判断某年为闰年?如何通过三角形的边长求面积?如何求解方程的根?第1个问题是有关技巧的问题,而后面3个问题则是与专业相关的问题,需要了解相关的算法才能解决。因此,建议初学者多阅读一些示例程序,学习一些编程技巧,补充常见问题相关的专业知识。笔者在教学过程中,推荐学生多看一下《C语言编程经典100例》,实践证明,这种做法是非常有效果。

4 加强调试能力的训练

调试能力是编程的一项基本功,对于初学者的重要性是非常大的。通过调试,可以让我们了解C程序的执行过程,变量值的变化情况,验证程序是否按我们预先的思路来运行的,每一步工作是否正常等。另外一个重要的功能是,当程序运行的结果不正确时,可以通过调试来排除错误。掌握调试的一般方法和步骤,遵循一些调试相关的原则[1],使调试成为编程中有力的工具。

5 突破重难点:函数和指针

C语言课程中的重难点很多,笔者建议初学者重点关注函数和指针这两方面内容,因为它们实在太重要了,是我们编程的基础,有必要作深入理解。

C语言程序是由函数构成的,其中有且仅有一个主函数。程序执行时,从主函数开始执行,当主函数执行完毕,整个程序也就结束了,主函数直接或者间接调用其它函数。理解了以上几点,也就对C语言程序有了一个整体的把握。对于函数,还须重视函数的参考传递,分为值传递和地址传递两种。值传递方式只是将实参的值复制给了形参,在被调用函数中只能对形参进行操作,而不会影响到实参;地址传递是将实参的地址号传递给了形参,在被调用的函数中可以实现对实参进行修改。

另外一个非常重要的概念是“指针”。指针是C语言的灵魂,这句话说得一点也不过分。在C语言程序中,有关数据的对象,甚至代码对象(如函数),都有相应的指针。指针是地址形象的称呼[2],在编程中灵活地运用指针可以使程序实现起来更加方便。

6 总结

C语言中要注意的内容很多,以上总结的几点内容是特别要注意的,也是对初学者的建议,提醒他们在学习C语言中使用正确的方法,抓住重难点,达到事半功倍的效果。

参考文献:

[1]伍鹏.C语言调试方法探讨[J].电脑知识与技术,2006,(36):157-158.

[2]孙利辉,杜红,伍鹏.C语言指针教学难点探讨[J].电脑知识与技术,2006,(17):217-218.

[3]徐宝文,李帮清,刘杰等译.C程序设计语言[M].北京:机械工业出版社,2001.

第9篇:c语言函数范文

关键词: Fortran 90;接口块;C++;面向对象程序设计;函数重载

中图分类号:TP314 文献标识码:A 文章编号:1671-7597(2011)1210193-02

0 引言

面向对象方法更加符合人类思维习惯,在软件开发中被公认为是能够提高代码重用性和可维护性的有效方法。C++支持面向对象程序设计,其函数重载机制可以提高程序设计的可读性和灵活性,是面向对象程序设计的一个常用方法。

Fortran语言是最早诞生的高级语言,广泛应用于科学与工程计算领域。与Fortran 77相比,Fortran 90增加了模块、自定义类型、指针、接口块等新工具[1],使其具有了一些现代语言特征,但仍是面向过程的编程语言,不直接支持函数重载等面向对象程序设计[2]。

本文利用Fortran 90新提供的接口块等工具,对C++函数重载进行模拟,并通过实例进行验证。C++开发环境为Visual C++ 6.0,Fortran 90开发环境为Compaq Visual Fortran 6.6。

1 函数重载

1.1 函数重载现象

数学上求一个数的绝对值,这个数既可以是整数也可以是实数,所调用的是同一个函数。假如用C语言编写一个求绝对值的函数,由于参数的数据类型不同,需要定义两个不同名称的函数,分别对整数和实数进行求值:

Int iabs(int);float fabs(float);

尽管这两个函数都是实现求绝对值的功能,函数名称却不同,这与人们的日常思维习惯不符,给程序设计人员记忆和使用函数带来不便。针对此类问题,C++则通过函数重载来解决[3]。函数重载是指在同一作用域内,用相同的函数名对应不同的函数实现,这些不同实现的同名函数称为重载函数。例如,C++可以将求绝对值的函数定义成一组函数名相同的重载函数:

int abs(int);float abs(float);

在调用程序中,由C++编译器根据实参和形参的匹配,自动选择调用哪一个重载函数。被重载的函数须同时满足以下条件:

1)要有两个或两个以上,且在同一作用域内;

2)实现的功能必须相同,函数名必须相同;

3)至少要在参数类型、参数个数或参数顺序上有所不同,即参数表不同。

C++函数重载包括类成员函数重载和普通函数重载,二者在本质上是相同的,都是函数名相同参数表不同。故此,本文以普通函数重载为例进行说明。

值得注意的是:C/C++与Fortran同属编译型语言,其实现例程(函数和子程序统称为例程)的机制相同,Fortran有返回值的例程为函数(Function),无返回值的例程为子程序(Subroutine);C/C++中

类型的函数无返回值,其它类型的函数有返回值,分别与Fortran中的子程序和函数对应。换言之,C++中的函数重载实际包括Fortran中的函数与子程序二种例程的重载。

1.2 函数重载的实现

在C++中,以交换两个整数和两个实数为例分析函数重载的实现。

#include

void swop(int & x, int & y) // 定义重载函数,参数以引用方式传递

{ int t; t = x; x = y; y = t; }

void swop(float & x, float & y) // 定义重载函数,参数以引用方式传递

{ float t; t = x; x = y; y = t; }

void main( void ) // 主函数

{ int a = 3, b = 4; float c = 2.5, d = 6.9;

swop(a, b); cout

swop(c, d); cout

其中,用同一函数名swop分别定义了两个参数表不同,功能相同的重载函数。在主函数中,分别调用重载函数swop对整型数a、b和实型数c、d进行交换,程序运算结果为a=4;b=3与c=6.9;d=2.5,实现了正确调用。从而证明:C++编译器能够根据参数表匹配的原则,自动判断并选择调用合适的重载函数。

实质上,C++编译器在编译重载函数时,会依据参数表的不同给目标重载函数添加不同的修饰,依此来对重载函数加以区分。这样,才使得函数重载机制得以成立。

2 模拟函数重载

2.1 模拟手段-接口块

在C/C++语言程序中,通常使用头文件作为调用程序与系统库函数之间的桥梁和纽带。头文件中描述了各个系统库函数的函数名、返回值类型与参数列表等接口信息,但其本身并不包含库函数的实现代码。用户调用库函数时,由编译器按照头文件中的函数原型从相应库中提取库函数的实现代码参与运算。

Fortran 90新增加的接口块具有与C/C++头文件类似的作用,可以在调用程序中通过接口块明确被调外部例程的接口信息,如例程是函数还是子程序、例程名、函数返回值类型、参数的个数、传递方式及其数据类型等,这样,调用程序就能对外部例程产生正确调用。

假如不使用接口块,我们用Fortran 90外部例程(子程序)实现一个简单算法:

Subroutine PrintReal (x)

Implicit None ! 废除Fortran 77的隐含声明,即I-N规则

Real x

Print*, "x = ", x ! 将参数x(实型)输出到屏幕

End Subroutine

调用该外部例程的主程序为:

Program Main

Implicit None

External PrintReal ! 声明PrintReal为外部例程

Integer :: a = 1.0

Call PrintReal(a) ! 调用PrintReal外部例程

End Program

程序编译、链接都没问题,但程序运行结果为x=1.4012985E-45,显然是错误的。原因是形参x的数据类型为实型,对应实参a的数据类型却为整型,实参与形参的数据类型不匹配,从而导致调用错误。假如我们在主程序中建立被调外部例程PrintReal的接口块,来替换External PrintReal语句:

Interface

Subroutine PrintReal (x)

Real x

End Subroutine

End Interface

程序编译时就会提示错误:实参与形参的数据类型不符,这也正是我们希望看到的结果,从中也看到了在调用程序中建立被调外部例程接口块的重要性。

在外部例程接口简单的情况下,调用程序中是否建立被调外部例程的接口块是可选的;但在下列情况下必须使用接口块[4]:

1)外部例程具有可选参数;

2)外部函数返回数组或变长字符串;

3)外部例程具有假定形状数组、指针或目标参数;

4)例程做参数。

接口块的构造形式为:

Interface

接口体

End Interface

当中的接口体,类似于C/C++中的函数原型声明,只包括外部例程的接口信息。通常,接口块位于调用程序的声明区。

探索中发现,当接口块只声明一个外部例程原型时,若给接口块命名,则在调用程序中可以用接口块名代替外部例程名进行调用;当接口块中声明两个或两个以上外部例程原型时,还能否用接口块名代替外部例程名,依据参数表匹配的原则,选择调用合适的外部例程呢?如果这种设想成立,就可以用Fortran 90模拟C++函数重载。

2.2 实现模拟

上述探讨的Fortran 90接口块,主要针对的是外部例程,通过在调用程序中建立其接口块,明确其接口信息,来产生正确的调用。若将外部例程置于模块(Module),则外部例程就转化为模块例程。因此,例程重载分外部例程重载和模块例程重载二种。

2.2.1 外部例程重载

以交换两个整数和两个实数的重载为例,重载的外部例程实现分别为:

Subroutine SwopInteger (x, y)

Integer temp, x, y

temp = x; x = y; y = temp

End Subroutine

Subroutine SwopReal (x, y)

Real temp, x, y

Temp = x; x = y; y = temp

End Subroutine

在调用程序的声明区建立如下的接口块:

Interface Swop ! 建立有名接口块

Subroutine SwopInteger (x, y) ! 声明重载外部例程接口

Integer x, y

End Subroutine

Subroutine SwopReal (x, y) ! 声明重载外部例程接口

Real x, y

End Subroutine

End Interface

这样,就可以用统一的形式Call Swop(a,b)分别调用两个不同的外部例程:当实参a和b为整型时,调用的是SwopInteger外部例程;当实参a和b为实型时,则调用的是SwopReal外部例程。从而,成功地模拟了C++函数重载机制。

2.2.2 模块例程重载

将上述二个外部例程置于模块,转化为模块例程(Module procedure):

Module MyMod ! 模块程序单元

Implicit None

Contains

Subroutine SwopInteger (x, y) ! 重载的模块例程

……

Subroutine SwopReal (x, y) ! 重载的模块例程

……

End Module

由于模块的缺省访问属性为Public,所以一旦调用程序引用(Use)了模块,模块中包括模块例程在内的实体在调用程序中就是可见的,模块例程就如同调用程序的内部例程,其接口是自显的[5]。所以,建立模块例程重载的接口块可以只列出重载的模块例程:

Interface Swop ! 定义模块例程重载接口块

Module procedure SwopInteger, SwopReal

End Interface

正因为模块的缺省访问属性为Public,所以模块例程重载的接口块既可以置于模块的声明区,也可以置于引用模块的调用程序的声明区。程序运行结果表明,模块例程同样可以被重载。

3 结语

Fortran 90不支持面向对象程序设计,但具备了一些现代语言特征,本文正是利用其提供的接口块这一利器,对C++函数重载进行了成功模拟,给出了外部例程和模块例程两种重载方法,为Fortran 90的应用扩展积累了经验。

参考文献:

[1]ISO/IEC 1593-1:1991,Fortran 90[S].

[2]周振红、余明辉、张成才等,Fortran 90模拟C++主要面向对象特性[J].武汉大学学报(工学版),2006,39(2):42-46.

[3]吕凤翥,C++语言程序设计[M].北京:电子工业出版社,2006:113-114.

[4]周振红、郭恒亮、张君静等,Fortran 90/95高级程序设计[M].郑州:黄河水利出版社,2005:28-29.

[5]任慧、周振红,Fortran与C/C++共享模块中的数据和例程[J].郑州大学学报(工学版),2008,29(1):99-101.

Fortran 90 emulating C++ function overloading

JIN Kaiguan, ZHOU Zhenhong

(School of Hydraulic & Environmental Engineering,Zhengzhou University,Zhengzhou 450001,China)

Abstract: Function overloading is an important embodiment of polymorphism in C++, and a kind of common use for object-oriented programming. Fortran 90 does not support object-oriented programming, but possesses some features of modern computer languages which make it possible to emulate object-oriented programming. With the exploration of some related language elements and tools of Fortran 90, it is put forward that the function overloading mechanism can be emulated indirectly with the new powerful tool of interfaces on the basis of analyzing C++ function overloading. The examples have proved that this method is workable so as to extend the applicable areas of Fortran 90, and provide some ideas to emulate object-oriented programming.

Key words: Fortran 90;interface;C++;object-oriented programming;function overloading