C 指针&&函数
Posted _NiuLi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C 指针&&函数相关的知识,希望对你有一定的参考价值。
一、函数指针
顾名思义,函数指针,首先它是一个指针,因为可以指向函数,所以称为函数指针。可以与数组指针类比。
与定义数组指针类似,函数指针的定义如下:
函数返回值类型(*变量名)(函数参数类型)
如 void (*pfun)(int) //函数指针pfun指向的函数的类型是 void (int)
来判断下面的代码是什么意思
(1)、char * (*fun1)(char * p1, char * p2);
(2)、char * *fun2(char * p1, char * p2);
(3)、char * fun3(char * p1, char * p2);
上述代码只要考虑优先级,我们就很容易判断出来。
解:
(1)、*先与fun1结合,所以fun1是一个指针,去掉(*fun1),就是fun1可以指向的类型,所以fun1是一个函数指针。可以指向的函数的类型为char*(char* p1,char* p2)。故第(1)行语句是定义一个函数指针。
(2)、()的优先级高于*故fun2先与()结合,所以fun2是一个函数,函数的返回值类型是char**,参数数是(char*p1,char*p2),所以这是一个函数的声明。
(3)、同(2)一样fun3是一个函数,这一一个函数的声明。
那么,函数指针有什么用呢?函数指针与普通指针一样解引用就可一访问到指向的对象。解引用函数指针就可以调用函数。
#include <stdio.h>
int add(int a,int b)
return a+b;
int main()
int(*padd)(int,int)=&add;//定义函数指针padd指向add()
int ret=0;
//ret=add(2,3);
ret=(*padd)(2,3);
printf("%d\\n",ret);
return 0;
二、函数指针数组
顾名思义,函数指针数组,首先是一个数组,因为数组元素是函数指针,所以称为函数指针数组。
1、函数指针数组的定义
该如何定义一个函数指针数组呢?
我们先来看一下普通数组和指针数组是如何定义的。
char arr1[3]; //字符数组
char *arr2[3]; //指针数组
同理,char (*arr[3]) (char*); //函数指针数组
其实很好理解,[]优先级高于*,arr先与[3]结合,所以arr是一个数组,大小为3;去掉arr[3],就是数组元素的类型,char(*)(char*)这是一个函数指针类型。故arr是一个函数指针数组大小为3.
2、数组的初始化
与初始化普通数组一样,只是数组的元素是函数的地址
比如数组元素是指向int (int,int)类函数
int(*pfun[3])(int,int)=fun1,fun2,fun3; 也可以{&fun1,&fun2,&fun3}
3、函数指针数组的应用(简易计算器的实现)
#include <stdio.h>
int add(int a,int b)
return a+b;
int sub(int a,int b)
return a-b;
int mul(int a,int b)
return a*b;
int div(int a,int b)
return a/b;
int main()
int input=1;
int x=0,y=0;
int ret=0;
int(*p[4])(int,int)=add,sub,mul,div;
while(input)
printf("1.add 2.sub 3.mul 4.div 0.exit\\n");
scanf("%d",&input);
if(input>0&&input<5)
printf("请输入操作数\\n");
scanf("%d%d",&x,&y);
ret=(*p[intput-1])(x,y);
printf("%d\\n",ret);
else if(input==0)
break;
else
printf("输入有误,请重新输入\\n");
return 0;
上面的代码是使用函数指针数组来实现计算器,不用函数指针数组还可使用switch语句,但是如果计算器的功能复杂就会使用大量的case语句,这种情况下使用函数指针数组就可以减少代码冗余。
三、函数指针数组的数组指针
顾名思义,函数指针数组的数组指针,首先它是一个指针,因为它指向一个数组,所以叫数组指针,又这个数组是一个函数指针数组,所以这个指针就是指向函数指针数组的数组指针。
如下是定义一个简单的函数指针数组的数组指针:
char * (*(*parr)[3])(char * p);
*先与parr结合,所以parr是一个指针,去掉(*parr)就是parr可以指向的类型,
char*(*[3])(char*p): *先与[3]结合,这是一个指针数组,parr指向一个数组,去掉[3] 就是数组的类型,char*(*)(char*p)这是一个函数指针类型,故parr是指向函数指针数组的数组指针。
只需对一个函数指针数组取地址,取出的地址就可以对函数指针数组的指针初始化或赋值。
四、回调函数
1、概念
什么是回调函数呢?
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。
既然通过函数指针就可以调用一个函数,那么我们是不是可以封装一个函数,既可以实现加减,又可以实现乘除呢?答案是可以的。(这里说的不适在函数内部判断来实现的)
//回调函数
#include <stdio.h>
int add(int a, int b)
return a+b;
int sub(int a, int b)
return a-b;
int mul(int a, int b)
return a*b;
int div(int a, int b)
return a/b;
int op(int (*pfun)(int , int)) //回调函数op,只要给该函数传上面函数的地址,
//就可以实现两个数的加减乘除
return pfun(1,2);
int main()
int input=1;
int x=0,y=0;
int ret=0;
int(*p[4])(int,int)=add,sub,mul,div;
while(input)
printf("1.add 2.sub 3.mul 4.div 0.exit\\n");
scanf("%d",&input);
if(input>0&&input<5)
printf("请输入操作数\\n");
scanf("%d%d",&x,&y);
ret= op(p[input-1]);
printf("%d\\n",ret);
else if(input==0)
break;
else
printf("输入有误,请重新输入\\n");
return 0;
其实上面的例子没有必要用回调函数来实现,这样太复杂来,而且太大材小用了,只是方面理解。
2、应用
接下来我们来看一下回调函数的应用
编写一个冒泡排序函数可以既可以排序字符串,又可以排序数字,还可以排序字符。
#include <stdio.h>
#include <string.h>
int com_int(const void *elem1, const void *elem2 )
return *(int *)elem1 - *(int *)elem2;
int com_str(const void *elem1, const void *elem2)
return strcmp((char *)*(int *)elem1, (char *)*(int *)elem2);
int com_char(const void *elem1, const void *elem2)
return*(char*)elem1 - *(char*)elem2;
void Swap(char *p1, char *p2, size_t sz)
size_t i = 0;
for(i = 0; i<sz; i++)
char tmp = *(p1+i);
*(p1+i) = *(p2+i);
*(p2+i) = tmp;
void bubble_sort(void *base, size_t num, size_t width,int (*cmp)(const void *elem1, const void *elem2))
size_t i = 0,j=0;
for(i = 0; i < num-1; i++)
for(j = 0; j < num-1-i; j++)
if(cmp((char *)base+ width*j, (char *)base+width*(j+1)) > 0)
Swap((char *)base+ width*j, (char *)base+width*(j+1), width);
int main()
//char *arr1[] = "bbbb","aaaa","dddd","cccc";
//int arr1[] = 1, 3, 5, 7, 2, 4, 6, 8 ;
char arr1[] = "asdggt";
int i = 0,len=0;
len = sizeof(arr1) / sizeof(arr1[0]);
bubble_sort(arr1,len , sizeof(char), com_char);
for(i = 0 ;i<sizeof(arr1)/sizeof(arr1[0]);i++)
printf("%c\\n",arr1[i]);
printf("\\n");
return 0;
本文出自 “牛丽” 博客,请务必保留此出处http://15129279495.blog.51cto.com/10845420/1737892
以上是关于C 指针&&函数的主要内容,如果未能解决你的问题,请参考以下文章