函数声明 : int max(int a,int b);

函数名:平常使用的函数的名字,如max。函数名是函数名的地址,函数名相当于一个虚拟内存地址,是一个地址常量。

函数类型:除了函数名外的函数声明的其他部分int (int a,int b),函数类型包括函数的参数列表类型和返回值类型两部分。

函数地址:系统将程序可执行文件加载到内存中,函数在内存中的虚拟地址,相对于本程序地址空间的。

函数指针:与普通指针一样,只是函数指针指向的类型是函数而已,函数指针保存的值就是函数地址,因此用来接收函数名,因为函数名就是函数地址。

具体说明

    函数和变量一样,在内存中是一块内存块。
    变量名就是相应内存块的别名,就像人的名字一样。对变量取地址才能得到变量名所指代的入口内存地址。而函数名不一样,函数名就是函数代码所在的内存块的入口地址,这和数组名类似,函数名和数组名都是常量地址。
    对函数指针取值是错误的,对于一般情况是没有意义的。但是对函数指针取值得到的值与函数地址是一样的,这个还不清楚为什么,如果你知道,请不吝赐教,愿闻其详。

    而函数指针的声明是这样的: 函数返回类型 (* 函数指针名)(参数列表); 
    这和普通的函数声明类似,只是函数名处被代替为了括号括起来的函数指针声明。而*只是用来声明指针的语法,不难理解。*号外的左右括号不能省略,不然,*号就成了函数返回值类型的一部分,结果函数指针就成了普通的函数名了,那就成了正常的函数声明。比如: int (*pmax)(int a,int b);这样就声明了一个函数指针,这是声明函数指针变量,而不是定义类型。普通的变量声明是类型在前,变量名在后,而函数指针声明不一样,int (int a,int b)是函数类型,在中间的(*pmax)是变量的声明部分。而括号的作用是将*号作为说明后面的变量是指针,而不是返回值的指针类型。不加括号*号就找错了位置。总体来说,int (*)(int a,int b)是函数指针类型,pmax是函数指针变量。这种声明是一种语法规定而已。而int (*)(int a,int b)作为一个类型,像结构体struct{int a;int b;};类似,属于匿名类型,所以为了方便使用,就会使用typedef 来定义一个别名,方便使用。
使用方法:typedef int (*TMax)(int a,int b); 
    仔细观察就会发现,这和函数指针声明区别很小,就多了一个typedef,难怪开始我就看着迷糊了。稍微一想,其实就这么回事,并不复杂。因为int (*)(int a,int b)是一种类型,直接用类型定义就是变量,这是指针类型,自然是指针变量。而加了typedef则是类型其别名,因此就得到一个指针类型的新名称,而不是变量。这里很容易混淆。定义了新类型TMax后,就可以用TMax定义函数指针变量了,如TMax pmax;和普通的类型定义变量一样使用。函数指针变量接受函数名即函数地址。然后函数指针就可以当做普通函数来调用函数了,此时就把函数指针当做函数名使用。函数指针最常用的是用在回调函数里,或者是传递参数。这些使用就和普通函数使用差不多了。关键就是这些定义的理解,使用倒是简单,就不罗嗦了。如果你不清楚一些具体的细节语法,可以参看相关资料。但是要结合本文,好让自己时刻保持清晰的思路,掌握的很深刻。