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

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 

责任编辑:宏彬 


本文标签: 函数 指针 函数指针 类型 指向