指向函数的指针
c/c++ 2010-11-20 13:17:02 阅读41 评论0 字号:大中小订阅首先看这个程序:
#include
using namespace std;
void max(int a, int b)
{
cout<<"now call max("< int t = a>b?a:b; cout< } void min(int a, int b) { cout<<"now call min("< int t = a cout< } typedef void (*myFun)(int a, int b); //定义一个函数指针用来引用max,min //回调函数 void callback(myFun fun, int a, int b) { fun(a,b); } void main() { int i = 10; int j = 55; callback(max,i,j); callback(min,i,j); } 编译结果: now call max(10,55)... 55 now call min(10,55)... 10 Press any key to continue 回调函数是一种例子。 我曾经写过一个命令行程序,有很多命令,于是构着了一个结构的数组,大概是这样 struct{ char *cmd_name; bool (*cmd_fun)(); }cmd_info_list[MAX_CMD_NUM]; 程序中得到一个用户输入的命令字符串后,就匹配这个数组,找到对应的处理函数。 以后每次添加一个命令,只需要加个函数,然后在这个数组中加一个记录就可以了,不需要修改太多的代码。 这可以算是一种用法吧。呵呵。 Windows 中,窗口的回调函数就用到了函数指针。 用VC向导 New Projects ----> Win32 Application ----> A typical "Hello World!" application 其中的WndProc 是WNDPROC 类型的函数typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM); WndProc 作为窗口的回调函数,用来填充WNDCLASSEX 结构。 WNDCLASSEX wcex; wcex.lpfnWndProc = (WNDPROC)WndProc; void ListTraverse(LinkList L,void (*visit)(int)) { Link p; p=L->next; while(p) { visit(p->data); p=p->next; } return OK; } void print(int c) { printf("%d",c); } ListTraverse(L,print); 这算是个例子吧??? #include #include #include double Add (double x, double y) { return x+y; } double Sub (double x, double y) { return x-y; } double Mul (double x, double y) { return x*y; } double Div (double x, double y) { return x/y; } /*5个“函数指针”的数组*/ double (*funcTable[5])( double, double ) ={ Add, Sub, Mul, Div, pow }; char *msgTable[5] = { "Sum", "Difference", "Product", "Quotient", "Power" }; int main() { int i; double x=12.5, y=4; printf("Input 2 operands for some arithmetic:\n"); if(scanf("%lf %lf",&x,&y)!=2) { printf("Invalid input.\n"); } for (i=0; i<5; ++i) { printf( "%10s: %6.2f\n", msgTable[i], funcTable[i](x,y) ); } return 0; } 参考资料:C in a nutshell. (美)Peter Prinz & (美)Tony Crawford ************************************************************************************************************ https://www.wendangku.net/doc/2e12051238.html,/parad1se/blog/item/f11ee9314df97c11eac4aff7.html 代码简化, 促进跨平台开发的目的. typedef 行为有点像#define 宏,用其实际类型替代同义字。 不同点:typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换。 用法一: typedef int (*MYFUN)(int, int); 这种用法一般用在给函数定义别名的时候 上面的例子定义MYFUN 是一个函数指针, 函数类型是带两个int 参数, 返回一个int 在分析这种形式的定义的时候可以用下面的方法: 先去掉typedef 和别名, 剩下的就是原变量的类型. 去掉typedef和MYFUN以后就剩: int (*)(int, int) 用法二: typedef给变量类型定义一个别名. typedef struct{ int a; int b; }MY_TYPE; 这里把一个未命名结构直接取了一个叫MY_TYPE的别名, 这样如果你想定义结构的实例的时候就可以这样: MY_TYPE tmp; 第二种用法:typedef 原变量类型别名 typedef补充内容: 例如: typedef int (*PF) (const char *, const char *); 这个声明引入了PF 类型作为函数指针的同义字,该函数有两个const char * 类型的参数以及一个int 类型的返回值。 简单的函数指针的用法 //形式1:返回类型(*函数名)(参数表) char(*pFun)(int); char glFun(int a){return;} void main() { pFun =glFun; (*pFun)(2); } 第一行定义了一个指针变量pFun.它是一个指向某种函数的指针,这种函数参数是一个int类型,返回值是char类型。只有第一句我们还无法使用这个指针,因为我们还未对它进行赋值。 第二行定义了一个函数glFun().该函数正好是一个以int为参数返回char的函数。我们要从指针的层次上理解函数-函数的函数名实际上就是一个指针,函数名指向该函数的代码在内存中的首地址。 使用typedef更直接 typedef char(*PTRFUN)(int) PTRFUN pFun; char glFun(int a){return;} void main() { pFun = glFun; (*pFun)(2); } typedef的功能是定义新的类型。第一句就是定义了一种PTRFUN的类型,并定义这种类型为指向某种函数的指针,这种函数以一个int 为参数并返回char类型。 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 下面是个例子: ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 在typedef的使用中,最麻烦的是指向函数的指针,如果没有下面的函数,你知道下面这个表达式的定义以及如何使用它吗? int (*s_calc_func(char op))(int, int); 如果不知道,请看下面的程序,里面有比较详细的说明 // 定义四个函数 int add(int, int); int sub(int, int); int mul(int, int); int div(int, int); // 定义指向这类函数的指针 typedef int (*FP_CALC)(int, int); // 我先不介绍,大家能看懂下一行的内容吗? int (*s_calc_func(char op))(int, int); // 下一行的内容与上一行完全相同, // 定义一个函数calc_func,它根据操作字符op 返回指向相应的计算函数的指针 FP_CALC calc_func(char op); // 根据op 返回相应的计算结果值 int calc(int a, int b, char op); int add(int a, int b) { return a + b; } int sub(int a, int b) { return a - b; } int mul(int a, int b) { return a * b; } int div(int a, int b) { return b? a/b : -1; } // 这个函数的用途与下一个函数作业和调用方式的完全相同, // 参数为op,而不是最后的两个整形 int (*s_calc_func(char op)) (int, int) { return calc_func(op); } FP_CALC calc_func(char op) { switch (op) { case '+': return add; case '-': return sub; case '*': return mul; case '/': return div; default: return NULL; } return NULL; } int calc(int a, int b, char op) { FP_CALC fp = calc_func(op); // 下面是类似的直接定义指向函数指针变量 // 下面这行是不用typedef,来实现指向函数的指针的例子,麻烦! int (*s_fp)(int, int) = s_calc_func(op); // ASSERT(fp == s_fp); // 可以断言这俩是相等的 if (fp) return fp(a, b); else return -1; } void test_fun() { int a = 100, b = 20; printf("calc(%d, %d, %c) = %d\n", a, b, '+', calc(a, b, '+')); printf("calc(%d, %d, %c) = %d\n", a, b, '-', calc(a, b, '-')); printf("calc(%d, %d, %c) = %d\n", a, b, '*', calc(a, b, '*')); printf("calc(%d, %d, %c) = %d\n", a, b, '/', calc(a, b, '/')); } 运行结果 calc(100, 20, +) = 120 calc(100, 20, -) = 80 calc(100, 20, *) = 2000 calc(100, 20, /) = 5 方法 指针函数和函数指针的区别 关于函数指针数组的定义 为函数指针数组赋值 函数指针的声明方法为: 数据类型标志符 (指针变量名) (形参列表); 注1:“函数类型”说明函数的返回类型,由于“()”的优先级高于“*”,所以指针变量名外的括号必不可少,后面的“形参列表”表示指针变量指向的函数所带的参数列表。例如: int func(int x); /* 声明一个函数 */ int (*f) (int x); /* 声明一个函数指针 */ f=func; /* 将func函数的首地址赋给指针f */ 赋值时函数func不带括号,也不带参数,由于func代表函数的首地址,因此经过赋值以后,指针f就指向函数func(x)的代码的首地址。 注2:函数括号中的形参可有可无,视情况而定。 下面的程序说明了函数指针调用函数的方法: 例一、 #include C++指针函数习题 一、选择题 1.以下程序的运行结果是()。 sub(int x, int y, int *z) { *z=y-x; } void main() { int a,b; sub(10,5,&a); sub(7,a,&b); cout< #include<> 用名作为其他变量名地别名. ; 等价于; ()声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名地一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元.故:对引用求地址,就是对目标变量求地址.与相等. ()不能建立数组地引用.因为数组是一个由若干个元素所组成地集合,所以无法建立一个数组地别名. 引用应用 、引用作为参数 引用地一个重要作用就是作为函数地参数.以前地语言中函数参数传递是值传递,如果有大块数据作为参数传递地时候,采用地方案往往是指针,因为这样可以避免将整块数据全部压栈,可以提高程序地效率.但是现在(中)又增加了一种同样有效率地选择(在某些特殊情况下又是必须地选择),就是引用. 【例】: ( , ) 此处函数地形参, 都是引用 { ; ; ; ; } 为在程序中调用该函数,则相应地主调函数地调用点处,直接以变量作为实参进行调用即可,而不需要实参变量有任何地特殊要求.如:对应上面定义地函数,相应地主调函数可写为: ( ) { ; >>>>; 输入两变量地值 (); 直接以变量和作为实参调用函数 <<<< ' ' <<; 输出结果 } 上述程序运行时,如果输入数据并回车后,则输出结果为. 由【例】可看出: ()传递引用给函数与传递指针地效果是一样地.这时,被调函数地形参就成为原来主调函数中地实参变量或对象地一个别名来使用,所以在被调函数中对形参变量地操作就是对其相应地目标对象(在主调函数中)地操作. ()使用引用传递函数地参数,在内存中并没有产生实参地副本,它是直接对实参操作;而使用一般变量传递函数地参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量地副本;如果传递地是对象,还将调用拷贝构造函数.因此,当参数传递地数据较大时,用引用比用一般变量传递参数地效率和所占空间都好. ()使用指针作为函数地参数虽然也能达到与使用引用地效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用"*指针变量名"地形式进行运算,这很容易产生错误且程序地阅读性较差;另一方面,在主调函数地调用点处,必须用变量地地址作为实参.而引用更容易使用,更清晰. 如果既要利用引用提高程序地效率,又要保护传递给函数地数据不在函数中被改变,就应使用常引用. 、常引用 常引用声明方式:类型标识符引用名目标变量名; 用这种方式声明地引用,不能通过引用对目标变量地值进行修改,从而使引用地目标成为,达到了引用地安全性. 【例】: ; ; ; 错误 ; 正确 这不光是让代码更健壮,也有些其它方面地需要. 【例】:假设有如下函数声明: 指向函数的指针 函数指针是指指向函数而非指向对象的指针。像其他指针一样,函数指针也指向某个特定的类型。函数类型由其返回类型以及形参表确定,而与函数名无关: bool (*pf)(const string &,const string &); 这个语句将pf声明为指向函数的指针,它所指向的函数带有两个const string &类型的形参和bool 类型的返回值。 注意:*pf两侧的括号是必需的。 1.typedef简化函数指针的定义: 函数指针类型相当地冗长。使用typedef为指针类型定义同义词,可将函数指针的使用大大简化: Typedef bool (*cmpfn)(const string &,const string &); 该定义表示cmpfn是一种指向函数的指针类型的名字。该指针类型为“指向返回bool类型并带有两个const string 引用形参的函数的指针”。在要使用这种函数指针类型时,只需直接使用cmpfcn即可,不必每次都把整个类型声明全部写出来。 2.指向函数的指针的初始化和赋值 在引用函数名但又没有调用该函数时,函数名将被自动解释为指向函数的指针。假设有函数: Bool lengthcompare(const string &,const string &); 除了用作函数调用的左操作数以外,对lengthcompare的任何使用都被解释为如下类型的指针: bool (*)(const string &,const string &); 可使用函数名对函数指针初始化或赋值: cmpfn pf1=0; cmpfn pf2=lengthcompare; pf1=legnthcompare; pf2=pf1; 此时,直接引用函数名等效于在函数名上应用取地址操作符: cmpfcn pf1=lengthcompare; cmpfcn pf2=lengthcompare; 注意:函数指针只能通过同类型的函数或函数指针或0值常量表达式进行初始化或赋值。 将函数指针初始化为0,表示该指针不指向任何函数。 指向不两只函数类型的指针之间不存在转换: string::size_type sumLength(const string &,const string &); bool cstringCompare(char *,char *); //pointer to function returning bool taking two const string& cmpFcn pf;//error:return type differs pf=cstringCompare;//error:parameter types differ pf=lengthCompare;//ok:function and pointer types match exactly 3.通过指针调用函数 指向函数的指针可用于调用它所指向的函数。可以不需要使用解引用 指针函数与函数指针的区别 一、 在学习arm过程中发现这“指针函数”与“函数指针”容易搞错,所以今天,我自己想一次把它搞清楚,找了一些资料,首先它们之间的定义: 1、指针函数是指带指针的函数,即本质是一个函数。函数返回类型是某一类型的指针 类型标识符 *函数名(参数表) int *f(x,y); 首先它是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针变量。 表示: float *fun(); float *p; p = fun(a); 注意指针函数与函数指针表示方法的不同,千万不要混淆。最简单的辨别方式就是看函数名前面的指针*号有没有被括号()包含,如果被包含就是函数指针,反之则是指针函数。来讲详细一些吧!请看下面 指针函数: 当一个函数声明其返回值为一个指针时,实际上就是返回一个地址给调用函数,以用于需要指针或地址的表达式中。 格式: 类型说明符* 函数名(参数) 当然了,由于返回的是一个地址,所以类型说明符一般都是int。 例如:int *GetDate(); int * aaa(int,int); 函数返回的是一个地址值,经常使用在返回数组的某一元素地址上。 int * GetDate(int wk,int dy); main() { int wk,dy; do { printf(Enter week(1-5)day(1-7)\n); scanf(%d%d,&wk,&dy); } while(wk<1||wk>5||dy<1||dy>7); printf(%d\n,*GetDate(wk,dy));函数指针
C指针函数习题
指针变量作为函数参数
指向函数的指针详解
指针函数与函数指针的区别
指向函数的指针