百度
360搜索
搜狗搜索

函数指针的写法,函数指针如何定义?详细介绍

本文目录一览: c语言 指向返回指针的函数的指针的写法

举个例子给你看
main()
{
int* max(int,int); //此处int* max 和int *max 都行
int *(*p)(int,int);
int a,b,c;
p = max;
scanf("%d,%d",&a,&b);
c = *(*p)(a,b);
printf("a=%d,b=%d,max=%d\n",a,b,c);
getch();
}
int *max(int x,int y)
{
int z,*p;
if(x>y) z = x;
else z = y;
p=&z; //或者是*p=z;
return(p);
}
char*(*p)fun()
我定义的是一个返回 类型为char*类型也就是字符指针类型 的函数无参指针p!
你可以于此类似的定义出
int *(*p2)fun(int,int)
含有两个形参的返回值为int *类型也就是整形指针的函数指针p2
写法应为:(*fun)(int,int *)。fun首先与*结合,表示fun是指针。其次指向函数
int *func(int x,...);
int *p;
p=func(int x,...);
你的陈述不太全,缺返回的指针指向的类型。写法如下:
char *(*p)(int,int);//声明p是指向一个具有两个int型形参的函数,函数返回一个char *型指针。

指向函数的指针与指向数组的指针的声明定义的写法

指向函数的指针:int (*pFUN)();
指向数组的指针:int (*ptr)[5];
int main()
{void (*p)(int n);//声明函数指针的时候,参数的个数和类型必须和被指向的函数相同
void fun(int a);
p=fun;//指针p指向fun,fun是地址,正确
(*p)(0);//通过指针调用函数,与p();等价其中0是作为函数的参数
return 0;}
void fun(int a)
{}
这么举的例子你还能看明白?上面的例子写的是函数指针。
指向数组的指针我就不知道怎么说了,
比如int a[10] = {0}; a就可以当作指针来用。

函数指针如何定义?

关于函数指针数组的定义方法,有两种:一种是标准的方法;一种是蒙骗法。
第一种,标准方法:
分析:函数指针数组是一个其元素是函数指针的数组。那么也就是说,此数据结构是是一个数组,且其元素是一个指向函数入口地址的指针。
根据分析:首先说明是一个数组:数组名[]
其次,要说明其元素的数据类型指针:*数组名[].
再次,要明确这每一个数组元素是指向函数入口地址的指针:函数返回值类型 (*数组名[])().请注意,这里为什么要把“*数组名[]”用括号扩起来呢?因为圆括号和数组说明符的优先级是等同的,如果不用圆括号把指针数组说明表达式扩起来,根据圆括号和方括号的结合方向,那么 *数组名[]() 说明的是什么呢?是元素返回值类型为指针的函数数组。有这样的函数数祖吗?不知道。所以必须括起来,以保证数组的每一个元素是指针。
第二种,蒙骗法:
尽管函数不是变量,但它在内存中仍有其物理地址,该地址能够赋给指针变量。获取函数方法是:用不带有括号和参数的函数名得到。
函数名相当于一个指向其函数入口指针常量。 那么既然函数名是一个指针常量,那么就可以对其进行一些相应的处理,如强制类型转换。
那么我们就可以把这个地址放在一个整形指针数组中,然后作为函数指针调用即可。
(一) 用函数指针变量调用函数
可以用指针变量指向整形变量、字符串、数组、结构体、也可以指向一个函数。一个函数在编译时被分配一个入口地址。这个入口地址就称为函数指针。可以用一个指针变量指向函数,然后通过该指针变量调用此函数。用简单的数值比较为例:
1 #include

2 #include

3

4 int main()

5 {

6 int max(int,int);

7 int (*p)(int,int);

8 int a,b,c;

9 p = max;

10 scanf("%d,%d",&a,&b);

11 c = (*p)(a,b);

12 printf("a=%d,b=%d,max=%d\n",a,b,c);

13 return 0;

14 }

15

16 int max(int x,int y)

17 {

18 int z;

19 if(x>y) z = x;

20 else z = y;

21 return(z);

22 }

指针函数的定义格式

类型名 *函数名(函数参数列表);其中,后缀运算符括号“()”表示这是一个函数,其前缀运算符星号“*”表示此函数为指针型函数,其函数值为指针,即它带回来的值的类型为指针,当调用这个函数后,将得到一个“指向返回值为…的指针(地址),“类型名”表示函数返回的指针指向的类型”。“(函数参数列表)”中的括号为函数调用运算符,在调用语句中,即使函数不带参数,其参数表的一对括号也不能省略。其示例如下:int *pfun(int, int);由于“*”的优先级低于“()”的优先级,因而pfun首先和后面的“()”结合,也就意味着,pfun是一个函数。即:int *(pfun(int, int));接着再和前面的“*”结合,说明这个函数的返回值是一个指针。由于前面还有一个int,也就是说,pfun是一个返回值为整型指针的函数。返回类型可以是任何基本类型和复合类型。返回指针的函数的用途十分广泛。事实上,每一个函数,即使它不带有返回某种类型的指针,它本身都有一个入口地址,该地址相当于一个指针。比如函数返回一个整型值,实际上也相当于返回一个指针变量的值,不过这时的变量是函数本身而已,而整个函数相当于一个“变量”。例如下面一个返回指针函数的例子: #include

float *find(float(*pionter)[4],int n);//函数声明 int main(void) { 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-1); for(i=0;i<4;i++) printf(%5.2f\t,*(p+i)); return 0; }float *find(float(*pionter)[4],int n)/*定义指针函数*/ { float *pt; pt=*(pionter+n); return(pt); }共有三个学生的成绩,函数find()被定义为指针函数,其形参pointer是指针指向包含4个元素的一维数组的指针变量。pointer+n指向score的第n+1行。*(pointer+1)指向第一行的第0个元素。pt是一个指针变量,它指向浮点型变量。main()函数中调用find()函数,将score数组的首地址传给pointer.

C语言函数指针怎么用?

有函数: int fun(int a,int b);\x0d\x0a要定义指向该函数的指针\x0d\x0a对比指向 int a; 的指针\x0d\x0aint *p; p = &a;\x0d\x0ap的定义是怎么来的?\x0d\x0a首先要保证p是一个指针类型\x0d\x0a写下(*p),\x0d\x0a然后,考虑下p的基类型,\x0d\x0ap的基类型就是变量a的类型int\x0d\x0a将int 放在(*p)前面就行了\x0d\x0aint (*p); \x0d\x0a括号可以省略,就成了 int *p;\x0d\x0a\x0d\x0a同理\x0d\x0a想要实现 pf = &fun;\x0d\x0a(*pf) 将pf定义为一个指针,\x0d\x0a将fun的类型作为pf的基类型\x0d\x0afun相当于一个 int (int a,int b)类型的量\x0d\x0aint (int a,int b) (*pf);\x0d\x0a基类型中有圆括号和中括号要后移\x0d\x0aint (*pf)(int a,int b) ;//括号不能省略\x0d\x0apf = &fun;\x0d\x0a调用时\x0d\x0a(*pf)(3,4); pf(3,4)都可以

如何定义一个指向任何函数的函数指针

 (一) 用函数指针变量调用函数
  可以用指针变量指向整形变量、字符串、数组、结构体、也可以指向一个函数。一个函数在编译时被分配一个入口地址。这个入口地址就称为函数指针。可以用一个指针变量指向函数,然后通过该指针变量调用此函数。用简单的数值比较为例:
1 #include

2 #include

3

4 int main()

5 {

6 int max(int,int);

7 int (*p)(int,int);

8 int a,b,c;

9 p = max;

10 scanf("%d,%d",&a,&b);

11 c = (*p)(a,b);

12 printf("a=%d,b=%d,max=%d\n",a,b,c);

13 return 0;

14 }

15

16 int max(int x,int y)

17 {

18 int z;

19 if(x>y) z = x;

20 else z = y;

21 return(z);

22 }

  main函数中的" c = max(a,b); " 包括了一次函数的调用。每一个函数都占用一段内存单元。因此,可以用一个指针变量指向一个函数,通过指针变量来访问它指向的函数。

  第7行:int (*p)( int,int ); 用来定义 p 是一个指向函数的指针变量,该函数有两个整形参数,函数值为整形。注意 *p 两侧的括号不可省略,表示 p 先与 * 结合,是指针变量,然后再与后面的 ( ) 结合,表示此指针变量指向函数,这个函数值 (即函数的返回值) 是整形的。如果写成 int *p ( int,int ) ,由于( )的优先级高于 *,它就成了声明一个函数P( 这个函数的返回值是指向整形变量的指针)。

  赋值语句 p = max ; 作用是将函数 max 的入口地址赋给指针变量p。和数组名代表数组首元素地址类似,函数名代表该函数的入口地址。这时 p 就是指向函数 max 的指针变量,此时 p 和 max都指向函数开头,调用 *p 就是调用 max 函数。但是p作为指向函数的指针变量,它只能指向函数入口处而不可能指向函数中间的某一处指令处,因此不能用 *(p + 1)来表示指向下一条指令。

  注意:

  (1) 指向函数的指针变量的一般定义形式为:

  数据类型 (*指针变量名)(函数参数列表)

  这里数据类型就是函数返回值的类型

  (2) int (* p) ( int,int ); 它只是定义一个指向函数的指针变量 p, 它不是固定指向哪一个函数的,而只是表示定义这样一个类型的变量,它是专门用来存放函数的入口地址的。在程序中把哪一函数(该函数的值应该是整形的,且有两个整形参数)的地址赋给它,他就指向哪一个函数。在一个函数中,一个函数指针变量可以先后指向同类型的不同函数。

  (3) p = max; 在给函数指针变量赋值时,只需给出函数名而不必给出函数参数,因为是将函数的入口地址赋给 p ,而不涉及 实参和形参的结合问题,不能写成 p = max(a,b);

  (4) c = (*p)(a,b) 在函数调用时,只需将( *p ) 代替函数名即可,后面实参依旧。

  (5) 对于指向函数的指针变量,像 p++ ,p+n.....是无意义的。

  (二) 用指向函数的指针作为函数参数

  函数指针变量通常的用途之一就是把指针作为参数传递到其他函数。

  函数的参数可以是变量、指向变量的指针变量、数组名、指向数组的指针变量,也可以是指向函数的指针也可以作为参数,以实现函数地址的传递,这样就能够在被调用的函数中使用实参函数。

  void sub ( int ( *x1) (int), int (*x2) (int,int) )

    {

      int a,b,i,j;

      a = (*x1)(i);      /* 调用 f1 函数 */

      b = (*x2)(i)(j);    /* 调用 f2 函数 */

    }

  如果实参为两个 函数名 f1 和 f2. 在函数首部定义x1、x2为函数指针变量,x1指向的函数有一个整形形参,x2指向的函数有两个形参。i 和 j 是函数f1 和 f2所要的参数。函数sub的形参 x1、x2(指针变量)在函数 sub 未被调用时并不占用内存单元,也不指向任何函数。在sub被调用时,把实参函数 f1 和 f2的入口地址传给形式指针变量 x1 和 x2.

  既然在 sub 函数中要调用 f1 和 f2 函数,为什么不直接调用f1 和 f2而要用函数指针变量呢? 确实,如果只是用到f1 和 f2 函数,完全可以在sub函数中直接调用f1 和 f2,而不必设指针变量 x1 和 x2。 但是,如果在每次调用sub时,调用的函数不是固定的,下次是f3 和 f4,再是f5 和 f6...这时用指针变量就比较方便了。

阅读更多 >>>  苹果xs max屏幕失灵解决方法有哪些

C语言函数指针定义法

1、typedef int (*Fptr)(int , int );
Fptr fptr = NULL; (此处的Fptr是数据类型?)
这里的Fptr是新定义的一种数据类型,是指向 int function(int, int)这类函数的指针类型。
2、int (*Fptr)(int , int ) ;
Fptr = NULL; (此处的Fptr是函数指针变量?)
这里定义了一个函数指针变量,变量名Fptr,它是指向 int function(int, int)这类函数的指针类型。
第一个表明用Fptr代表一种数据类型,这种数据类型是函数的指针;
第二个Fptr代表一个变量,其本身是函数的指针。
1
typedef int (*Fptr)(int , int );
Fptr fptr = NULL; (此处的Fptr是数据类型?)
使用了typedef,Fptr就是数据类型,代表int (*XXX)(int , int );这一堆
如果写成Fptr fptr,意思就是int (*fptr)(int , int );了
你的理解没有错,Fptr就是返回值是int,参数是两个int的函数指针类型,fptr才是函数指针变量
2
int (*Fptr)(int , int ) ;
Fptr = NULL; (此处的Fptr是函数指针变量?)
Fptr就是一个返回值是int,参数是两个int的函数指针变量了

函数指针和指针函数的区别

定义不同,写法不同。指针函数本质是一个函数,其返回值为指针。函数指针本质是一个指针,其指向一个函数。指针函数:int*fun(intx,inty);函数指针:int(*fun)(intx,inty);可以简单粗暴的理解为,指针函数的*是属于数据类型的,而函数指针的星号是属于函数名的。再简单一点,可以这样辨别两者:函数名带括号的就是函数指针,否则就是指针函数。函数的定义:给定一个数集A,对A施加对应法则f,记作f(A),得到另一数集B,也就是B=f(A)。那么这个关系式就叫函数关系式,简称函数。函数概念含有三个要素:定义域A、值域C和对应法则f。其中核心是对应法则f,它是函数关系的本质特征。函数,最早由中国清朝数学家李善兰翻译,出于其著作《代数学》。之所以这么翻译,他给出的原因是“凡此变数中函彼变数者,则此为彼之函数”,也即函数指一个量随着另一个量的变化而变化,或者说一个量中包含另一个量。

指向函数的指针用法

指向函数的指针的用法:
1.指向函数的指针的类型
指向函数的指针应该怎样声明?拿两个字符串的比较函数来说:
int strCompare(const string & s1, const string & s2) ;
如果两个字符串相等就返回0,否则,s1< s2返回负数,s1 > s2返回正数其实函数名不是其类型的一部分,函数类型是只由它的返回类型和参数来决定。函数名称只不过是指向函数代码的地址。所以指向函数的指针的类型应该用下面的形式声名:
int (*pf)( const string &, const string & );
2.初始化和赋值
指向函数的指针可如下被初始化只有当赋值操作符左边指针的参数表和返回类型与右边函数或指针的参数表和返回类型
完全匹配时初始化和赋值才是正确的如果不匹配则将产生编译错误消息在指向函数
类型的指针之间不存在隐式类型转换。
int (*pfi)( const string &, const string & ) = strCompare;
int (*pfi2)( const string &, const string & ) = &strCompare;
指向函数的指针可以如下被赋值
pfi = strCompare;
pfi2 = pfi;
3.调用
如下代码:
#include

using namespace std;

int min( int*, int );

int (*pf)( int*, int ) = min;

const int iaSize = 5;

int ia[ iaSize ] = { 7, 4, 9, 2, 5 };

int main()

{

cout << "Direct call: min: "

<< min( ia, iaSize ) << endl;

cout << "Indirect call: min: "

<< pf( ia, iaSize ) << endl;

return 0;

}

int min( int* ia, int sz )

{

int minVal = ia[ 0 ];

for ( int ix = 1; ix < sz; ++ix )

if ( minVal > ia[ ix ] )

minVal = ia[ ix ];

return minVal;

}

4.函数指针的数组

我们可以声明一个函数指针的数组例如

int (*testCases[10])();

将testCases 声明为一个拥有10 个元素的数组每个元素都是一个指向函数的函数指针,该函数没有参数返回类型为int。

上面的声明等价于下面声明:

typedef int (*PFV)(); // 定义函数类型指针的typedef

PFV testCases[10];

函数指针的数组可以用一个初始化列表来初始化该表中每个初始值都代表了一个与数

组元素类型相同的函数例如

int lexicoCompare( const string &, const string & );

int sizeCompare( const string &, const string & );

typedef int ( *PFI2S )( const string &, const string & );

PFI2S compareFuncs[2] =

{

lexicoCompare,

sizeCompare

};

// 两个等价的调用

pfCompare[ 0 ]( string1, string2 ); // 编写

((*pfCompare)[ 0 ])( string1, string2 ); // 显式

5,参数和返回类型

函数参数的类型不能是函数类型函数类型的参数将被自动转换成该函数类型的指针

例如

// typedef 表示一个函数类型

typedef int functype( const string &, const string & );

void sort( string *, string *, functype );

编译器把sort()当作已经声明为

void sort( string *, string *,

int (*)( const string &, const string & ) );

上面这两个sort()的声明是等价的

注意除了用作参数类型之外函数指针也可以被用作函数返回值的类型例如

int (*ff( int ))( int*, int );

该声明将ff()声明为一个函数它有一个int 型的参数返回一个指向函数的指针类型



int (*) ( int*, int );

同样使用typedef 名字可以使声明更容易读懂例如下面的typedef PF 使得我们能更

容易地分解出ff()的返回类型是函数指针

typedef int (*PF)( int*, int );

PF ff( int );

函数不能声明返回一个函数类型如果是则产生编译错误例如函数ff()不能如下

声明

// typedef 表示一个函数类型

typedef int func( int*, int );

func ff( int ); // 错误: ff()的返同类型为函数类型

……恕我直言,没几处对的

不过就事论事,最重要的错误是

1void(*oper[4]);

根本与函数指针毫无关系

对于与函数指针有关的类型,建议养成用

typedef

简化声明的习惯

12typedef void sorting_function_type();sorting_function_type* oper[4];

一定不能用

typedef

的话,就要写成

1void (* oper[4])();

void

run(void

(*ptask)())

---

拆开来看

void

run(

参数)

参数

=

void

(*ptask)()

也就是

run函数接受的参数是一个函数指针ptask,

这个指针指向

无参数无返回值的函数

,也就是形如

void

fun

(void)类型的函数,在你的例子里面就是

void

task0(void)

void

task1(void)

....

(*ptask)()

,前面说了,ptask指向

函数的地址,这句话就是调用那个函数,就是执行

task0

task1等

void

(*

code

task[])()

=

{task0,task1,task2,task3};

这句话定义了一个函数指针数组

task[],初始化值为

task[0]

=

task0

等等等等

最后你要用的时候就这样

:

调用run的时候:

run(

task[0])

//执行task0

...

程序会崩溃,sa是空函数指针,你执行它相当于执行地址为0的指令。应用程序的指令空间是操作系统分配的,不允许你访问地址为0的地址。函数指针就是函数运行指令的起始地址

看完以下的,您就知道什么是指向函数的指针了,其实就是回调函数!

程序员常常需要实现回调。本文将讨论函数指针的基本原则并说明如何使用函数指针实现回调。注意这里针对的是普通的函数,不包括完全依赖于不同语法和语义规则的类成员函数(类成员指针将在另文中讨论)。

声明函数指针

回调函数是一个程序员不能显式调用的函数;通过将回调函数的地址传给调用者从而实现调用。要实现回调,必须首先定义函数指针。尽管定义的语法有点不可思议,但如果你熟悉函数声明的一般方法,便会发现函数指针的声明与函数声明非常类似。请看下面的例子:

void f();// 函数原型

上面的语句声明了一个函数,没有输入参数并返回void。那么函数指针的声明方法如下:

void (*) ();

让我们来分析一下,左边圆括弧中的星号是函数指针声明的关键。另外两个元素是函数的返回类型(void)和由边圆括弧中的入口参数(本例中参数是空)。注意本例中还没有创建指针变量-只是声明了变量类型。目前可以用这个变量类型来创建类型定义名及用sizeof表达式获得函数指针的大小:

// 获得函数指针的大小

unsigned psize = sizeof (void (*) ());

// 为函数指针声明类型定义

typedef void (*pfv) ();

pfv是一个函数指针的自定义类型,它指向的函数没有输入参数,返回类行为void。使用这个类型定义名可以隐藏复杂的函数指针语法。

指针变量应该有一个变量名:

void (*p) (); //p是指向某函数的指针

p是指向某函数的指针,该函数无输入参数,返回值的类型为void。左边圆括弧里星号后的就是指针变量名。有了指针变量便可以赋值,值的内容是署名匹配的函数名和返回类型。例如:

void func()

{

/* do something */

}

p = func;

p的赋值可以不同,但一定要是函数的地址,并且署名和返回类型相同。

传递回调函数的地址给调用者

现在可以将p传递给另一个函数(调用者)- caller(),它将调用p指向的函数,而此函数名是未知的:

void caller(void(*ptr)())

{

ptr(); /* 调用ptr指向的函数 */

}

void func();

int main()

{

p = func;

caller(p); /* 传递函数地址到调用者 */

}

如果赋了不同的值给p(不同函数地址),那么调用者将调用不同地址的函数。赋值可以发生在运行时,这样使你能实现动态绑定。

调用规范

到目前为止,我们只讨论了函数指针及回调而没有去注意ANSI C/C++的编译器规范。许多编译器有几种调用规范。如在Visual C++中,可以在函数类型前加_cdecl,_stdcall或者_pascal来表示其调用规范(默认为_cdecl)。C++ Builder也支持_fastcall调用规范。调用规范影响编译器产生的给定函数名,参数传递的顺序(从右到左或从左到右),堆栈清理责任(调用者或者被调用者)以及参数传递机制(堆栈,CPU寄存器等)。

将调用规范看成是函数类型的一部分是很重要的;不能用不兼容的调用规范将地址赋值给函数指针。例如:

// 被调用函数是以int为参数,以int为返回值

__stdcall int callee(int);

// 调用函数以函数指针为参数

void caller( __cdecl int(*ptr)(int));

// 在p中企图存储被调用函数地址的非法操作

__cdecl int(*p)(int) = callee; // 出错

指针p和callee()的类型不兼容,因为它们有不同的调用规范。因此不能将被调用者的地址赋值给指针p,尽管两者有相同的返回值和参数列。

阅读更多 >>>  mysql 存储过程 循环,mysql 使用存储过程 循环查找数据

网站数据信息

"函数指针的写法,函数指针如何定义?"浏览人数已经达到21次,如你需要查询该站的相关权重信息,可以点击进入"Chinaz数据" 查询。更多网站价值评估因素如:函数指针的写法,函数指针如何定义?的访问速度、搜索引擎收录以及索引量、用户体验等。 要评估一个站的价值,最主要还是需要根据您自身的需求,如网站IP、PV、跳出率等!