• 关于C的函数指针总结


    函数指针是指向函数的指针变量
      因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如前所述,C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上一致的。函数指针有两个用途:调用函数和做函数的参数。函数指针的说明方法为: 
      数据类型标志符 (指针变量名)(形参列表);
      注1:“函数类型”说明函数的返回类型,由于“()”的优先级高于“*”,所以指针变量名外的括号必不可少,后面的“形参列表”表示指针变量指向的函数所带的参数列表。例
      int func(int x); /* 声明一个函数 */
      int (*f) (int x); /* 声明一个函数指针 */
      f=func; /* 将func函数的首地址赋给指针f */
      赋值时函数func不带括号,也不带参数,由于func代表函数的首地址,因此经过赋值以后,指针f就指向函数func(x)的代码的首地址。
      注2:函数括号中的形参可有可无,视情况而定。 
      下面的程序说明了函数指针调用函数的方法: 
      例一、

      #include<stdio.h>
      int max(int x,int y){ return(x>y?x:y); }
      void main()
      {
      int (*ptr)(int, int);
      int a,b,c;
      ptr=max;
      scanf("%d,%d",&a,&b);
      c=(*ptr)(a,b);
      printf("a=%d,b=%d,max=%d",a,b,c);
      }


      ptr是指向函数的指针变量,所以可把函数max()赋给ptr作为ptr的值,即把max()的入口地址赋给ptr,以后就可以用ptr来调用该函数,实际上ptr和max都指向同一个入口地址,不同就是ptr是一个指针变量,不像函数名称那样是死的,它可以指向任何函数,就看你像怎么做了。在程序中把哪个函数的地址赋给它,它就指向哪个函数。而后用指针变量调用它,因此可以先后指向不同的函数,不过注意,指向函数的指针变量没有++和--运算,用时要小心。 
      不过,在某些编译器中这是不能通过的。这个例子的补充如下。
      应该是这样的: 
      1.定义函数指针类型: 
      typedef int (*fun_ptr)(int,int); 
      2.申明变量,赋值: 
      fun_ptr max_func=max; 
      也就是说,赋给函数指针的函数应该和函数指针所指的函数原型是一致的。
      例二、

      #include<stdio.h>
      void FileFunc()
      {
      printf("FileFunc\n");
      }
      void EditFunc()
      {
      printf("EditFunc\n");
      }
      void main()
      {
      void (*funcp)();
      funcp=FileFunc;
      (*funcp)();
      funcp=EditFunc;
      (*funcp)();
      }


      指针函数和函数指针的区别
      1,这两个概念都是简称,指针函数是指带指针的函数,即本质是一个函数。我们知道函数都又有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。
      其定义格式如下所示: 
      返回类型标识符 *返回名称(形式参数表) 
      { 函数体 } 
      返回类型可以是任何基本类型和复合类型。返回指针的函数的用途十分广泛。事实上,每一个函数,即使它不带有返回某种类型的指针,它本身都有一个入口地址,该地址相当于一个指针。比如函数返回一个整型值,实际上也相当于返回一个指针变量的值,不过这时的变量是函数本身而已,而整个函数相当于一个“变量”。例如下面一个返回指针函数的例子: 
     

     #include<iostream>
      using namespace std;
      void main()
      {
      float *find(float(*pionter)[4],int n);
      static float score[][4]={{60,70,80,90},{56,89,34,45},{34,23,56,45}};
      float *p;
      int i,m;
      cout<<"Enter the number to be found:";
      cin>>m;
      p=find(score,m);
      for(i=0;i<4;i++)
      cout<<""<<*(p+i);
      }
      float *find(float(*pionter)[4],int n)/*定义指针函数*/
      {
      float *pt;
      pt=*(pionter+n);
      return(pt);
      }


      学生学号从0号算起,函数find()被定义为指针函数,起形参pointer是指针指向包含4个元素的一维数组的指针变量。pointer+1指向 score的第一行。*(pointer+1)指向第一行的第0个元素。pt是一个指针变量,它指向浮点型变量。main()函数中调用find()函数,将score数组的首地址传给pointer. 
      2,“函数指针”是指向函数的指针变量,因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如前所述,C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上一致的。函数指针有两个用途:调用函数和做函数的参数。
      函数指针的说明方法为: 
      数据类型标志符 (*指针变量名)(参数);
      注1:函数括号中的参数可有可无,视情况而定。下面的程序说明了函数指针调用函数的方法: 

      #include 
      int max(int x,int y){ return(x>y?x:y); }
      void main()
      {
      int (*ptr)();
      int a,b,c;
      ptr=max;
      scanf("%d,%d",&a,&b);
      c=(*ptr)(a,b);
      printf("a=%d,b=%d,max=%d",a,b,c);
      }


      ptr是指向函数的指针变量,所以可把函数max()赋给ptr作为ptr的值,即把max()的入口地址赋给ptr,以后就可以用ptr来调用该函数,实际上ptr和max都指向同一个入口地址,不同就是ptr是一个指针变量,不像函数名称那样是死的,它可以指向任何函数,就看你像怎么做了。在程序中把 哪个函数的地址赋给它,它就指向哪个函数。而后用指针变量调用它,因此可以先后指向不同的函数,不过注意,指向函数的指针变量没有++和--运算,用时要小心。
      关于函数指针数组的定义
      关于函数指针数组的定义方法,有两种:一种是标准的方法;一种是蒙骗法。
      第一种,标准方法:
      { 
      分析:函数指针数组是一个其元素是函数指针的数组。那么也就是说,此数据结构是是一个数组,且其元素是一个指向函数入口地址的指针。 
      根据分析:首先说明是一个数组:数组名[] 
      其次,要说明其元素的数据类型指针:*数组名[]. 
      再次,要明确这每一个数组元素是指向函数入口地址的指针:函数返回值类型 (*数组名[])().请注意,这里为什么要把“*数组名[]”用括号扩起来呢?因为圆括号和数组说明符的优先级是等同的,如果不用圆括号把指针数组说明表达式扩起来,根据圆括号和方括号的结合方向,那么 *数组名[]() 说明的是什么呢?是元素返回值类型为指针的函数数组。有这样的函数数祖吗?不知道。所以必须括起来,以保证数组的每一个元素是指针。
      }
      第二种,蒙骗法:
      尽管函数不是变量,但它在内存中仍有其物理地址,该地址能够赋给指针变量。获取函数方法是:用不带有括号和参数的函数名得到。
      函数名相当于一个指向其函数入口指针常量。 那么既然函数名是一个指针常量,那么就可以对其进行一些相应的处理,如强制类型转换。 
      那么我们就可以把这个地址放在一个整形指针数组中,然后作为函数指针调用即可。
      完整例子:
     

     #include "stdio.h"
      int add1(int a1,int b1);
      int add2(int a2,int b2);
      void main()
      {
      int numa1=1,numb1=2;
      int numa2=2,numb2=3;
      int (*op[2])(int a,int b);
      op[0]=add1;
      op[1]=add2;
      printf("%d %d\n",op[0](numa1,numb1),op[1](numa2,numb2));
      }
      int add1(int a1,int b1)
      {
      return a1+b1;
      }
      int add2(int a2,int b2)
      {
      return a2+b2;
      }


      再给出常用的C变量的定义方式:
      a) 一个整型数(An integer) 
      b) 一个指向整型数的指针(A pointer to an integer) 
      c) 一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer to an integer) 
      d) 一个有10个整型数的数组(An array of 10 integers) 
      e) 一个有10个指针的数组,该指针是指向一个整型数的(An array of 10 pointers to integers) 
      f) 一个指向有10个整型数数组的指针(A pointer to an array of 10 integers) 
      g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer) 
      h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer )
      答案是: 

      a) int a; // An integer 
      b) int *a; // A pointer to an integer
      c) int **a; // A pointer to a pointer to an integer
      d) int a[10]; // An array of 10 integers
      e) int *a[10]; // An array of 10 pointers to integers
      f) int (*a)[10]; // A pointer to an array of 10 integers
      g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer
      h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an intege



  • 相关阅读:
    .NET 动态脚本语言
    webParts与Web部件
    比较JqGrid与XtraGrid
    XtraGrid滚轮翻页
    Python------继承
    Python 私有化类的属性
    Python print 输出不换行,只有空格
    Python--函数参数类型
    手推FP-growth (频繁模式增长)算法------挖掘频繁项集
    Python 返回多个值+Lambda的使用
  • 原文地址:https://www.cnblogs.com/lyp3314/p/2265716.html
Copyright © 2020-2023  润新知