①函数指针:主语是指针,即指向函数的指针。(可以参照整型指针,字符型指针等概念来理解)
②函数指针实际上是函数代码在内存中的起始地址。
③示例: int (*sub)(num1,num2);
a,int声明函数的返回值是整型
b,(*sub)通过()结合两个对象使他们具有更高的运算优先级,通知编译器这是一个指针类型的对象
c,(num1,num2)带参数说明这个对象是个函数
d,总结:该定义即是一个指向sub(num1,num2)的指针,也可称作为函数sub(num1,num2的指针)
PS:提示在声明一个指向特定类型函数的指针时,必须先声明一个该类型的函数。函数名可以用来表示函数的地址。(结合数组名,数组的指针及首元素地址理解原理相同)
①有了函数指针后,可以把适当类型的函数的地址赋值给它。请看以下示例代码:
void f1(char*);//无 返回值 入口参数是指针 的一个函数声明
void f2(char*);
int round (double);//返回整型 入口是双精度浮点型的 一个函数声明
void (*pf)(char*);//一个指针 指向一个无返回值 入口参数是char型指针 的函数
pf=f1;//合法操作 给指针赋值 赋的值为函数f1(char*)的函数名 也就是该函数的内 存地址 同时该函数的类型与指针声明是的类型(==返回值类型/入口参数类型/入口参数个数==)相同。
pf=f2;//合法
pf=round;//无效 round(double)函数的返回值类型为整型 入口参数为double 均不是pf指针声明时要求的==适当类型==。
pf=f1();//无效f1()并不是一个地址,函数的地址是函数名(不带小括号的)。
②用法1:将函数指针用作另外一个函数的参数。看起来有点绕其实很好理解:将函数指针看成一个整体假设我将它用A代替。
int f(A);//声明一个函数 返回值是int型的值 入口参数是“”函数指针型的参数
再来看一个复杂一点的:
void show(void(*fp)(char*),char*);
//一步一步来理解这个声明:void show()说明这是一个无返回值的函数
//(xxx,xxx)这个逗号说明该函数有两个入口参数
//逗号左边是void (*fp)(char*)即一个函数指针 (一个指向函数代码起始地址的指针)
//逗号右边是char*一个指向字符的指针
//至此可以完成一个功能即将一个函数指针作为其它函数的参数。
//通过这种方式可以实现对 适当类型 函数的调用。(注意是指定了函数的类型并没有指定函数名)
/*func_ptr.c--使用函数指针*/
# include
# include
# include
char showmenu(void);
void eatline(void);//
void ToUpper(char* str);
void ToLower(char* str);
void Transpose(char* str);
void Dummy(char* str);
void show(void (*fp)(char*),char *str);
int main(void)
{
char line[81]={0};
char copy[81]={0};
char choice=0;
void (*ptfn)(char*);//声明一个指针 该指针指向一个函数
//所指向的函数没有返回值 入口参数为一个指向char的指针
//请注意pfun是指针 (而不是*pfun)在赋值时请直接给pfun赋值一个函数地址(函数名)
puts("enter a string empty line to quit:");
while(gets(line)!=NULL&&line[0]!='\0')
{
while((choice=showmenu())!='n')
{
switch (choice)//请注意接下来就是通过指针调用函数
{
case 'u': ptfn=ToUpper; break;
case 'l': ptfn=ToLower; break;
case 't': ptfn=Transpose; break;
case 'o': ptfn=Dummy; break;
defulat : break;//什么都不做
}
strcpy(copy,line);
show(ptfn,copy);
}
puts("enter a string empty line to quit:");
}
puts("bye");
return 0;
}
/*=====================================
功能:将用户由键盘输入的选择字符返回
入口参数:无
返回值:用户选择的字符
========================================*/
char showmenu(void)
{
char ans;
puts("请选择您的操作:");
puts("u->up,l->low");
puts("t->tra,o->ori");
puts("n->next");
ans=getchar();
ans=tolower(ans);
eatline();
while(strchr("ultin",ans)==NULL)
{
puts("请正确输入您的选择");
ans=getchar();
ans=tolower(ans);
eatline();
}
return ans;
}
void eatline(void)
{
while(getchar()!='\n')
{
continue;
}
}
/*把接收到的字符串 由小写转换为大写*/
void ToUpper(char* str)
{
while(*str)
{
*str=toupper(*str);
str++;
}
}
/*把接收到的字符串 由大写转换为小写*/
void ToLower(char* str)
{
while(*str)
{
*str=tolower(*str);
str++;
}
}
/*把接收到的字符串 大小写切换*/
void Transpose(char* str)
{
while(*str)
{
if(islower(*str))
{
*str=toupper(*str);
}
else if(isupper(*str))
{
*str=tolower(*str);
}
str++;
}
}
/*接收到的字符串 不进行任何操作*/
void Dummy(char* str)
{
printf("不进行任何操作\n");
}
/*函数选择=================================
入口参数:1,void (*fp)(char*) 函数选择
2,char *str要操作的字符
返回值:无
=========================================*/
void show(void (*fp)(char*),char *str)
{
(*fp)(str);//通过入口参数1选择函数对入口参数2的字符串进行操作
puts(str);
}