C语言自学笔记--C函数和指针

非教程

  • 1,什么是函数指针?
  • 2,使用函数指针
  • 3,实例程序(来自于C Primer Plus)

1,什么是函数指针?

①函数指针:主语是指针,即指向函数的指针。(可以参照整型指针,字符型指针等概念来理解)
②函数指针实际上是函数代码在内存中的起始地址。
③示例: int (*sub)(num1,num2);
a,int声明函数的返回值是整型
b,(*sub)通过()结合两个对象使他们具有更高的运算优先级,通知编译器这是一个指针类型的对象
c,(num1,num2)带参数说明这个对象是个函数
d,总结:该定义即是一个指向sub(num1,num2)的指针,也可称作为函数sub(num1,num2的指针)

2,使用函数指针

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*一个指向字符的指针
//至此可以完成一个功能即将一个函数指针作为其它函数的参数。
//通过这种方式可以实现对  适当类型  函数的调用。(注意是指定了函数的类型并没有指定函数名)

3,实例程序(来自于C Primer Plus)

/*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);
}

你可能感兴趣的:(C语言自学笔记,C语言包,函数指针)