c :函数指针具体解释

在研究opencv源码的过程中。处处可见到函数指针,于是翻出来谭浩强的《C程序设计》把函数指针这一块内容再补一补!

1 定义

数据类型 (*指针变量名)(參数表);

注:

数据类型是指的函数返回值的类型;

(*指针变量名)两側的括号不能省略。表示p先与*结合,是指针变量。然后再与后面的(參数表)结合;

(參数表)能够是一个參数,也能够是多个參数,只是在引用的时候要保证形參与实參一致。

2
int (*p)(int a, int b);

表示定义一个指向函数的指针变量p,它不是固定的指向哪一个函数。而是表示定义了这样一个类型的变量。它是专门用于存放函数的入口地址的。我们都知道每个函数都占用一段内存单元,它们有一个起始地址,我们就是使用函数指针来指向函数的入口地址的。

在一个程序中,同一个函数指针变量能够指向多个函数,可是要务必保证这些函数都是同类型的不同函数。

3  赋值

在给函数指针变量赋值时,仅仅须要给出函数名,而不必给出參数,比方:

p=max。

而不能写成:

p=max(x。y);

由于是将函数入口地址赋给p,而不涉及到实參和形參的结合问题。

4 注意

和数组名代表地址数组地址首地址类似。函数名代表该函数的入口地址。

p是指向函数的指针变量,它仅仅能指向函数的入口处。而不能指向函数的中间的某条指令,因此不能用*(p+1)来表示函数的下一条指令。

同理,p++,p--或者p+n都是不正确的。

5 实例

#include <stdio.h>
int max(int x, int y);  /*函数声明   求最大值*/</span>
int min(int x, int y);  /*函数声明   求最小值*/</span>
int add(int x, int y);  /*函数声明     求和值*/</span>
void process(int i, int j, int (*p)(int a, int b)); /*函数声明 调用函数指针*/

int main()
{
    int x, y;
    cin>>x>>y;  

    cout<<"Max is: ";
    process(x, y, max);  

    cout<<"Min is: ";
    process(x, y, min);  

    cout<<"Add is: ";
    process(x, y, add);  

    getch();
    return 0;
}  

int max(int x, int y)       /*函数定义   求最大值*/
{
return x > y ? x : y;
 }
int min(int x, int y)       /*函数定义   求最小值*/
{
 return x > y ?

y : x;
}
int add(int x, int y)       /*函数定义   求和值*/
{
return x + y;
 }
void process(int i, int j, int (*p)(int a, int b))
<pre name="code" class="cpp">                           /*函数定义   调用指针*/

{

cout<<p(i, j)<<endl;

}



当输入为:

1    2

输出结果为:

max is:2

min is:1

add is:3

6 补充

以下对上述样例再做一下补充,从本例中能够看出不论调用max,min,还是add,函数process一点都没有修改,仅仅是在调用process函数时改变了实參函数名而已。这就添加了函数使用的灵活性。能够编写一个通用的函数来实现各种专用的功能。须要注意的是,对作为实參的函数,应在主调函数前(中)先函数声明。

參考内容:

《c程序设计》(第三版)谭浩强

时间: 2025-01-01 23:31:02

c :函数指针具体解释的相关文章

C语言函数、函数指针解析

函数.函数指针的理解: 函数的定义: void myfunc(void) { } 函数的声明 void myfunc(void); 函数指针的定义.初始化.赋值: 定义:void (*funcp)(void); 初始化: void (*funcp)(void) = &myfunc; 赋值 void (*funcp)(void); funcp = &myfunc; 函数调用:(*funcp)(); funcp(); 也可以这样赋值:void (*funcp)(void); funcp = m

Objective-C中,ARC下的 strong和weak指针原理解释

Objective-C中,ARC下的 strong和weak指针原理解释 提示:本文中所说的"实例变量"即是"成员变量","局部变量"即是"本地变量" 一.简介 ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain.release.autorelease语句.你不再需要担心内存管理,因为编译器为你处理了一切 注意:ARC 是编译器特性,而不是 iOS 运行时特性(除

函数指针和回调函数

函数指针 函数指针是指向函数调用地址的指针.它和函数名究竟有什么关系呢?且看下文. 且看一小程序 首先,先请看下边程序: 1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 void func(string s) 6 { 7 cout << s << endl; 8 } 9 10 void (*pFunc)(string s); // 不能够写成 void *pFunc(s

大话 函数指针 和 枚举这对鸳鸯

一:起因 (1)函数指针是指向函数的指针变量,即本质是一个指针变量,是一个指向函数(可能是代码区)的首地址的指针,正如我们都知道,数组名就是指向数组第一个元素的常量指针,对于一个函数而言,函数名也是指向函数第一条指令的常量指针.大话 回调函数 和 枚举 (2)而回调函数就是C语言里面对函数指针的高级应用,回调函数是一个通过函数指针调用的函数.如果你把函数指针(函数的入口地址)传递给另一个函数,当这个函数指针被用来调用它所指向的函数时,我们就说这个函数是回调函数. 大话 函数指针 和 指针函数 (

为什么 C++ 中成员函数指针是 16 字节?

当我们讨论指针时,通常假设它是一种可以用 void * 指针来表示的东西,在 x86_64 平台下是 8 个字节大小.例如,下面是来自 维基百科中关于 x86_64 的文章 的摘录: Pushes and pops on the stack are always in 8-byte strides, and pointers are 8 bytes wide. 从 CPU 的角度来看,指针无非就是内存的地址,所有的内存地址在 x86_64 平台下都是由 64 位来表示,所以假设它是 8 个字节是

由typedef和函数指针引起的危机

由typedef和函数指针引起的危机 昨天阅读了大神强哥的代码,发现里面用到了函数指针,也用到的typedef.本来我自以为对这两个概念有一定的认识,但是突然发现这两个东西居然用到了一起!!!!(在一起了也不说一声,一点心理准备都没有): typedef int (* fp)(void *para, void *end); 瞬间就蒙了,这是个啥东西???于是我开始看书,上网查资料,想弄明白.在这个过程中,我发现自己不仅仅是对这两个概念理解不够!!!而是,对数组.指针.变量的理解都不够.这引发了我

C++成员函数指针的应用

 C++中,成员指针是最为复杂的语法结构.但在事件驱动和多线程应用中被广泛用于调用回叫函数.在多线程应用中,每个线程都通过指向成员函数的指针来调用该函数.在这样的应用中,如果不用成员指针,编程是非常困难的.  刚遇到这种语法时也许会让你止步不前.但你会发现,使用恰当的类型定义之后,复杂的语法是可以简化的.本文引导你了解成员函数指针的声明,赋值和调用回叫函数.  成员函数指针的声明  一个成员函数指针包括成员函数的返回类型,后随::操作符类名,指针名和函数的参数.初看上去,语法有点复杂.其实可以把

彻底搞定C指针-函数名与函数指针【转】

转自:http://blog.csdn.net/a1232345/article/details/43524371 函数名与函数指针 一 通常的函数调用    一个通常的函数调用的例子://自行包含头文件void MyFun(int x);    //此处的申明也可写成:void MyFun( int ); int main(int argc, char* argv[]){   MyFun(10);     //这里是调用MyFun(10);函数 return 0;} void MyFun(in

【C语言】函数指针与回调函数

在C语言中:指针是C语言的特色,有着各种各样的指针,普通的变量指针,常量指针,数组指针,指针数组,函数指针,指针函数.我们就讲一下函数指针与回调函数吧 首先关于函数指针,其实很简单. 对于一个函数指针来说,顾名思义,就是一个指向函数的指针,需要知道的是,对于指针而言,他总是存储一块地址,地址里面有着一个,一组,或者一块数据,在函数中,函数的存储是放在代码段的,每个函数都有着一个函数首地址,调用了这个地址相当于调用的这个函数. 具体的可以观看我的这篇博客,其中就通过在内存阶段改变栈帧返回值,成功的