函数指针数组如何接收参数

函数指针数组如何接收参数,第1张

void (array[10])(void)

array[10]--->就是函数指针数组

将对应的函数名赋值给数组就可以了

比如这么个函数

int fun(int a)

array[0] = fun;

就这样就可以了。

你试试吧

首先我们定义一个类Ctest,类里面包含三个不同形式的成员函数,静态成员函数statFunc()、动态成员函数dynFunc()和虚拟函数virtFunc()。在main函数中我们利用cout标准输出流分别输出这三个函数的地址,程序如下所示:

#include <iostream>

#include <stdioh>

using namespace std;

class Ctest

{

public:

static void statFunc()

{ cout << "statFunc" << endl; }

void dynFunc()

{ cout << "dynFunc" << endl; }

virtual void virtFunc()

{ cout << "virtFunc" << endl; }

};

void main()

{

cout << "address of Ctest::statFunc:" << &Ctest::statFunc << endl;

cout << "address of Ctest::dynFunc :" << &Ctest::dynFunc << endl;

cout << "address of Ctest::virtFunc:" << &Ctest::virtFunc << endl;

while(1);

}

首先 函数指针是指向一组同类型的函数的指针;而类成员函数我们也可以相似的认为,它是指向同类中同一组类型的成员函数的指针,当然这里的成员函数更准确的讲应该是指非静态的成员函数。前者是直接指向函数地址的,而后者我们从字面上也可以知道 它肯定是跟类和对象有着关系的。

函数指针实例:

代码如下:

typedef int (p)(int,int);//定义一个接受两个int型且返回int型变量的函数指针类型

int func(int x,int y)

{

printf("func:x=%d,y=%d/n",x,y);

return (x<yx:y);

}

int main()

{

p fun=func;//定义函数指针并给它赋上一个函数指针

cout<<"min:"<<(fun)(4,5)<<endl;//为什么fun需要用()扩起来呢因为的运算符优先级比()低,如果不用()就成了(fun())

return 0;

}

而“指向类成员函数的指针”却多了一个类的区别:

class A

{

public:

int func(int x,int y)

{

printf("A::func:x=%d,y=%d/n",x,y);

return (x<yx:y);

}

};

typedef int (A::p)(int,int);//指针名前一定要加上所属类型类名 A::的限定

int main()

{

p fun=&A::func;

A a; //因为成员函数地址的解引用必须要附驻与某个对象的地址,所以我们必须创建某个对象。

cout<<"min:"<<(afun)(4,5)<<endl;

return 0;

}

嘿嘿。。只是用起来 感觉怪怪滴。

接下来 我们可以再扩展一下下:

代码如下:

#include <tcharh>

#include <iostream>

#include <stdioh>

using namespace std;

class A

{

public:

int func1(int x,int y)

{

printf("A::func:x=%d,y=%d/n",x,y);

return (x<yx:y);

}

virtual int func2(int x,int y)

{

printf("A::func:x=%d,y=%d/n",x,y);

return (x>yx:y);

}

};

class B:public A

{

public:

virtual int func2(int x,int y)

{

printf("B::func:x=%d,y=%d/n",x,y);

return (x+y);

}

};

typedef int (A::p)(int,int);//指针名前一定要加上所属类型类名 A::的限定

typedef int (B::p0)(int,int);

int main()

{

A a; //因为成员函数地址的解引用必须要附驻与某个对象的地址,所以我们必须创建某个对象。

p fun=&A::func1;

cout<<(afun)(4,5)<<endl;

cout<<(bfun)(4,5)<<endl<<endl;

fun=&A::func2;

cout<<(afun)(4,5)<<endl;//请注意这里调用的是虚函数,嘿嘿 还真神奇 类成员函数指针也支持多态。

cout<<(bfun)(4,5)<<endl<<endl;

//fun=&B::func2; //这样式错误滴,因为不存在派生类的"指向类成员函数的指针"到基类的"指向类成员函数的指针"的隐式转换

fun=(int (A::)(int,int))&B::func2;//应该进行强制转换

cout<<(afun)(4,5)<<endl;

cout<<(bfun)(4,5)<<endl<<endl;

p0 fun0=&B::func2;

cout<<(afun)(4,5)<<endl;

cout<<(bfun)(4,5)<<endl<<endl;

fun0=&A::func2; //正确,因为这里进行了隐式转换

cout<<(afun)(4,5)<<endl;

cout<<(bfun)(4,5)<<endl<<endl;

//从上面我们不难发现 指向类成员函数的指针基类和派生类的关系和指向类对象的指针基类和派生类的关系完全相反,

//基类成员函数的布局被认为是派生类成员函数布局的一个子集

return 0;

}

接下 是有关模板类的类成员函数指针的使用

实例如下:

代码如下:

#include <tcharh>

#include <iostream>

#include <stdioh>

using namespace std;

class A

{

public:

int func(int x,int y)

{

printf("A::func : x=%d,y=%d/n",x,y);

return (x<yx:y);

}

};

class B

{

public:

int func(int x,int y)

{

printf("B::func : x=%d,y=%d/n",x,y);

return (x>yx:y);

}

};

template<class T>

class C

{

public:

T c;

void Print()

{

int (T::p)(int,int)=&T::func;

(cp)(4,5);

}

};

int main()

{

C<A> ca;

C<B> cb;

caPrint();

cbPrint();

return 0;

}

从上面 可以很清晰地看到。。其实它和普通的模板没有什么区别。。只不过将限定名称该为参数名酒OK啦。。。

函数的指针可以作为一个参数传递给另外一个函数,这一点非常有意思。一个函数用函数指针作参数,意味着这个函数的一部分工作需要通过函数指针调用另外的函数来完成,这被称为“回调(callback)”。处理图形用户接口的许多C库函数都用函数指针作参数,因为创建显示风格的工作可以由这些函数本身完成,但确定显示内容的工作需要由应用程序完成。

举一个简单的例子,假设有一个由字符指针组成的数组,你想按这些指针指向的字符串的值对这些指针进行排序,你可以使用qsort()函数,而qsort()函数需要借助函数指针来完成这项任务(关于排序的详细介绍请参见第3章“排序和查找”。qsort()函数有4个参数:

(1) 指向数组开头的指针;

(2) 数组中的元素数目;

(3) 数组中每个元素的大小;

(4) 指向一个比较函数的指针。

qsort()函数返回一个整型值。

比较函数有两个参数,分别为指向要比较的两个元素的指针。当要比较的第一个元素大于、等于或小于第二个元素时,比较函数分别返回一个大于o,等于。或小于。的值。

排序算法和交换算法都是qsort()函数的部分内容。qsort()函数的交换算法代码只负责拷贝指定数目的字节(可能调用memcpy()或memmove()函数),因此qsort()函数不知道要对什么样的数据进行排序,也就不知道如何比较这些数据。比较数据的工作将由函数指针所指向的比较函数来完成。

对本例来说,不能直接用strcmp()函数作比较函数,其原因有两点:第一,strcmp()函数的类型与本例不符(见下文中的介绍);第二,srtcmp()函数不能直接对本例起作用。strcmp()函数的两个参数都是字符指针,它们都被strcmp()函数看作是字符串中的第一个字符;本例要处理的是字符指针(char s),因此比较函数的两个参数必须都是指向字符指针的指针。

为什么不能直接将strcmp()函数传递给qsort()函数呢为什么strpcmp()函数中的参数是如此一种形式呢因为函数指针的类型是由它所指向的函数的返回值类型及其参数的数目和类型共同决定的,而qsort()函数要求比较函数含两个const void 类型的参数:

qsort()函数不知道要对什么样的数据进行排序,因此,base参数和比较函数中的两个参数都是void指针。这一点很容易理解,因为任何指针都能被转换成void指针,并且不需要强制转换。但是,qsort()函数对函数指针参数的类型要求就苛刻一些了。本例要排序的是一个字符指针数组,尽管strcmp()函数的比较算法与此相符,但其参数的类型与此不符,所以在本例中strcmp()函数不能直接被传给qsort()函数。在这种情况下,最简单和最安全的方法是将一个参数类型符合qsort()函数的要求的比较函数传给qsort()函数,而将比较函数的参数强制转换成strcmp()函数所要求的类型后再传给strcmp()函数;strpcmp()函数的作用正是如此。

不管是强制转换strpcmp()函数的参数的类型,还是强制转换指向strcmp()函数的指针的类型,你都必须小心进行,因为稍有疏忽,就会使程序出错。在实际编程中,转换函数指针的类型更容易使程序出错。

运行时的意思是指你程序编译后成可执行文件运行时的话 这个时候你的程序已经变成二进制代码,已经早就丢失了什么类、成员函数之类的。

除非通过在编译前IDE或编译器自动分析你的代码,把类结构什么的提前分析出来。 运行时再把你要调试的类的内存位置和内存的具体内容代入到你的结构里,就能实现你想要的功能

你这个功能,做好用c++实现,因为c#是托管代码,给不出rcvdata

rcvaddr这个函数指针来给c++调用。

也就是说,你得写个c++的dll实现该功能,然后用c#加载你自己的c++

dll。

怎么调用dll方法网上有,不贴了。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/12156558.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存