admin 管理员组文章数量: 1086019
2024年12月29日发(作者:网页创建二级目录)
维普资讯
2006年第8卷第3期
巢湖学院学报
No.3.,Vo1.8.20O6
总第78期
C.haehu College Journal Genm'al Serial No.78
C++语言中函数指针的分析与应用
汪明光
(安徽省巢湖市气象局,安徽巢湖238000)
摘 要:本文对C++语言中函数指针进行了较为系统的分析与研究,指出它与指针函数的概
念区别,并通过实例阐述使用函数指针的方法。
关键词:C++语言;函数指针;指针函数;应用
中田分类号: I l1.52 文献标识码:A文章编号:1672—2868(2006)03—0030--05
1引言
自定义类型。由于函数在内存中是具有一段连续
在C++语言中。指针与函数是两个重要的概
区域。而计算机在执行程序语句时是按照地址进
念,它们相结合产生的概念——函数指针在一般
行寻址的,因此每个函数都有一定的人口地址
C++书籍中较少涉及,而在深层编程中,灵活运用 (首地址)。函数实际上和变量表达式有一个相似
函数指针能使编程简洁、高效、灵活,且可读性
的地方,就是函数和变量的最终结果一定是放在
强。许多程序员对函数指针概念存在模糊认识,
内存中某个块。函数只不过是放在代码段中的一
导致不能正确使用,容易产生错误。本文在进一
个个标识符而已。从地址的角度来看,如果某个
步介绍函数和指针的基础上,详细地分析了函数
函数被调用。一定是代码执行到函数的入口处。
指针的概念。并与另一重要概念指针函数作了对
在C++中。函数名就是函数的人口地址。
比,指出二者的区别,文中着重介绍了函数指针 由于在C++语言中可以具有各种基本类型
、
在实际编程中的使用方法。
和用户自定义类型,因此我们也可以将函数本身
2函数和指针
作为一个变量。这样我们就可以将有关指针的概
2.1 函数
念运用于到函数上。从而得到两种类型的数据形
在C++语言中,函数在概念上对应内存中一 式:函数指针与指针函数。
段连续区域,根据C++语言关于函数的定义,其
2.2指针
一
般形式如下所示: 学习C++语言,指针是一个令人头痛的问题,
返回类型说明符-函数名(形式参数表)
稍微不注意就会使程序无法正常运行,甚至造成
f函数体}
死机,在程序设计过程中指针也往往是产生隐含
其中返回类型可以是任何基本类型和用户
bug的原因。为了正确地掌握函数指针的概念.我
收稿日期:2006一O1—14
作者简介:汪明光(1968一),男,安徽巢湖人。巢湖市气象局工程师,南京大学大气科学系o4级研究生,研究方向:数值模拟。
3O
维普资讯
们必须首先掌握指针的概念。
状是int(int,double);f2就是新定义的一个变量。
指针是存放地址值的变量或者常量。int a-
因为这两个函数形状不一样。因此它们是两
l,&a就是表示指针常量,(&表示取地址运算
个不同类型,即f1和 是不同类型的变量,这就
符,也llp ̄Jl用);而int 表示的是指针变量。正 好比int a和double b,a和b是不一样的。
确地运用指针的关键在于对变量类型和指针所
函数的返回类型和参数表中参数的个数及
指向类型的理解。
类型决定了函数的具体类型。也就是函数指针所
(1)变量类型:可以将变量名字去掉,剩下的 指向的类型。
就是变量类型。
既然把函数名看作为函数类型的一个具体
例如:int a;//变量类型为指向int的指针 变量。就可以定义指向这个变量的指针即函数指
int a://变量类型为指向int的指针
针。对于函数类型:int f(int,int),定义函数指针为
的指针
int( (int,int),注意这里一定要加上小括号,否
(2)指针所指向的类型:是指编译器将指针
则就会变成指针函数。定义了指针后,就可以对
所指向的那一片区域所看成的类型。如果指向是
指针赋值,如 =函数名。下面来看一个具体的例
整形变量,则为整形指针;若指向的是double数,
子。
则为实数指针。在实际分析时我们只需要把指针
#include<iostream>
声明语句中的指针名字和名字左边的 号去掉。
#include<string>
余下部分就是指针所指向的类型。
using namespace std;
例如:int a;//指针所指向的类型为int 。
int max(int x,int y){return y?x:y);l
C++指针比较抽象,不容易理解。使用指针千
void main0
万要明白该指针的变量类型和指针指向什么地
I
方。进一步掌握函数指针必须正确理解指针的基 int(*fp)(int,int);//定义了一个指向函数的
本概念。 指针
3函数指针的研究
int a,b,C
3.1 函数指针的概念
=max',// ̄函数max的首地址赋给函数指
函数指针(FunctionJ.ojnter)为指向函数的指
针
针。函数指针定义的一般形式为Return_Type
cin>>a>>b;//键盘输入两个整数
( Function_Pointer)(Argulist)o
c-max(a,b);//直接调用函数ma】【O
根据前面介绍函数的概念。我们知道函数和
cout<<"a-"<<a<<"
。
"<<"b="<<b<<"。"<<’’
变量都是内存中大小不等的块。从地址的观点看
ma】【="<<c<<endl;
是一回事。因此定义函数指针和定义一般变量的 c= )(a,b)// ̄过函数指针进行函数调用
指针没有什么本质区别,仅仅是这个指针指向类
cout<<"a-""<<a<<”,’’<<"b="<<b<<",’’<<"
型为函数。这里将函数作为基本元素处理。也就
max--”<<c<<endl:
是将整个函数作为一个类型。而函数名就是这个
l
类型的一个具体变量。在C++中函数意味着逻辑
fp定义为指向函数的指针变量,因此可把
上拥有首地址的内存中一个连续区域。函数名实
IIla】【O赋给 作为fp的值,即把函数maxO的入口
际上就是常量指针一函数的入口地址,但它又不
地址赋给函数指针fp,以后就可以用fp来调用该
同于普通的如int*,double*指针,它还携带参数
函数,实际上fp和max都指向相同的人口地址。
表。参数表中的参数个数及类型的差异可导致函
不同的是指针变量不象函数名称那样死,它可以
数类型的不同。
指向任何函数。如果赋予不同的值给 (不同函数
例如:int fl(int,int);一个函数类型,形状是
地址),那么调用者将调用不同地址的函数。赋值
int(int。int):fl就是新定义的一个变量。
可以发生在程序运行中。这样就能实现动态绑
int f2(int,double),一个函数类型,形
定。
31
维普资讯
3.2 函数指针和指针函数的区别
是指带指针的函数,本质是一个函数。我们知道
函数与指针相结合除了产生函数指针外,还 函数都有返回类型(如果不返回类型。则为无值
生成另外一个广泛使用的重要概念一指针函数。 型),只不过指针函数返回的是指向返回类型的
函数指针和指针函数是两个截然不同的概念,实 指针。表(一)列出了二者之间的差异:
际使用时极易混淆,产生错误。事实上指针函数
表(一)函数指针和指针函数的区别
名称 指针函数 函数指针
定义 R
eturn_Type Funtion
Name(Argulist)
Ret
F
urn_Type
_
unction
_
Pointer)(Argulist)
说明 返回类型 函数名(参数表) 返回类型( 函数指针名)(参数表)
指针指向的类型 基本类型或用户自定义类型 函数类型
数据类型 函数类型 指针类型
指向地址含义 对应内存中的某一地址 对应内存中某一连续地址
算术运算 可以进行++、一运算 不能进行算术运算
3-3 函数指针在鳊程中的应用
发生某事件时。自动呼叫某段程序代码j,Charles
函数指针(function pointer)是一种指向函数
Petzold称此为 ̄Don't Call Me.I'll Call You Jo
的指针。和一般指向变量的指针不完全相同。凡 事件驱动(event—driven)的系统经常透过函数指针
是研究过系统原代码 (例如:Linux Kernel、
来实现回调机制,例如Win32的WinProc其实
Borland OWL)的人。对于函数指针应该都不陌
就是一种回调。用来处理窗口的讯息。
生,因为多数低级系统都使用C++语言编写,而 函数指针虽然在实际编程中能够灵活、高效
函数指针是C++语言中的动态机制。有许多不可
地运用。但其本身却有致命缺点:函数指针无法
取代的地方。所以在C++原代码中到处可见函数
对参数(parameter)和返回值(return value)的
指针的使用。
型态进行检查,因为函数已经退化成指针,指针
函数指针主要有两个用途:调用函数和做函
是不带有这些型态信息的。少了型态检查,当参
数的参数。一旦函数指针被传递和纪录。它就开 数或返回值不一致时,会造成严重的错误,而编
启了许多可能性,产生很多有趣的应用,主要表
译器和虚拟机器(VM)并不会帮我们找出函数
现在以下三方面:
指针所犯的错误。
多态(polymorphism):多态的实现方式很复
3.4函数指针使用实例
杂,大致上是编译器或VM在数据结构内加入
’
函数指针提供了一些有趣、高效和优美的编
一
个变量指针,此指针通常称为vptr。是Virtual 程技巧。我们可以将函数指针代替switch/if—
Table Pointer的意思。vptr指向一个Vitrual
statements语句,或实现不能显示函数的调用(回
Table,此Vitrual Table是一个数组(array),由许 调函数的调用)。通过对函数指针的分析可以得
多函数指针组成,每个函数指针各自指向一个函
知,既然函数名能够通过函数指针加以保存。那
数的地址。
么我们也一定可以定义一个数组保存若干个函
多线程(muhithreading):将函数指针传人负
数名,这就是函数指针数组。利用函数指针,我们
责建立多线程的API中:例如Win32的 可以构成指针数组,更明确地说是构成指向函数
CreateThread(…pF…)。
的指针数组。其构建步骤如下:
回调(call—back):所谓的回调机制就是:『当
(1)typedef return_type(丰fp)(argulisO;//定义
维普资讯
一
个函数指针类型
(2)fp funO={ufnl如n2,fu3,...};//利用自定
义类型fp把 口定义为一个指向一系列函数的
指针数组,ifml,ufn2等为函数指针fp的原形函
数。
(3)fun[i]0;// ̄|用指向函数的指针数组进行
下标操作。实现函数的间接调用。
下面例子是关于浮点数的四个基本运算。它
首先是采用switch语句编程。然后又采用函数指
针进行编程。通过对两种方法编写的程序进行比
较。可以更清楚地看出巧妙运用函数指针的优
点,它可以省略很多重复工作,使得程序简洁明
了。
//一个用函数指针替换switch语句的例子
//目的:使用“1”、“2”、“3”、“4”符号完成浮
点数的四个基本运算
//定义浮点数的四个基本运算函数
n0at Plus(lfoat a,lfoat b){retum a+b;}
n0at Minus(lfoat aj1oat b){retum a-b;l
n0at Multipy(lfoat a,lfoat b){return a ;}
lfoat DivideMinus(lfoat a,lfoat b){return a/b;}
//使用swimh语句实现四个基本运算
void Switch(lfoat a,lfoat b。int opNumber)
I
n0at result;
//执行代码
siwtch(opNumber)
I
case‘1’:reslut=Plus(a,b);break;
case‘2’:reslut=Minus(a。b);break;
case‘3’:reslut=Muhiply(a,b);break;
case‘4’:reslut=Divide(a,b);break;
l
cout<<“The result is”<<result<<endl; //显
示结果
l
实际要解决的问题不仅仅涉及上述四种运
算,而是上百种运算,如果按照这种方法写下去,
那么在每一个函数里面,都必须作很多的判断,
写出的代码肯定非常长,并且每一次处理,都要
作许多次判断后才能找到正确的处理函数。代码
的执行效率也不高。针对上述问题,我们可以采
用函数指针数组的方法加以解决。
//使用函数指针完成四个基本运算
void Switch
_
Functlon
_
Pointer(n0at a ̄loat b,
int opNumber)
I
typedef flota fp)(lfoat,lfoa0;
fp fun【】={Plus,Minus,Multiply,Divide};
//定义函数指针数组。组中指针分别指向四
个基本运算函数
noat result;
//执行代码
(*fun[opNumber])();//通过函数指针数组进
行选择判断
cout<<”The result is”<<result<<endl: //显
示结果
}
可以看出使用指针函数编写程序。执行代
码段只需要一行语句。就能够完成所有运算的判
断处理。减少了编写代码的工作量。将Opn= ̄r
作为数组下标,直接调用函数指针,从代码执行
效率上看,也比case语句高。假如多个函数都要
作这样处理。函数指针更能体现出它的优势。
・
在此要强调的是指针数组元素所保存的只
是一个内存地址。一般来讲内存地址不能进行类
似(*fun[opNumber])()这样地址与括号的操作。但
函数指针是一个例外。函数指针之所以这么叫
它。就是因为它是指向函数即指向内存中代码区
的指针。它被系统授予允许与0括号操作的权利,
可以进行间接的函数词用。既然函数指针允许这
么操作。那么被定义成函数指针的数组就一定可
以进行同样的操作。正确使用函数指针数组的前
提条件是,若干个需要通过函数指针数组保存的
函数必须有相同的输入、输出值。
4总结
函数指针由于语法定义复杂,比较抽象,不
容易掌握,是学习C++语言的难点。利用函数指
针可以编写可读性强的程序。在深入系统底层编
程中会运用到大量的函数指针,因此要想成为一
名好的程序员。必须对函数指针有比较深刻地了
解。
33
维普资讯
在实际编程时我们必须注意虽然函数指针
是说同一函数指针不能指向具有不同函数形状
能够实现程序运行过程中的动态绑定,但是在编
的函数,在定义函数指针时我们很容易犯这样的
写程序时我们绝对不能将同一函数指针赋给具
错误。
有不同函数返回类型或带不同形参的函数,也就
参考文献:
[1】用靖译.C++面向对象程序设计 】.北京:清华大学出版社,2003.
【2】潘爱民.C++.net技术内幕[M】.北京:清华大学出版社,2OO4.
[3】粱肇新.鳊程高手箴言[M】.北京:电子工业出版社,2005.
[4】Charles Petrold.Programming Windows【M】.Microsoft Press,1998.
ANAI S置S AND APPLICA1[10N 0N FUNCT10N POD IIER D C++LANGUAGE
WANG Ming-guang
(Chaohu Meteorological Bureau,Chaohu Anhui 238000)
Abstract:This article give8 the relatively systematic analysis and research on function pointer in C++
language,pointing out the concept diference from pointer function,and then a instance is given out
to show the method of using function pointer.
Key words:C++;function pointer,pointer function;叩plication
责任编辑:宏彬
(上接第37页)
BAS;ED 0N BAN L0GIC ANAIIYS置S 0TWAY—REES PR0C0T0L
DENG Yong-jinag '
(1 School of Comput.nad Inf.,Hofei Univ.fo Technol,Hefei Anhui 230009)
(2 Department of Computer,Tongling College,Tongling Anhui 244OOO)
Abstract:The Otway—Rees protocol main function was completes the the bidirectional authentication。
this article discusses the formMized analysis in the design secret cipher authentication protcool;
Based on the Otway—Rees protcool,carries on the form analysis with the BAN logic to it,points out
form analysis may assist discovers protocol design flaw.
Key words:BAN logic;rule;logic reasoning;formal analysis
责任编辑:宏彬
版权声明:本文标题:C++语言中函数指针的分析与应用 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1735568822a1677024.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论