1、简单的函数指针应用:
char (*pFun)(int);
char glFun(int a){ return;}
void main()
{
pFun = glFun;
(*pFun)(2);
}
第一行定义了一个 指针变量 pFun。首先我们认识到它是一个 指向某种函数的指针 ,这种函数参数是一个int型,返回值是char类型。 只有第一句我们还无法使用这个指针,因为我们还未对它进行赋值。
第二行定义了一个函数glFun()。该函数正好是一个以int为参数返回char的函数。我们要 从指针的层次上理解函数——函数的函数名实际上就是一个指针 ,函数名指向该函数的代码在内存中的首地址
然后就是main()函数了,它的第一句您应该看得懂了—— 它将函数glFun的地址赋值给变量pFun 。main()函数的第二句中“*pFun”显然是取pFun所指向地址的内容,当然也就是取出了函数glFun()的内容,然后给定参数为2。
2.使用typedef更直观更方便
typedef char (*PTRFUN)(int);
PTRFUN pFun;
char glFun(int a){ return;}
void main()
{
pFun = glFun;
(*pFun)(2);
}
typedef的功能是定义新的类型 。第一句就是定义了一种PTRFUN的类型, 并定义这种类型为指向某种函数的指针 ,这种函数以一个int为参数并返回char类型。后面就可以像使用int,char一样使用PTRFUN了。
第二行的代码便使用这个新类型定义了变量pFun,此时就可以像使用形式1一样使用这个变量了。
3、一个小例子。
#include<stdio.h>
typedef int (*pFun)(int , int);
int add(int x,int y)
{
int sk_res = x + y;
return sk_res;
}
int main(void)
{
int Res = 0;
pFun m_p_add;
m_p_add = add;
Res = m_p_add(2,4);
printf("Res = %d\n",Res);
}
四、
在学习《unix环境高级编程》信号的时候,我们会遇到一个比较复杂的函数,signal函数:
void (*signal(int signo,void (*func)(int)))(int)
单纯看这个函数还是比较容易理解的,即函数名,
*signal(int signo,void (*func)(int))
书中采用typedef来简化了函数的定义,
typedef void Sigfunc(int);
Sigfunc *signal(int,Sigfunc *) = Sigfunc *signal(int signo,Sigfunc *func)
书中采用typedef来简化了函数的定义,
typedef void Sigfunc(int);
Sigfunc *signal(int,Sigfunc *) = Sigfunc *signal(int signo,Sigfunc *func)
五、
注意
陷阱一:
记住,typedef是定义了一种类型的新别名, 不同于宏,它不是简单的字符串替换 。比如:
先定义:
typedef char* PSTR;
然后:
int mystrcmp(const PSTR, const PSTR);
const PSTR实际上相当于const char*吗?不是的,它实际上相当于char* const。
原因在于const给予了整个指针本身以常量性,也就是形成了常量指针char* const。
简单来说,记住当const和typedef一起出现时,typedef不会是简单的字符串替换就行。
陷阱二:
typedef在语法上是一个存储类的关键字 (如auto、extern、mutable、static、register等一样),虽然它并不真正影响对象的存储特性,如:
typedef static int INT2; //不可行
编译将失败,会提示“指定了一个以上的存储类”。
陷阱一:
记住,typedef是定义了一种类型的新别名, 不同于宏,它不是简单的字符串替换 。比如:
先定义:
typedef char* PSTR;
然后:
int mystrcmp(const PSTR, const PSTR);
const PSTR实际上相当于const char*吗?不是的,它实际上相当于char* const。
原因在于const给予了整个指针本身以常量性,也就是形成了常量指针char* const。
简单来说,记住当const和typedef一起出现时,typedef不会是简单的字符串替换就行。
陷阱二:
typedef在语法上是一个存储类的关键字 (如auto、extern、mutable、static、register等一样),虽然它并不真正影响对象的存储特性,如:
typedef static int INT2; //不可行
编译将失败,会提示“指定了一个以上的存储类”。