精华内容
下载资源
问答
  • 指针 指针数组 指针数组的指针 数组指针 数组指针的数组 函数指针 函数指针数组 指向函数指针数组的指针

           指针是c语言的灵魂所在,然而因为其过于灵活,在使用的过程中难免出错。接下来我们简单分析一下常见的指针运用。

    指针:

         1  一级指针

             char *p1 =  “abcdef”;

          2  二级指针

             char **p2 = &p1;

    指针数组:

         1 char *arr[5] ;  (在数组中存放5个char* 指针)

    指针数组指针

         1 char* arr[5];

            char * (*parr)[5] = &arr;

           parr就是指向指针数组arr的指针 (即parr为指针数组的指针)

    数组指针:

         1   int   arr[5] = {1,2,3,4,5};

              int  (*p)[5] = &arr ;          p即为指向数组的指针,又称数组指针

    数组指针的数组:

          int arr1[3] = {1,2,3};

          int arr2[3] = {4,5,6};

          int (*parr[2])[3]={arr1,arr2};


    函数指针:

      先写一个简单的函数

            int add(int x, int y)

             {

                return x+y;

             }

        int  (*pfun)(int, int);

                pfun = add;

    这样一来  pfun就是指向函数add的指针(即函数add的指针)。

    下面是定义一个函数指针的方法:



    指向函数指针数组的指针:

               函数指针数组也是指针数组,在这个数组中存放的是函数的指针

        eg: 我们先写加减乘除四个子函数。

             

            int (*pfunarr[4])(int, int) = {add, sub, mul, div};//这个数组就是函数指针数组      pfunarr就是指向函数指针数组的指针

    展开全文
  • 指针数组 首先从名字就可以知道这是一个数组,是存放指针的数组。 先看几种指针数组: int * 数组指针 函数指针 函数指针数组 指向函数指针数组的指针

    指针数组

    首先从名字就可以知道这是一个数组,是存放指针的数组。
    先看几种指针数组:
    int *arr1[10];
    char *arr2[5];
    char **arr3[6];
    因为 [ ] 的优先级是高于 * 的,所以数组名会先于 [ ] 相结合组成数组。 再于 int * / char *类型结合,组成存放该类型的数组。



    指针数组因为存放的都是指针所以不管是 int *   char * 还是 char ** 其大小都是四个字节。

    数组指针

    从名字看就知道是指针,是指向一个数组的指针。

    int (*p)[10];
    char (*p)[10];
    由数组指针知道 [ ] 的优先级是高于 *  的,所以用()来提升指针先结合。

    int (*p)[10];  //  是一个指向10个整形的一维数组的指针
    char (*p)[10]; //  是一个指向10个字符型的一维数组的指针

    数组的存储方式



    因为指向的是一个数组,所以大小由数组决定


    函数指针

    指向函数的指针,通俗的说也就是函数的地址
    void(*pfun)();
    pfun 先和*结合,说明pfun是指针,指针指向的是一个函数,指向的函数无参数,返回值类型为void
    也就是说 其可以保存函数的地址



    函数指针数组

    int (*parr[3])();
    parr先与 [ ]结合,说明是一个数组,再与*结合,说明数组存放的是指针,指针都指向的是函数
    函数指针数组的使用(转移表)
    例子:计算器
    #include<stdio.h>
    
    int add( x, y)
    {
    	return x + y;
    }
    int sub(x,y)
    {
    	return x - y;
    }
    int mul(x,y)
    {
    	return x * y;
    }
    int div(x,y)
    {
    	return x / y;
    }
    int main()
    {
    	int x, y;
    	int input = 1;
    	int ret = 0;
    	int(*parr[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表
    	while (input)
    	{
    		printf("*******************************\n");
    		printf("***** 1.add         2.sub *****\n");
    		printf("***** 3.mul         4.div *****\n");
    		printf("*******************************\n");
    		printf("请选择:");
    		scanf("%d", &input);
    		if ((input > 0 && input < 5))
    		{
    			printf("输入你要计算的数:\n");
    			scanf("%d  %d", &x, &y);
    			ret = (*parr[input])(x, y);
    		}
    		else
    			printf("输入有误!\n");
    		printf("%d\n", ret);
    	}
    	return 0;
    }
    输出结果:


    指向函数指针数组的指针 

    这是一个指针,指向一个数组,这个数组是一个函数指针数组,数组中的元素都是函数指针

    定义方式:

    #include<stdio.h>
    void test(const char *str)
    {
    	printf("%s\n", str);
    }
    int main()
    {
    	void (*pfun)(const char*) = test;
    	//函数指针pfun
    	void (*pfunArr[5])(const char* str);
    	//函数指针的数组pfunArr
    	void (*(*ppfunArr)[10])(const char* str) = &pfunArr;
    	//指向函数指针数组pfunArr的指针ppfunArr
    	return 0;
    }




    展开全文
  • 函数指针和指针函数用法和区别

    万次阅读 多人点赞 2018-05-24 08:11:10
    函数指针和指针函数,在学习 C 语言的时候遇到这两个东西简直头疼,当然还有更头疼的,比如什么函数指针函数、指针函数指针、数组指针、指针数组、函数指针数组等等,描述越长其定义就越复杂,当然理解起来就越难,...

    前言

    函数指针和指针函数,在学习 C 语言的时候遇到这两个东西简直头疼,当然还有更头疼的,比如什么函数指针函数、指针函数指针、数组指针、指针数组、函数指针数组等等,描述越长其定义就越复杂,当然理解起来就越难,特别是刚开始学习这门语言的童鞋,估计碰到这些东西就已经要崩溃了,然后好不容易死记硬背下来应付考试或者面试,然后过了几天发现,又是根本不会用,也不知道该在哪些地方用,这就尴尬了。
    今天这里只讲两个相对简单的,其实上面说那些太复杂的东西也真的很少用,即便是用了理解起来很麻烦,所以莫不如先深刻理解这两个比较容易的,并且项目中比较常用到。

    正文

    先来看看两者的定义以及说明。

    指针函数

    定义

    指针函数,简单的来说,就是一个返回指针的函数,其本质是一个函数,而该函数的返回值是一个指针。
    声明格式为:*类型标识符 函数名(参数表)

    这似乎并不难理解,再进一步描述一下。
    看看下面这个函数声明:

    int fun(int x,int y);
    

    这种函数应该都很熟悉,其实就是一个函数,然后返回值是一个 int 类型,是一个数值。
    接着看下面这个函数声明:

    int *fun(int x,int y);
    

    这和上面那个函数唯一的区别就是在函数名前面多了一个*号,而这个函数就是一个指针函数。其返回值是一个 int 类型的指针,是一个地址。

    这样描述应该很容易理解了,所谓的指针函数也没什么特别的,和普通函数对比不过就是其返回了一个指针(即地址值)而已。

    指针函数的写法

    int *fun(int x,int y);
    int * fun(int x,int y);
    int* fun(int x,int y);
    

    这个写法看个人习惯,其实如果*靠近返回值类型的话可能更容易理解其定义。

    示例

    (由于本人习惯于 Qt 中进行开发,所以这里为了方便,示例是在 Qt 工程中写的,其语法是一样的,只是输出方式不同)
    来看一个非常简单的示例:

    typedef struct _Data{
        int a;
        int b;
    }Data;
    
    //指针函数
    Data* f(int a,int b){
        Data * data = new Data;
        data->a = a;
        data->b = b;
        return data;
    }
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        //调用指针函数
        Data * myData = f(4,5);
        qDebug() << "f(4,5) = " << myData->a << myData->b;
    
        return a.exec();
    }
    
    

    输出如下:

    f(4,5) =  4 5
    

    注意:在调用指针函数时,需要一个同类型的指针来接收其函数的返回值。
    不过也可以将其返回值定义为 void*类型,在调用的时候强制转换返回值为自己想要的类型,如下:

    //指针函数
    void* f(int a,int b){
        Data * data = new Data;
        data->a = a;
        data->b = b;
        return data;
    }
    
    调用:
    Data * myData = static_cast<Data*>(f(4,5));
    

    其输出结果是一样的,不过不建议这么使用,因为强制转换可能会带来风险。

    函数指针

    定义

    函数指针,其本质是一个指针变量,该指针指向这个函数。总结来说,函数指针就是指向函数的指针。
    声明格式:类型说明符 (*函数名) (参数)
    如下:

    int (*fun)(int x,int y);
    

    函数指针是需要把一个函数的地址赋值给它,有两种写法:

    fun = &Function;
    fun = Function;
    

    取地址运算符&不是必需的,因为一个函数标识符就表示了它的地址,如果是函数调用,还必须包含一个圆括号括起来的参数表。

    调用函数指针的方式也有两种:

    x = (*fun)();
    x = fun();
    

    两种方式均可,其中第二种看上去和普通的函数调用没啥区别,如果可以的话,建议使用第一种,因为可以清楚的指明这是通过指针的方式来调用函数。当然,也要看个人习惯,如果理解其定义,随便怎么用都行啦。

    示例

    int add(int x,int y){
        return x+y;
    }
    int sub(int x,int y){
        return x-y;
    }
    //函数指针
    int (*fun)(int x,int y);
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        //第一种写法
        fun = add;
        qDebug() << "(*fun)(1,2) = " << (*fun)(1,2) ;
    	//第二种写法
        fun = &sub;
        qDebug() << "(*fun)(5,3) = " << (*fun)(5,3)  << fun(5,3);
    
        return a.exec();
    }
    
    

    输出如下:

    (*fun)(1,2) =  3
    (*fun)(5,2) =  2 2
    

    上面说到的几种赋值和调用方式我都分别使用了,其输出结果是一样的。

    二者区别

    通过以上的介绍,应该都能清楚的理解其二者的定义。那么简单的总结下二者的区别:

    定义不同

    指针函数本质是一个函数,其返回值为指针。
    函数指针本质是一个指针,其指向一个函数。

    写法不同

    指针函数:int* fun(int x,int y);
    函数指针:int (*fun)(int x,int y);
    可以简单粗暴的理解为,指针函数的*是属于数据类型的,而函数指针的星号是属于函数名的。
    再简单一点,可以这样辨别两者:函数名带括号的就是函数指针,否则就是指针函数。

    用法不同

    上面已经写了详细示例,这里就不在啰嗦了。

    总而言之,这两个东西很容易搞混淆,一定要深入理解其两者定义和区别,避免犯错。

    另外,本文都是针对普通函数指针进行介绍,如果是C++非静态成员函数指针,其用法会有一些区别,在另外一篇博客中单独介绍,文章在这里

    展开全文
  • 函数指针函数指针指向可执行代码段或调用可执行代码段的信息块的指针,而不是指向某种数据的指针。函数指针是将函数当做普通数据那样存储和管理。函数指针有一种固定的形式,就是包含一个确定的返回值类型和若干...

    我们已经学过C语言很长一段时间了,相信大家对于这个问题还不是特别的陌生,今天我们就来再次的认识这些令我们头痛的函数的一些基本的区别。

    函数指针

    函数指针:函数指针是指向可执行代码段或调用可执行代码段的信息块的指针,而不是指向某种数据的指针。函数指针是将函数当做普通数据那样存储和管理。函数指针有一种固定的形式,就是包含一个确定的返回值类型和若干个函数参数。声明一个函数指针看起来与声明一个函数相类似,知识在函数名前面加上了表示指针的,并且函数名和 会被用小括号括起来。例如下面的一段代码中,match被声明为一个函数指针,它接收两个void指针类型的参数,同时返回一个整型。
    int (*match)(void* key1,void* key2)
    以上该函数的声明的意思就是我们指定一个接收两个void指针,返回一个整型名为match函数的指针。例如:假如:假设有一个match_int函数的指针,它的两个void指针参数指向整型并返回1,考虑到之前函数的声明为match,我们可以这样去赋值。
    match=match_int
    要执行一个由函数指针所引用的函数,我们只需要在正常调用普通函数的地方调用函数指针,例如:想要在调用之前提到的函数指针match,我们执行下面的语句,假设x,y和retval都已经被声明为整型。
    retval=match(&x,&y)
    函数指针的最重要的用途是将函数封装到数据结构中。
    在我的认识中,函数指针的地址为第一条指令的地址,可以是该函数的函数名,也可以是对该函数取地址,函数名所代表的是函数的地址(函数名具有刻可读属性)。
    我们来看下代码:

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    
    void test(){
        printf("hehe\n");
    }
    int main()
    {
        printf("%p\n", test);
        printf("%p\n", &test);
        getchar();
        return 0;
    }

    输出的结果为:
    这里写图片描述
    我们可以看到输出的是两个地址,这两个地址是test函数的地址。
    那么我们的函数的地址要想保存起来,怎样保存?
    看下面的代码:

    void test()
    {
    printf(“hehe\n”);
    }
    //下面的pfun1和pfun2那哪个有能力存放test函数的地址?
    void (*pfun1)();
    void *pfun2();//()的优先级高于*

    首先,能给存储的地址,就是要求pfun1或pfun2是指针,那哪个是指针?
    答案是:

    pfun1可以存放,pfun1先和* 结合,说明pfun1是指针,指针指向的是一个函数,指向的函数无参数,返回值类型为void* ;

    函数指针数组

    数组是一个存放相同类型数据的存储空间,那我们已经学习了指针数组。比如:
    int *arr[10]//数组中的每个元素是int*
    那么要把函数的地址存放到一个数组中,那这个数组就叫做函数指针数组,那函数指针数组是如何进行定义的:

    `int (*parr1[10]) ();
    int    *parr2[10]();
    int    (*)() parr3;

    答案是parr1
    parr1先和[ ]结合,说明parr1是数组,数组的内容是什么呢?是int (*)()类型的函数指针。

    指向函数指针数组的指针

    我们但从字面来看这是一个指针,它指向的是一个函数指针数组定义一个指针。
    int (*arr[5])(int ,int)={NULL,Add,Sub,Mul,Div};
    int (*(*p)[5])(int ,int)=&arr;

    p先和*结合,是一个指向函数指针数组的变量,p中存放的是整个数组的地址。`(*p)1; (*p)表示访问数组下标为1的元素Add,然后调用Add函数,参数为1和2。

    展开全文
  • 我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,即指针指向该函数的内存首地址,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数。 这种指针就是函数指针。 p=函数名;//...
  • 函数指针指向的是函数而非对象。和其他类型一样,函数指针指向某种特定类型。因为函数的类型由它的返回类型和形参类型共同决定,与函数名无关,所以想要声明一个函数指针,只需要用指针替换函数名即可,例如:比较...
  • 如何打印函数指针指向的函数名

    千次阅读 2013-02-18 18:43:36
    在涉及自己创建的函数指针,为了方便调试,希望将函数指针当前指向的函数名打印出来。直接打印不可能,所以需要在定义指针时添加上指示符。 例如stackoverflow上的一段代码样例 ...
  • 函数指针指向函数代码的起始地址 定义 返回类型 (*指针变量名)( ) ; //如: int (*p)(int a,int b);//定义函数指针 使用 : //定义+赋值 int (*p)(int a,int b); int isdigit(int a...
  • 所谓函数指针数组就是在之前的函数指针的基础上增加了[],由于[]的优先级高于*,故 pf先与[]结合,说明它是一个数组,再与*结合说明数组中的元素的类型是指针,再看后面的参数列表,说明每一个指针都指向一个函数的...
  • 如前所述,C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针指向地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上是一致的。...
  • 指针数组表达式为:int *p[5] 理解:下标运算符[ ]的优先级是要高于指针运算符*,因此p先和下标运算符结合,决定了p首先是个数组,其类型int *,表明数组的元素都是都是指针。而数组占多少个字节由数组本身决定。...
  • 理解:定义了一个数组,而它的每个元素的类型是一个指向字符/字符串的指针。 元素表示:char *a[i] char *(a[i])是一样的,因为[]优先级高于* 思考:是否可以这样理解 (char*)arr[4]? 深入理解: 数组...
  • 指针函数指向函数指针变量

    千次阅读 2016-03-07 14:03:34
    一个函数在编译时被分配一个入口地址,这个函数入口地址就称为函数指针。可以用一个指针变量指向函数,然后通过该指针变量调用此函数。 1. 指向函数指针变量的一般定义形式为:  函数类型 (*变量名)...
  • 指向函数指针变量的用途之一就是可以把该函数的入口地址作为参数传递到其它函数(传递给形参)。 原理举例: 有一个函数名为fun的函数,它有两个形参x1和x2,并且定义x1和x2为指向函数指针变量。在调用fun函数...
  • 指针函数和函数指针

    万次阅读 多人点赞 2019-03-30 16:21:36
    很多人因为搞不清这两个概念,干脆就避而远之,我刚接触C语言的时候对这两个概念也比较模糊,特别是当指针函数、函数指针函数指针变量、函数指针数组放在一块的时候,能把强迫症的人活活逼疯。 其实如果理解了这些...
  • C++函数指针、指针函数、返回值为函数指针的函数浅谈 引言 函数指针、指针函数是C中重要而容易混淆的概念,博主将通过两个实例来说明这两个...定义了一个函数指针add,用于指向返回值为int,并且有两个int参数的函数...
  • 函数指针函数指针类型

    千次阅读 2018-09-29 08:48:59
    函数指针 1. 定义 每一个函数都占用一段内存单元,它们有一个起始地址,...注意:函数指针的本质是一个指针变量,且指针指向的函数的入口地址 2. 语法 指向函数的指针变量的一般定义形式为:  数据类型 ...
  • 详解C语言指针函数、函数指针函数指针数组

    万次阅读 多人点赞 2018-07-09 11:08:24
    而在指针中,指针函数、函数指针、指针函数数组、函数指针数组、指向函数指针数组的指针等等概念看着又绕又头疼。本问总结了一下以上一些概念以及用法,并给出例程深化理解。 1. 指针函数 指针函数就是返回指针值...
  • 正确答案: A int (*(*F)(int, int))(int) int (*F)(int, int) ... 先看优先级最高的,即内部括号(*F),看出F是一个指针,然后再看右边(int , int),说明它是一个函数指针,(int,int)为此函数的形参列表.
  • 指向函数指针 指向函数指针的数组
  • 函数名/函数地址/函数指针

    千次阅读 2017-02-13 15:45:28
    转自:... 函数指针:1。...指针变量指向函数 ...这正如用指针变量可指向整型变量、字符型、数组一样。...在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针指向地址。 可
  • 代码跟小甲鱼老师讲课时基本一样** 函数具有可赋值给指针的物理内存地址,一个函数的函数名就是一个指针,它指向函数的代码。一个函数的地址是该函数的进入点,也是...*函数指针还允许将函数作为变元传递给其他...
  • 一个指向 C++ 类的指针指向结构的指针类似, 访问指向类的指针的成员,需要使用成员访问运算符 ->,就像访问指向结构的指针...类的指针:他是一个内存地址值,他指向内存中存放的类对象(包括一些成员变量所赋的值).
  • 指向函数的指针 ------ 函数指针(function pointer)

    万次阅读 多人点赞 2017-11-21 13:23:17
    一个函数函数名是一个指针,它指向函数的代码。函数的调用可以通过函数名,也可以通过指向函数指针来调用。 定义形式:  类型 (*指针变量名)(参数列表); 例如:  int (*p)(int i,int j);  p是一个指针,...
  • c++ 函数指针

    万次阅读 多人点赞 2019-06-15 21:41:38
    声明指针时,必须指定指针指向的数据类型,同样,声明指向函数的指针时,必须指定指针指向函数类型,这意味着声明应当指定函数的返回类型以及函数的参数列表。 例如: double cal(int); ...
  • C++函数指针详解

    2021-01-21 17:09:41
    函数指针指向这个地址函数指针指向的类型,是函数本身。我们知道,指针所指向类型代表了指针所指向的内存区域的大小。所以函数指针指向的类型,是函数在内存中所占据内存的大小。知道了函数的起始地址和大小...
  • C语言之函数指针和函数的首地址

    千次阅读 2017-03-06 18:03:48
    至于函数指针用法,一眼便知 对于add和&add你应该这样理解,add是函数的首地址,它的类型是void (),&add表示一个指向函数add这个对象的地址,它的类型是void (*)(),因此add和&add所代表的地址值是一样的,但类型...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 782,704
精华内容 313,081
关键字:

函数指针指向地址