指针函数
指针函数是指带指针的函数,即本质是一个函数。
我们知道函数都有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。其定义格式如下所示:
返回类型标识符 *返回名称(形式参数表)
{ 函数体 }
返回类型可以是任何基本类型和复合类型。返回指针的函数的用途十分广泛。事实上,每一个函数,即使它不带有返回某种类型的指针,它本身都有一个入口地址,该地址相当于一个指针。比如函数返回一个整型值,实际上也相当于返回一个指针变量的值,不过这时的变量是函数本身而已,而整个函数相当于一个“变量”。例如下面一个返回指针函数的例子:
#include
float *find();
main()
{
static float score[][4]={{60,70,80,90},{56,89,34,45},{34,23,56,45}};
float *p;
int i,m;
printf("Enter the number to be found:");
scanf("%d",&m);
printf("the score of NO.%d are:/n",m);
p=find(score,m);
for(i=0;i<4;i++)
printf("%5.2f/t",*(p+i));
}
float *find(float(*pionter)[4],int n)/*定义指针函数*/
{
float *pt;
pt=*(pionter+n);
return(pt);
}
学生学号从0号算起,函数find()被定义为指针函数,起形参pointer是指针指向包含4个元素的一维数组的指针变量。pointer+1指向score的第一行。*(pointer+1)指向第一行的第0个元素。pt是一个指针变量,它指向浮点型变量。main()函数中调用find()函数,将score数组的首地址传给pointer.
【注意】
指针函数不同于函数指针, int (*f)(int a);或者char (*f1)(void);
函数指针声明为指针,它与变量指针不同之处是,它不是指向变量,而是指向函数。
函数指针有两个用途:调用函数和做函数的参数.
指向函数的指针:指向函数的指针变量
来源: 发布时间:星期四, 2008年9月25日 浏览:108次 评论:0
函数的指针是指函数的入口地址,和数组名代表数组的首地址一样,函数名代表函数的入口地址。
若有一个指针变量,存放某一个函数的入口地址,我们可以通过指向这个函数的指针变量来调用函数。
1.定义指向函数的指针变量
形式如下:
类型标识符(*变量标识符)();
类型标识符是指针变量所指向的函数类型,变量标识符是指向函数的指针变量名。
例如:
int(*p)();
定义了一个指向函数的指针变量p,它可以存放一类整型函数的入口地址,程序中把哪一个函数的入口地址赋给它,它就指向哪一个函数。
说明:
(1)定义指向函数的指针变量,可以指向一类函数。
(2)定义指向函数的指针变量时,括号不能省略。
形式int*p()定义的是指针函数头,返回值是指向整型数据的指针值,而不是指向函数的指针变量。
(3)对指向函数的指针变量p,p+i、p++、p--等运算无意义。
2.让指针变量指向函数
定义了指向函数的指针变量,就可以在指针变量与特定函数之间建立关联,让指针变量指向特定函数。
建立关联的方法为:
指针变量一函数名;
说明:
(1)指针变量只能指向定义时所指定的一类函数。
(2)一个指针变量可以先后指向多个不同的函数。
3.利用指针实现函数调用
指针变量一旦指向某函数,利用指针所指向的变量可以实现函数调用。
一般形式:
(*指针变量)(实参表);
指针变量(实参表)
///
在用C++编写程序时,经常需要在一个函数中调用其他函数,如果希望在一个函数中根据不同的参数调用不同的函数(这些函数的返回值和参数值都相同),此时就会考虑到使用函数指针。使用函数指针可以使得您的代码更加精练。
1、普通函数指针的使用:
首先让我们来看下面的一个例子:
#include <string>
#include <vector>
#include <iostream>
using namespace std;
bool IsRed( string color ) {
return ( color == "red" );
}
bool IsGreen( string color ) {
return ( color == "green" );
}
bool IsBlue( string color ) {
return ( color == "blue" );
}
void DoSomethingAboutRed() {
cout << "The complementary color of red is cyan!/n";
}
void DoSomethingAboutGreen() {
cout << "The complementary color of green is magenta!/n";
}
void DoSomethingAboutBlue() {
cout << "The complementary color of blue is yellow!/n";
}
void DoSomethingA( string color ) {
for ( int i = 0; i < 5; ++i )
{
if ( IsRed( color ) ) {
DoSomethingAboutRed();
}
else if ( IsGreen( color ) ) {
DoSomethingAboutGreen();
}
else if ( IsBlue( color) ) {
DoSomethingAboutBlue();
}
else return;
}
}
void DoSomethingB( string color ) {
if ( IsRed( color ) ) {
for ( int i = 0; i < 5; ++i ) {
DoSomethingAboutRed();
}
}
else if ( IsGreen( color ) ) {
for ( int i = 0; i < 5; ++i ) {
DoSomethingAboutGreen();
}
}
else if ( IsBlue( color) ) {
for ( int i = 0; i < 5; ++i ) {
DoSomethingAboutBlue();
}
}
else return;
}
// 使用函数指针作为参数,默认参数为&IsBlue
void DoSomethingC( void (*DoSomethingAboutColor)() = &DoSomethingAboutBlue ) {
for ( int i = 0; i < 5; ++i )
{
DoSomethingAboutColor();
}
}
void DoSomethingD( string color ) {
// define function point
// (定义函数指针,需要与DoSomethingAbout***的返回值和参数一致)
void (*DoSomethingAboutColor)();
// 根据不同的color参数为函数指针赋值
if ( IsRed( color ) ) {
DoSomethingAboutColor = &DoSomethingAboutRed; //记住这里需要用&符号
}
else if ( IsGreen( color ) ) {
DoSomethingAboutColor = &DoSomethingAboutGreen; //记住这里需要用&符号
}
else if ( IsBlue( color) ) {
DoSomethingAboutColor = &DoSomethingAboutBlue; //记住这里需要用&符号
}
else return;
for ( int i = 0; i < 5; ++i )
{
DoSomethingAboutColor();
}
}
int main( int argc, char* argv[] ) {
cout << "DoSomethingA:/n" ;
DoSomethingA( "red" );
cout << endl;
// 使用默认函数指针&DoSomethingAboutBlue
cout << "DoSomethingC with default parameter:/n" ;
DoSomethingC();
cout << endl;
cout << "DoSomethingC with &DoSomethingAboutRed:/n" ;
DoSomethingC( &DoSomethingAboutRed );
cout << endl;
cout << "DoSomethingD:/n" ;
DoSomethingD( "red" );
cout << endl;
return 0;
}
可以看到在DoSomethingA函数中,每次循环都需要判断一次color的值,这些属于重复判断;在DoSomethingB函数中,for 循环重复写了三次,代码不够精练。如果我们在这里使用函数指针,就可以只判断一次color的值,并且for 循环也只写一次,DoSomethingC给出了使用函数指针作为函数参数的代码,而DoSomethingD给出了使用string作为函数参数的代码。
2、类成员函数指针的使用
对于类的成员函数,其函数指针的定义和使用方法与上面普通函数指针还有一些差别,定义时需要在函数名之前加入类的界定符以指明该函数指针调用的函数是属于哪一个类,在调用的使用也需要在调用名称前添加(this->*)。下面举一个使用类成员函数指针的例子。
#include <string>
#include <iostream>
using namespace std;
class Color {
public:
Color( string clr ) : m_color( clr ) {
}
Color( const Color &src ) : m_color( src.m_color ) {
}
Color& operator=( const Color &src ) {
if ( this != &src ) {
m_color = src.m_color;
}
return *this;
}
~Color() {
}
bool IsRed() {
return ( m_color == "red" );
}
bool IsGreen() {
return ( m_color == "green" );
}
bool IsBlue() {
return ( m_color == "blue" );
}
void DoSomethingAboutRed() {
cout << "The complementary color of red is cyan!/n";
}
void DoSomethingAboutGreen() {
cout << "The complementary color of green is magenta!/n";
}
void DoSomethingAboutBlue() {
cout << "The complementary color of blue is yellow!/n";
}
void DoSomethingD() {
// define function point
// (定义函数指针,需要与DoSomethingAbout***的返回值和参数一致)
void (Color::*DoSomethingAboutColor)();
// 根据不同的color参数为函数指针赋值
if ( IsRed() ) {
DoSomethingAboutColor = &Color::DoSomethingAboutRed; //记住这里需要用&符号
}
else if ( IsGreen() ) {
DoSomethingAboutColor = &Color::DoSomethingAboutGreen; //记住这里需要用&符号
}
else if ( IsBlue() ) {
DoSomethingAboutColor = &Color::DoSomethingAboutBlue; //记住这里需要用&符号
}
else return;
for ( int i = 0; i < 5; ++i )
{
// 这里调用时需要使用this->*,并且需要加上括号
(this->*DoSomethingAboutColor)();
}
}
private:
string m_color;
};
int main( int argc, char* argv[] ) {
cout << "DoSomethingD of class Color:/n" ;
Color clr( "blue" );
clr.DoSomethingD();
return 0;
}