zoukankan      html  css  js  c++  java
  • 转:关于函数指针数组与返回数组指针的函数

    源地址:http://blog.chinaunix.net/uid-16875687-id-2155683.html

    int (*a[])(int);
    int (*p())[10];

    第一种情况为数组里面是函数指针的情况,因为(int (*)(int))是一个强制转换方式, 将里面的a[]这个数组转换成了一个函数指针的数组, 并且该函数是一个带一个整型变量,并且返回一个整型的函数.
    第二种情况为函数返回的为指向一个一维数组的指针的情况. 因为(int (*)[10])将其强制转换成了一个指针,而该指针则是一个指向一维数组的指针.
    分别举两个例子进行说明:
    对于第一种函数指针数组的情况,如下:
    #include<stdio.h>
    int fun(int a)
    {
            return a+1;
    }
    int main()
    {
            int (*p[10])(int);
            int i;
            p[0] = fun;
            i = (p[0])(10);
            printf("i=%d ", i);
            return 0;
    }
    p[10]为一个指针数组,而该指针数组里面的值为函数指针类型.让p[0]指向fun()函数.然后再进行调用,就可以调用到fun()这个函数了.

    对于第二种返回数组指针的函数,如下:
    #include<stdio.h>
    #include<stdlib.h>
    int (*p())[10]
    {
     int (*m)[10];
     int i;
     m = (int (*)[10])calloc(10, sizeof(int));
     if (m == NULL)
     {
      printf("calloc error ");
      exit(1);
     }
     for (i = 0; i < 10; i++)
      *(*m+i) = i+1;
     return m;
    }

    int main()
    {
     int (*a)[10];
     int i;
     a = p();
     for (i = 0; i < 10; i++)
      printf("%d ", *(*a+i));
     printf(" done ");
     return 0;
    }

    其实int (*m)[10];这种方式一般是用来指向一个二维数组的,例如
    int b[4][10];
    int (*m)[10] = b;
    其指向二维数组中的一维.
    使用*(*(m+i)+j);这种方式就可以访问b[i][j]这个元素.而上面的是使用这种方式来指向一个一维数组,同样也是一样的.只是前面的*(m+i)中的i变为0了.因为只有一维大小.即
    int a[10];
    int (*m)[10] = &a;
    就使得m指向了a这个数组了.而平时所用的int *p = a;只是让p指向了a的第一个元素.比前面的指向一维数组的指针少了一维.前面的m+1跳过的是10个整型的长度.而后面的p+1则只是跳过了1个整型的长度.

    关于函数指针方面的东西,有下面一个程序,可以加深一下对这方面的理解.如果大家觉得写得不好,请指正.

    #include<stdio.h>
    void f(int i)
    {
            printf("in f() i = %d ", i);
    }
    int main()
    {
            int i;
            void (*ptr)(int);
            printf("%p      %p ", f, *****f);
            f(10);
            (***********f)(30);
            ptr = f;
            ptr(40);
            (ptr)(50);
            (**********ptr)(55);
            i = (unsigned long)f;
            (*(void (*)(int))i)(70);
            ((void (*)(int))i)(90);
            ((void (*)(int))f)(100);
            (*(void (*)(int))f)(120);
            return 0;
    }
    对于这种方式,主要在于C语言中的函数是一种function-to-pointer方式,即对于函数,要将其转化成指针类型的.
    ptr是函数指针类型,则*ptr是该指针所指向的函数,而由于函数自身又转化成指针了,所以说*ptr又转化成了ptr这种函数指针类型,因此,前面无论有多少个*号,最后都是对这个函数的调用.
    而之前的(**f)(30),这种方式,也是与上面分析的一样,函数转化成函数指针,对该函数指针解引用,又得到函数.所以说这种方式也是正确的.
    对于后面的来说,i的值是函数f的地址,前面的(void (*)(int))是一个函数指针的强制转化方式,将该i的值转化成一个函数指针,而该函数指针又是一个带整形参数,且没有返回值的函数.因此((void (*)(int))i)(70)这种方式就是对该函数的一种调用.先将该地址转化成了这种函数指针的方式,然后再去调用,至于最前面的那个*号,可要可不要.所以说两种方式都是正确的.
    对于最后面一种方式,也是先将该函数转化成了一个函数指针,然后又去调用这个函数指针.同样也是调用这个函数了.
    关于函数指针方面的内容,理解起来是比较麻烦,比较郁闷的是以前理解了,后来又搞忘了,不过只要知道怎样去用,用的时候再查一查就没太大问题了.
  • 相关阅读:
    STM32 HAL库学习笔记
    嵌入式Linux学习笔记
    AVR_Interrupt
    shutdown命令用法
    ULINK2 USB电脑无法识别(连接电脑后,设备管理器显示未知设备)
    MDK中编译程序后Program Size详解
    Keil(MDK-ARM)系列教程(三)_工程目标选项配置(Ⅰ)
    第48章 MDK的编译过程及文件类型全解
    Do not access Object.prototype method ‘hasOwnProperty’ from target object no-prototype-builtins
    让vscode按照eslint进行格式化
  • 原文地址:https://www.cnblogs.com/xuhj001/p/3446377.html
Copyright © 2011-2022 走看看