精华内容
下载资源
问答
  • 所谓函数指针数组就是在之前的函数指针的基础上增加了[],由于[]的优先级高于*,故 pf先与[]结合,说明它是一个数组,再与*结合说明数组中的元素的类型是指针,再看后面的参数列表,说明每一个指针都指向一个函数的...

    一、函数指针数组

    1.1函数指针数组的声明

          函数指针数组的声明如下,所谓函数指针数组就是在之前的函数指针的基础上增加了[],由于[]的优先级高于*,故 pf先与[]结合,说明它是一个数组,再与*结合说明数组中的元素的类型是指针,再看后面的参数列表,说明每一个指针都指向一个函数的入口地址,并且指向的函数的返回类型为int。

    int (*pf[])(int, int);

    1.2函数指针的使用

          以下代码展示了函数指针数组的一个简单的应用。

    #include <stdio.h>
    
    int Add(int x, int y)
    {
    	return x + y;
    }
    
    int Sub(int x, int y)
    {
    	return x - y;
    }
    
    int main()
    {
    	int a = 10;
    	int b = 20;
    
            //定义一个有2个指针的数组,指针指向一个函数,该函数有两个整型参数并返回一个整型数
    	int(*p[2])(int, int);
    	p[0] = Add; //函数指针数组的第一个元素指向Add函数
    	p[1] = Sub;
    
    	printf("%d, %d\n", p[0](a, b), p[1](a, b));
    
    	system("pause");
    	return 0;
    }

    二、指向函数指针数组的指针

          在此,仅作介绍,它也叫函数指针数组的指针。下面的定义怎么理解呢?首先,p和*结合说明是一个指针,之后与[]结合,说明是一个数组指针,再与*结合说明用一个指针指向了数组指针,之后又指向了一个函数的入口地址,该函数有两个int类型参数,返回值是int。

    int (*(*p)[])(int, int);

         总而言之,指向函数指针数组的指针就是在函数指针数组的基础上,再加一个*表示一个指针去指向它。当然,既然有函数指针数组的指针,则必然还有函数指针数组的指针数组,只不过一般的编程用到的情况很少,如果读者有兴趣的话,可以去研究一下。

    展开全文
  • 我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,即指针指向该函数的内存首地址,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数。 这种指针就是函数指针。 p=函数名;//...

    1. 函数指针的定义

    一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似。

    我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,即指针指向该函数的内存首地址,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数。

    这种指针就是函数指针

    p=函数名;//p为指针变量
    

    2. 函数指针的定义形式

    2.1 一般定义方法

    returnType (*pointerName)(param list);
    

    returnType 为函数返回值类型,pointerNmae 为指针名称,param list 为函数参数列表。参数列表中可以同时给出参数的类型和名称,也可以只给出参数的类型,省略参数的名称,这一点和函数原型非常类似。

    注意( )的优先级高于*,第一个括号不能省略,如果写作returnType *pointerName(param list);就成了函数原型,它表明函数的返回值类型为returnType *。

    例:

    void (*irq_func)(void);
    

    定义了一个函数指针irq_func,指向的函数接收一个整形参数且无返回值。

    2.2 加上typedef关键字的定义

    typedef void (*irq_func)(void);
    

    加上typedef关键字后,irq_func就不再是一个单一的函数指针了,而是一种数据类型,是指向“无形参且无返回值”这种类型函数的函数指针类型。

    我们可以利用irq_func去定义具体的函数指针。
    例如:

    void test(void)
    {
    	printf("hello world!\n");
    }
    
    typedef void (*irq_func)(void);
    
    irq_func p_test_1=test;//定义一个指向函数test的函数指针p_test_1。
    irq_func p_test_2=&test;//函数指针指向函数地址时候,可以加取地址符号&,也可以不加,效果等同。
    

    注意:函数指针指向函数地址时候,可以加取地址符号&,也可以不加,效果等同。函数名是一个地址,可以将他赋值给一个指向函数的指针。前面加了&符号其意义是一样的。这些都是设计语言时这样规定的。

    记住:只要加上typedef,就是定义了一种新的数据类型,或为已存在的数据类型进行重命名。这里属于第一种。

    3.利用函数指针调用其所指向的函数

    3.1 情况1:一般调用

    int test(void)
    {
    	return 6;
    }
    
    typedef int (*irq_func)(void);
    
    irq_func p_test_1=test;
    

    问:当我们向使用函数指针p_test_1来调用函数test时,下列哪种方法是正确的?

    第1种写法:

    int i;
    i=p_test_1();
    

    第2种写法:

    int j;
    j=(*p_test_1)();
    

    答:以上两种写法都可以。最终效果一致,变量 i 和 j 的值均为6.

    3.2 情况2:函数指针做为结构体成员

    当函数指针是一个结构体变量的成员时,此时怎么正确调用此函数指针所指向的函数?

    问:此时下面三个调用函数的写法哪个正确?

    #include "stdio.h"
    
    int test(void)
    {
    	return 5;
     } 
     
     typedef struct haha
     {
     	int (*p_test)(void);
     }haha,*p_haha;
     
    haha cw=
    {
    	.p_test=test,
    };
    
    p_haha p_cw=&cw;
    
    int main(void)
    {
    	int i,j,k;
    	
    	/*写法1*/
    	i=cw.p_test();	
    	printf("i =%d\n",i);
    	
    	/*写法2*/
    	j=cw.(*p_test)();
    	printf("j =%d\n",j);
    	
    	/*写法3*/
    	k=(*(cw.p_test))();
    	printf("k =%d\n",k);
    }
    

    答:写法1,3正确。写法2错误。
    C语言中,‘.’运算符的优先级很高,比 * 高。

    第二种写法是在找cw的(*p_test)成员,这里显然是没有的,改成:(*(cw.p_test))()就没有问题,指向函数的指针说白了也就是一个特殊的变量而已。需要首先要通过’.'运算符获取到这个成员变量,才能使用这个变量。cw.p_test是获取变量的过程,不可以拆开的。

    如果用结构体指针p_cw来调用test函数,则正确写法是(*(p_cw->p_test))()

    (这里需要特别感谢CSDN的“Frankenstein_Quasimo”的解疑回答!)

    参考资料:https://blog.csdn.net/zhangzhi123456789/article/details/49253171

    展开全文
  • C语言中,我们知道,指针变量一种特殊的变量,专门用来...指针数组、数组指针、函数指针、函数指针数组、指向函数指针数组的指针 1.指针数组  指针数组强调的是数组,并且数组元素是指针类型 例:int *arr[5]//ar

    C语言中,我们知道,指针变量一种特殊的变量,专门用来存放其它变量的地址。因此,指针也可以说就是地址。但是,需要注意的是:什么类型的变量应该存放在什么类型的指针变量中。接下来我们对各类指针做一个讲解,希望能够帮到大家。分别有:

    指针数组、数组指针、函数指针、函数指针数组、指向函数指针数组的指针

    1.指针数组
      指针数组强调的是数组,并且数组元素是指针类型
    例:int *arr[5]//arr是一个数组,数组元素是指针(int*)

    2.数组指针
      数组指针强调的是指针,并且这个指针指向一个数组,即指针变量存放的是数组地址
    例:int (*arr)[5]//arr是一个指针,并且指向一个含有5个整型元素的数组

    3.函数指针
      函数指针强调指针,并且这个指针指向一个函数,即指针变量保存的是函数的地址
    例:void test(char* str);
    void (*p)(char*)//p是一个指针,并且指向一个函数,这个函数参数是char*,返回类型是void型

    4.函数指针数组
      函数指针数组强调数组,数组元素是函数指针
    例:void test(char* str);
    void (*p[5])(char*)//p是一个数组,有五个元素,每个元素是函数指针,这些指针指向的函数参数是char*,
    返回类型是void型

    5.指向函数指针数组的指针
      指向函数指针数组的指针强调指针,这个指针指向一个函数指针数组,这个数组中的元素是函数指针
    例:void test(char* str)
    void (*(*pfun)[5])(char*)=&test
    //pfun是一个指针,指向一个含有5个元素的数组,数组元素为函数指针,
    这个函数参数是char*,返回类型是void型

    展开全文
  • 本文主要介绍 C语言函数指针的知识,这里整理了详细的资料及示例代码以便大家学习参考,有需要学习此部分知识的朋友可以参考下
  • C语言函数指针和回调函数的详解

    万次阅读 多人点赞 2019-05-18 23:10:01
    函数指针指向函数的指针变量。 因此“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如前所述,C在编译时,每一个函数都有一个...

    函数指针:指向函数的指针变量。 因此“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如前所述,C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上是大体一致的。函数指针有两个用途:调用函数和做函数的参数。

    我们首先来看一个函数指针的例子:

    #include <stdio.h>
    #include <stdlib.h>
    void (*pfun)(int data);
    void myfun(int data)
    {
    	printf("get data:%d\n",data);
    }
    int main(int argc,char *argv[])
    {
    	pfun = myfun;
    	(*pfun)(100);
    	return 0;
    }
    从这个例子可以看到,我们首先定义了一个函数指针pfun ,这个函数指针的返回值为void型,然后我们给函数指针赋值,赋值为myfun,也就是myfun函数的首地址,在C99中myfun函数名就是myfun函数的首地址,此时pfun获得了myfun的地址,pfun的地址等于myfun的地址,所以最终调用pfun();也就相当于调用了myfun();
    
    第二种用法:typedef 原变量类型 别名
    也可以用typedef来定义一个指针函数这样使在大型代码中更加简洁
    #include <stdio.h>
    #include <stdlib.h>
    typedef void (*pfun)(int data);
    /*typedef的功能是定义新的类型。第一句就是定义了一种pfun的类型,并定义这种类型为指向某种函数的指针,这种函数以一个int为参数并返回void类型。*/
    void myfun(int data)
    {
    	printf("get data:%d\n",data);
    }
    int main(int argc,char *argv[])
    {
    	pfun p= myfun;      //函数指针指向执行函数的地址
    	p(100);
    	return 0;
    }
    这里面的pfun代表的是函数的类型,通过pfun来代表void (*)(int)函数类型即pfun是指针函数的别名,pfun p相当于定义了一个
    void (*p)(int)函数指针。p = myfun可以理解为将函数指针p指向myfun函数的地址,p(100);相当于执行myfun(100);
    
    第三种用结构体函数指针的方法
    #include <stdio.h>
    #include <stdlib.h>
    typedef struct gfun{
    	void (*pfun)(int);	
    }gfun;
    void myfun(int data)
    {
    	printf("get data:%d\n",data);
    }
    int main(int argc,char *argv[])
    {
    	gfun gcode={
    		.pfun = myfun,   //将函数指针指向要调用函数的地址
    	};
    	gcode.pfun(100);
    	return 0;
    } 
    

    这三种方法运行的结果一样
    在这里插入图片描述
    回调函数:通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
    下面是一个回调函数的例子:

    #include <stdio.h>
    #include <stdlib.h>
    typedef struct gfun{
    	int (*pfun)(int);	
    }gfun;
    
    int myfun(int data)
    {
    	printf("get data:%d\n",data);
    	return (data*2);
    }
    int rt_data(int data,int (*tr_fun)())
    {
    	return ((*tr_fun)(data));
    }  
    int main(int argc,char *argv[])
    {
    	int ret;
    	gfun gf;
    	gf.pfun = myfun;
    	ret = rt_data(100,gf.pfun);
    	printf("return data:%d\n",ret);
    	return 0;
    }
    

    运行的结果如下:
    在这里插入图片描述
    通过上面的例子我们可以看到将结构体中的函数指针指向了myfun函数地址,在回调函数中我们将函数指针gf.pfun作为rt_data(int data,int (*tr_fun)())函数的参数即为int (*tr_fun)();回调函数中的return (*tr_fun)(data)相当于对指针进行了简引用,返回这个指针指向地址的内容值。

    回调函数的意义
    可以把调用者与被调用者分开,所以调用者不关心谁是被调用者。它只需知道存在一个具有特定原型和限制条件的被调用函数。简而言之,回调函数就是允许用户把需要调用的函数的指针作为参数传递给一个函数,以便该函数在处理相似事件的时候可以灵活的使用不同的方法。
    回调函数在实际中有什么作用?先假设有这样一种情况:我们要编写一个库,它提供了某些排序算法的实现(如冒泡排序、快速排序、shell排序、shake排序等等),为了能让库更加通用,不想在函数中嵌入排序逻辑,而让使用者来实现相应的逻辑;或者,能让库可用于多种数据类型(int、float、string),此时,该怎么办呢?可以使用函数指针,并进行回调。
    回调可用于通知机制。例如,有时要在A程序中设置一个计时器,每到一定时间,A程序会得到相应的通知,但通知机制的实现者对A程序一无所知。那么,就需一个具有特定原型的函数指针进行回调,通知A程序事件已经发生。实际上,API使用一个回调函数SetTimer()来通知计时器。如果没有提供回调函数,它还会把一个消息发往程序的消息队列。
    谈完回调函数的意义,我们就有了用户和开发者之间的概念,举个例子,用户是实现myfun这个函数,开发者是实现rt_data函数,根据需求用户将myfun函数以参数的形式传入开发者的rt_data函数中,rt_data函数就能返回给相应的数据给用户,开发者不用告诉用户它实现了什么,用户也并不知道开发者怎么实现,用户只用传入自己的函数,便可以得到开发者实现的函数返回值,开发者可以将内容封装起来,将头文件以及库文件提供给用户。
    下面看个封装的例子
    main.c是上层用户开发的
    fun.c fun.h是开发者开发的

    mian.c代码如下

    #include "fun.h"
    #include<stdio.h>
    #include<stdlib.h>
    
    typedef struct gfun{
    	int (*pfun)(int);	
    }gfun;
    
    int myfun(int data)
    {
    	printf("get data:%d\n",data);
    	return (data*2);
    }
     
    int main(int argc,char *argv[])
    {
    	int ret;
    	gfun gf;
    	gf.pfun = myfun;
    	ret = rt_data(100,gf.pfun);
    	printf("return data:%d\n",ret);
    	return 0;
    }
    

    fun.h代码:

    #ifndef _FUN_H_
    #define _FUN_H_
    int rt_data(int data,int (*tr_fun)());
    
    #endif
    

    fun.c代码:

    #include "fun.h"
    int rt_data(int data,int (*tr_fun)())
    {
    	return ((*tr_fun)(data));
    }  
    

    最后用gcc main.c fun.c -o main编译完成后生成mian执行文件
    将执行文件执行后的结果如下:
    在这里插入图片描述
    在linux下制作动态链接库,将fun.c和fun.h打包成一个动态链接库

    先明白以下几个命令是什么意思:

    生成动态库:

    gcc -shared -fPIC fun.c -o fun.so

    -shared : 生成动态库;

    -fPIC : 生成与位置无关代码;

    -o :指定生成的目标文件;

    使用动态库:

    gcc main.c -L . –lfun -o main

    -L : 指定库的路径(编译时); 不指定就使用默认路径(/usr/lib/lib)

    -lfun : 指定需要动态链接的库是谁;

    代码运行时需要加载动态库:

    ./main 加载动态库 (默认加载路径:/usr/lib /lib ./ …)

    ./main
    我们将编译动态生成的libfun.so拷贝到/usr/lib后,现在就不需要fun.c了,此时我们将fun.c移除也可以正常的编译并执行main函数的结果。
    下面是我制作动态链接库的过程:
    在这里插入图片描述

    展开全文
  • 这是一个经过简化的可以选择功能的程序 主函数的意思是先定义函数指针*fun 然后指向排序函数 执行fun所指向的函数(就是排序) 然后排序函数会返回排好序的数组的首地址,最后进行输出 我知道这个算法肯定有错误 但是...
  • c语言函数指针和void *指向函数

    千次阅读 2018-08-22 14:52:12
    先说函数指针: void (*fun)(void); 这个就是一个函数指针了,函数的参数为空 void (*fun)(int); 这个也是一个函数指针,函数参数有个int 来看看void*类型: void *fun; 这样定义看起来很抽象,有...
  • 详解C语言指针函数、函数指针函数指针数组

    万次阅读 多人点赞 2018-07-09 11:08:24
    而在指针中,指针函数、函数指针、指针函数数组、函数指针数组、指向函数指针数组的指针等等概念看着又绕又头疼。本问总结了一下以上一些概念以及用法,并给出例程深化理解。 1. 指针函数 指针函数就是返回指针值...
  • c语言_函数指针的调用方法 函数指针就是指向函数的指针。 程序运行结果:
  • 为了方便操作类型属性相同的函数,c/c++引入了函数指针函数指针就是指向代码入口地址的指针,是指向函数的指针变量。 因而“函数指针”本身首先应该是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向...
  • c语言函数指针及指针函数

    千次阅读 2018-11-14 17:41:04
    函数指针本质是一个指针变量,指向函数的指针包含了函数的入口地址。 形式 指针函数: 函数返回值类型 *函数名(参数) 函数指针: 函数返回值类型(*函数名)(参数) 理解: 普通的函数主要分为有返回值和无返...
  • 但是,在指针变量的传递中,形参实际上和实参都指向同一个目标,因此,值改变则指向改变。 4)普通变量和指针变量最大的不同,在于传递的内容,尽管都是传值,但一个是值,另一个是地址 5)形...
  • C语言函数指针和复杂声明

    千次阅读 2018-07-20 15:16:56
    不同于JS中函数可以作为函数变量被创建(因为作者原本是学JS的,所以刚接触C时有点混淆),C语言中函数本身不是变量,但是可以定义指向函数的指针,即函数指针,从而用作变量进行一些参数传递等。 以下用一些示例...
  • 如何在C语言中使用函数指针 函数指针的定义 int (*p)(int,int); int代表的是指针变量名,两个int代表,函数参数有两个,且都为int型,当然以上定义只为示例,需要根据不同的函数,指定不同的参数类型和参数个数。...
  • C语言根据函数指针得到其函数名

    千次阅读 2019-02-22 10:59:42
    这次遇到的需求是需要知道函数指针指向的函数的名称是什么。感觉是不是有点儿像java里的反射,可以知道运行时的类是啥。 解决方法 方法一:内核态、printk()函数 如果是在内核态中,那么可以通过printk()函数来...
  • 理解函数指针和定义 先看一下一段代码: #define _CRT_SECURE_NO_WARNINGS 1 #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; void test() { printf("hehe\n"); } int main...
  • C语言-函数指针与函数名的区别

    千次阅读 多人点赞 2016-01-01 11:39:44
    记得大学时老师曾说函数的函数名是函数的入口的指针,之前看block通过clang编译...首先先定义一函数以及一个指向盖函数的函数指针,并分别对他们进行调用。 #include void fun(int x); int main(int argc, const char
  • c语言函数指针

    2013-08-28 21:54:54
    定义:指向函数的指针:函数指针 函数:void printFuction() 函数指针:void(*ptf)() 赋值:ptf=printFuction(ptf=&printFuction)c语言规定:当用函数名(printFution)来初始化函数指针时,函数名会被转换为指向...
  • C语言指针函数和函数指针区别

    千次阅读 多人点赞 2019-02-28 15:24:46
    C语言函数指针和指针函数的区别 C和C++中经常会用到指针,和数据项一样,函数也是有地址的,函数的地址是存储其机器语言代码的内存的开始地址。 指针函数和函数指针经常会混淆,一个是返回指针的函数,另一个是指向...
  • C语言指向函数指针

    千次阅读 2018-04-20 19:17:19
    这里介绍了关于指向一维数组的指针, 相关内容可以参考该文. 本文将简要介绍指向函数的指针. 如何声明一个指向函数的指针? ...void print(int num);... // 声明指向函数的指针,...函数指针类型的通用形式: 返回类型 (...
  • 前言一、返回指针的函数二、指向函数指针 说明:这个C语言专题,是学习iOS开发的前奏。也为了让有面向对象语言开发经验的程序员,能够快速上手C语言。如果你还没有编程经验,或者对C语言、iOS开发不感兴趣,请...
  • C语言-函数指针与函数名的区别***

    千次阅读 多人点赞 2018-06-11 13:48:46
    记得大学时老师曾说函数的函数名是函数的入口的指针,之前看block通过clang编译生成的C...首先先定义一函数以及一个指向盖函数的函数指针,并分别对他们进行调用。 //VS 2017 void fun(int& x); //定义函数f...
  • C语言函数指针和函数的首地址

    千次阅读 2017-03-06 18:03:48
    1、爆简单的代码 ... 对于add和&add你应该这样理解,add是函数的首地址,它的类型是void (),&add表示一个指向函数add这个对象的地址,它的类型是void (*)(),因此add和&add所代表的地址值是一样的,但类型不一样
  • C语言 | 函数指针作为函数的参数

    万次阅读 多人点赞 2019-08-05 08:22:38
    函数指针有两种常用的用法,一种是作为结构体成员,关于函数指针作为结构体成员的用法可移步至上一篇【C语言笔记】函数指针作为结构体成员进行查看。另一种是函数指针作为函数的参数。这一篇分享的是函数指针作为...
  • C语言指向函数指针

    千次阅读 2017-10-12 22:11:01
    C语言中,如果想把函数A作为函数B的参数传递给B,那么就可以使用指向函数指针。 假设我们有一个函数,来描述小动物一天的生活。包括吃、睡、叫。其中所有种类的动物的吃和睡方式都一样,但叫的不一样。可能会...
  • 正如文章题目所言,一个是函数的指针返回值,一个是指向函数指针,在这里 int *p( int a,int b)函数的返回值指向一个整型变量。  要弄明白两者的区别,首先得知道运算符()和*的优先级,由于运算符()的...
  • 函数返回值可以是 int char float等,当然也可以是地址值,那么函数返回值是地址...已知每个函数在编译的时候,系统会分配给函数一个入口地址,函数名表示这个入口地址,定义指向函数指针变量称之为函数的指针变量。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 174,150
精华内容 69,660
关键字:

c语言指向函数的指针

c语言 订阅