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;
}

C 指针&&函数

时间: 2024-08-12 15:49:55

C 指针&&函数的相关文章

数组指针、指针数组、函数指针、指针函数 -----笔记

1.数组的四种访问方式 定义数组 a[]; 指针 *p 指向数组a; (1) 利用数组的下表进行访问 a[i]; (2) 数组名+地址的偏移量i *(a+i) (3) 利用指针 p 进行下表访问 p[i] (4) 指针p + 地址的偏移量i *(p+i) 一维数组数组名:相当于一个单指针 2. 数组指针(指针)     指针数组(数组) 函数指针(指针)     指针函数(函数)    -------->只看后边两个字就能够区分是指针还是数组或函数 _______________________

【转】 指针函数与函数指针的区别

一. 在学习arm过程中发现这“指针函数”与“函数指针”容易搞错,所以今天,我自己想一次把它搞清楚,找了一些资料,首先它们之间的定义: 1.指针函数是指带指针的函数,即本质是一个函数.函数返回类型是某一类型的指针 类型标识符    *函数名(参数表) int *f(x,y); 首先它是一个函数,只不过这个函数的返回值是一个地址值.函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针变量. 表示: float *fun();

函数指针和指针函数

(1)函数指针 函数指针就是指向函数的指针变量,即本质是一个指针变量. int (*f) (int x); /* 声明一个函数指针 */ f=func; /* 将func函数的首地址赋给指针f */ 指向函数的指针包含了函数的地址,可以通过它来调用函数.声明格式如下:        类型说明符 (*函数名)(参数) (2)指针函数 指针函数是指带指针的函数,即本质是一个函数.函数返回类型是某一类型的指针 类型标识符 *函数名(参数表) int *f(x,y);

指针函数与函数指针

指针函数与函数指针:函数名之前的指针×是不是被括号包含,如果被包含就是函数指针,反之则是指针函数. 1.指针函数是指带指针的函数,即本质是一个函数,函数返回时某一个类型的指针 类型符 *函数名(参数名) 指针函数的返回值是一个地址值,指针函数一定有函数返回值,而至在主调函数中函数返回值必须赋值给同类型的指针变量: float *fun(); float *p = fun(); 2.函数指针是指向函数的指针变量,即本质是一个指针变量 int (*f)(int x) f =func; 指向函数的指针

【C/C++学院】0726-cppIDE/一级指针/指针数组/函数指针/函数指针数组/二级指针

[送给在路上的程序员] 对于一个开发者而言,能够胜任系统中任意一个模块的开发是其核心价值的体现. 对于一个架构师而言,掌握各种语言的优势并可以运用到系统中,由此简化系统的开发,是其架构生涯的第一步. 对于一个开发团队而言,能在短期内开发出用户满意的软件系统是起核心竞争力的体现. 每一个程序员都不能固步自封,要多接触新的行业,新的技术领域,突破自我. cppIDE 使用mfc和codeblocks中的mingw编译器.执行system命令中的bat批处理脚本. 一级指针 指针,结构体struct,

深入理解 [指针函数] 、[函数指针]、[指针的指针]、[指向指针数组的指针]

指针函数 1.指针函数是指带指针的函数,即本质是一个函数.当一个函数声明其返回值为一个指针时,实际上就是返回一个地址给调用函数,以用于需要指针或地址的表达式中. 函数返回类型是某一类型的指针: 格式: 类型标识符  *函数名(参数表) int *match(void *key_x,void *key_y); 解析:首先来说它是一个函数,只不过这个函数的返回值是一个地址值.函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针

函数指针与指针函数返回值的区别

指针函数是指带指针的函数,即本质是一个函数.函数返回类型是某一类型的指针定义: 类型标识符 *函数名(参数表)eg: int *f(x,y);函数指针是指向函数的指针变量,即本质是一个指针变量.int (*f) (int x); /* 声明一个函数指针 */ f=func; /* 将func函数的首地址赋给指针f */ 函数指针与指针函数返回值的区别,码迷,mamicode.com

函数指针与指针函数

一. 在学习arm过程中发现这“指针函数”与“函数指针”容易搞错,所以今天,我自己想一次把它搞清楚,找了一些资料,首先它们之间的定义: 1.指针函数是指带指针的函数,即本质是一个函数.函数返回类型是某一类型的指针 类型标识符    *函数名(参数表) int *f(x,y); 首先它是一个函数,只不过这个函数的返回值是一个地址值.函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针变量. 表示: float *fun();

【C语言】用指针函数完成:有a个学生,每个学生有b门课。要求在输入学生序号后输出该学生成绩

//用指针函数完成:有a个学生,每个学生有b门课.要求在输入学生序号后输出该学生成绩 #include <stdio.h> float * search(float (* pointer )[4],int n) //形参pointer是一个数组指针 { float *pt; pt=*(pointer+n); return pt; } int main() { float score[][4]={{60,70,80,90},{56,57,78,85},{75,45,36,85}}; float

深入理解指针—&gt;指针函数与函数指针的区别

一. 在学习过程中发现这"指针函数"与"函数指针"容易搞错,所以今天,我自己想一次把它搞清楚,找了一些资料,首先它们之间的定义: 1.指针函数是指带指针的函数,即本质是一个函数.函数返回类型是某一类型的指针 类型标识符    *函数名(参数表) int *f(x,y); 首先它是一个函数,只不过这个函数的返回值是一个地址值.函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针变量. 表示: f