(一) 用函数指针变量调用函数

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

 1 #include <stdio.h>
2 #include <stdlib.h>
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...这时用指针变量就比较方便了。

http://www.cnblogs.com/zxl2431/archive/2011/03/25/1995285.html

zxl2431 指向函数的指针的更多相关文章

  1. 指向函数的指针 分类: C/C++ 2015-07-13 11:03 14人阅读 评论(0) 收藏

    原文网址:http://www.cnblogs.com/zxl2431/archive/2011/03/25/1995285.html 讲的很清楚,备份记录. (一) 用函数指针变量调用函数 可以用指 ...

  2. C语言中 指向函数的指针 简介

    引子:在学习CPrimerPlus的第十四章的14.13节中,遇到了如下三行文字,是有关指向函数的指针的,把我搞晕了. char * fump(); //返回指向char的指针的函数 char (* ...

  3. 12-返回指针的函数&&指向函数的指针

    前言 接下来我只讲指针的最常见用法,比如这一章的内容----返回指针的函数 与 指向函数的指针   一.返回指针的函数 指针也是C语言中的一种数据类型,因此一个函数的返回值肯定可以是指针类型的. 返回 ...

  4. 【C语言】14-返回指针的函数与指向函数的指针

    前言 前面我们花了接近3个章节学习指针,应该都感受到指针的强大了吧.指针可以根据地址直接操作内存中的数据,使用得当的话,不仅能使代码量变少,还能优化内存管理.提升程序性能.关于指针的内容还非常多,比如 ...

  5. 指向函数的指针与iOS-Block相关知识

    指向函数的指针与iOS-Block相关知识 一. 函数指针的定义和调用: 关于函数指针的知识详细可参考:http://www.cnblogs.com/mjios/archive/2013/03/19/ ...

  6. 指向函数的指针数组(C++)

    我们能够创建一个指向函数的指针数组.为了选择一个函数,只需要使用数组的下标,然后间接引用这个指针.这种方式支持表格式驱动码的概念:可以根据状态变量去选择被执行函数,而不用条件语句或case语句.这种设 ...

  7. 【学习笔记】【C语言】指向函数的指针

    每个函数都有自己的内存地址,指针保存了函数的地址后就能指向函数了. #include <stdio.h> double haha(double d, char *s, int a) { } ...

  8. C++学习笔记:指向函数的指针

    #include <stdio.h> int sum(int a, int b) { return a+b; } int minus(int a, int b) { return a-b; ...

  9. 《C++ Primer》之指向函数的指针

    函数指针是指指向函数而非指向对象的指针.像其他指针一样,函数指针也指向某个特定的类型.函数类型由其返回类型以及形参表确定,而与函数名无关: // pf points to function retur ...

随机推荐

  1. 区分json与jsonp

    JSON(JavaScript Object Notation)和JSONP(JSON with Padding)虽然只有一个字母的差别,但其实他们根本不是一回事儿,下边简单区分概括一下: JSON是 ...

  2. (转)c运行库、c标准库、windows API的区别和联系

    C运行时库函数C运行时库函数是指C语言本身支持的一些基本函数,通常是汇编直接实现的.  API函数API函数是操作系统为方便用户设计应用程序而提供的实现特定功能的函数,API函数也是C语言的函数实现的 ...

  3. common daemon

    http://zdsyouxiang.iteye.com/blog/1940202 http://commons.apache.org/proper/commons-daemon/procrun.ht ...

  4. xcode 各种项目设置

    1:语言环境设置:项目–>PROJECT–>info–>Locailzation 2 : 手动加入项目依赖 Build Settings–>Search path–>Li ...

  5. Sass(SCSS)中文手册——入门

    简书原文 https://www.jianshu.com/p/e82c27aa05c7 前言 该中文手册是我在Sass中文文档的基础上编辑的,或者也可以理解为就是Sass中文文档的翻版.之所以有这篇文 ...

  6. 三个Bootstrap免费字体和图标库

    前言:Bootstrap 简洁.直观.强悍.移动设备优先的前端开发框架,让web开发更迅速.简单 ,深入了解 Bootstrap 底层结构的关键部分,包括我们让 web 开发变得更好.更快, 组件无数 ...

  7. Emacs常用快捷键

    基本命令 C-x C-f 打开/新建文件 C-x C-s 保存当前缓冲区 C-x C-w 当前缓冲区另存为 C-x C-v 关闭当前Buffer并打开新文件 C-x i 光标处插入文件 C-x b 切 ...

  8. vue-cli 3.x 移除console总结

    网上找了很多vue-cli 3.x的配置,很多已经不适用了,把采坑的经历记录下来,供参考. 一.使用 uglifyjs-webpack-plugin 插件 配置如下: // vue.config.js ...

  9. [Node.js] Provide req.locals data though middleware

    We can create Template Helpers, which can contains some common reuseable data and libs. /* This is a ...

  10. 用Go写了一个相似Proxy的小程序,能够用来訪问goolge个人使用还是能够的.

    package main import ( "fmt" "io" "net/http" ) func main() { http.Handl ...