`
hcmfys
  • 浏览: 356429 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

函数指针和指针函数以及函数指针数组

阅读更多
问题:一个整型a,根据a的值执行相应的代码

我的回答是使用switch case
面试官说可以这样做,但是还有速度更快的办法,但是他没说是什么办法...只提到了一下指针阿数组什么地,没听清。

想请教一下,他说的更快的办法是什么办法?

------------------------------------------------------------------------------------

关于函数指针数组的定义


关于函数指针数组的定义方法,有两种:一种是标准的方法;一种是蒙骗法。

第一种,标准方法:

{ 
分析:函数指针数组是一个其元素是函数指针的数组。那么也就是说,此数据结构是是一个数组,且其元素是一个指向函数入口地址的指针。 
根据分析:首先说明是一个数组:数组名[] 
其次,要说明其元素的数据类型指针:*数组名[]. 
再次,要明确这每一个数组元素是指向函数入口地址的指针:函数返回值类型 (*数组名[])().请注意,这里为什么要把“*数组名[]”用括号扩起来呢?因为圆括号和数组说明符的优先级是等同的,如果不用圆括号把指针数组说明表达式扩起来,根据圆括号和方括号的结合方向,那么 *数组名[]() 说明的是什么呢?是元素返回值类型为指针的函数数组。有这样的函数数祖吗?不知道。所以必须括起来,以保证数组的每一个元素是指针。

}

第二种,蒙骗法:

尽管函数不是变量,但它在内存中仍有其物理地址,该地址能够赋给指针变量。获取函数方法是:用不带有括号和参数的函数名得到。
函数名相当于一个指向其函数入口指针常量。 那么既然函数名是一个指针常量,那么就可以对其进行一些相应的处理,如强制类型转换。 
那么我们就可以把这个地址放在一个整形指针数组中,然后作为函数指针调用即可。


完整例子:
#include "stdio.h"
int add1(int a1,int b1);

int add2(int a2,int b2);

int main(int argc,char* argv[])

{

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

getch();

}

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 integer




函数指针数组的妙用

         笔者在开发某软件过程中遇到这样一个问题,前级模块传给我二进制数据,输入参数为 char* buffer和 int length,buffer是数据的首地址,length表示这批数据的长度。数据的特点是:长度不定,类型不定,由第一个字节(buffer[0])标识该数据的类型,共有256(28 )种可能性。我的任务是必须对每一种可能出现的数据类型都要作处理,并且我的模块包含若干个函数,在每个函数里面都要作类似的处理。若按通常做法,会写出如下代码:

void MyFuntion( char* buffer, int length )
{
    __int8 nStreamType = buffer[0];

    switch( nStreamType )
    {
       case 0:
           function1();
           break;
       case 1:
       ......
       case 255:
           function255();
           break;
     }
}        如果按照这种方法写下去,那么在我的每一个函数里面,都必须作如此多的判断,写出的代码肯定很长,并且每一次处理,都要作许多次判断之后才找到正确的处理函数,代码的执行效率也不高。针对上述问题,我想到了用函数指针数组的方法解决这个问题。

  函数指针的概念,在潭浩强先生的C语言程序设计这本经典的教程中提及过,在大多数情况下我们使用不到,也忽略了它的存在。函数名实际上也是一种指针,指向函数的入口地址,但它又不同于普通的如int*、double*指针,看下面的例子来理解函数指针的概念:
int funtion( int x, int y );
void main ( void )
{
   int (*fun) ( int x, int y );
   int a = 10, b = 20;
   function( a, b );
   fun = function;
   (*fun)( a, b );
    ……
}
  语句1定义了一个函数function,其输入为两个整型数,返回也为一个整型数(输入参数和返回值可为其它任何数据类型);语句3定义了一个函数指针,与int*或double*定义指针不同的是,函数指针的定义必须同时指出输入参数,表明这是一个函数指针,并且*fun也必须用一对括号括起来;语句6将函数指针赋值为funtion,前提条件是*fun和function的输入参数和返回值必须保持一致。语句5直接调用函数function(),语句7是调用函数指针,二者等效。

  当然从上述例子看不出函数指针的优点,目的主要是想引出函数指针数组的概念。我们从上面例子可以得知,既然函数名可以通过函数指针加以保存,那们也一定能定义一个数组保存若干个函数名,这就是函数指针数组。正确使用函数指针数组的前提条件是,这若干个需要通过函数指针数组保存的函数必须有相同的输入、输出值。
这样,我工作中所面临的问题可以解决如下:

首先定义256个处理函数(及其实现)。

void funtion0( void );
……
void funtion255(void );

其次定义函数指针数组,并给数组赋值。
void (*fun[256])(void);

fun[0] = function0;
……
fun[255] = function();
最后,MyFunction()函数可以修改如下:

void MyFuntion( char* buffer, int length )
{
    __int8 nStreamType = buffer[0];
    (*fun[nStreamType])();
}

  只要2行代码,就完成了256条case语句要做的事,减少了编写代码时工作量,将nStreamType作为数组下标,直接调用函数指针,从代码执行效率上来说,也比case语句高。假如多个函数中均要作如此处理,函数指针数组更能体现出它的优势。
函数指针与typedef
关于C++中函数指针的使用(包含对typedef用法的讨论)
(一)简单的函数指针的应用。
//形式1:返回类型(*函数名)(参数表)
char (*pFun)(int);
char glFun(int a){ return;}
void main()
{
    pFun = glFun;
    (*pFun)(2);
}
       第一行定义了一个指针变量pFun。首先我们根据前面提到的“形式1”认识到它是一个指向某种函数的指针,这种函数参数是一个int型,返回值是char类型。只有第一句我们还无法使用这个指针,因为我们还未对它进行赋值。
      第二行定义了一个函数glFun()。该函数正好是一个以int为参数返回char的函数。我们要从指针的层次上理解函数——函数的函数名实际上就是一个指针,函数名指向该函数的代码在内存中的首地址。
        然后就是可爱的main()函数了,它的第一句您应该看得懂了——它将函数glFun的地址赋值给变量pFun。main()函数的第二句中“*pFun”显然是取pFun所指向地址的内容,当然也就是取出了函数glFun()的内容,然后给定参数为2。
(二)使用typedef更直观更方便。
//形式2:typedef 返回类型(*新类型)(参数表)
typedef char (*PTRFUN)(int);
PTRFUN pFun;
char glFun(int a){ return;}
void main()
{
    pFun = glFun;
    (*pFun)(2);
}
        typedef的功能是定义新的类型。第一句就是定义了一种PTRFUN的类型,并定义这种类型为指向某种函数的指针,这种函数以一个int为参数并返回char类型。后面就可以像使用int,char一样使用PTRFUN了。
        第二行的代码便使用这个新类型定义了变量pFun,此时就可以像使用形式1一样使用这个变量了。
(三)在C++类中使用函数指针。
//形式3:typedef 返回类型(类名::*新类型)(参数表) 
class CA
{
public:
    char lcFun(int a){ return; }
};
CA ca;
typedef char (CA::*PTRFUN)(int);
PTRFUN pFun;
void main()
{
    pFun = CA::lcFun;
    ca.(*pFun)(2);
}
        在这里,指针的定义与使用都加上了“类限制”或“对象”,用来指明指针指向的函数是哪个类的,这里的类对象也可以是使用new得到的。比如:
CA *pca = new CA;
pca->(*pFun)(2);
delete pca;
        而且这个类对象指针可以是类内部成员变量,你甚至可以使用this指针。比如:
        类CA有成员变量PTRFUN m_pfun;
void CA::lcFun2()
{ 
   (this->*m_pFun)(2);
}
         一句话,使用类成员函数指针必须有“->*”或“.*”的调用。在调用动态库时,习惯用typedef重新定义动态库函数中的函数地址(函数指针),如在动态库(test.dll)中有如下函数:
      int   DoCase(int, long);

则,在调用动态库是有两种方法:

1. 先声明一个与动态库中类型一致的指针函数变量:

        int (*DOCASE)(int ,long);//用于指向动态库中的DoCase函数地址

         HINSTANCE gLibMyDLL = NULL;

       gLibMyDLL = LoadLibrary("test.dll");

       if(gLibMyDLL != NULL)

         {

                   //得到函数地址

                     DOCASE = (int(*)(int,long))GetProcAddress(gLibMyDLL, "DoCase");

          }  

         //调用函数

         int s = DOCASE(1,1000);

    2.用typedef定义一个指针函数:typedef (*DOCASE)(int ,long);

         HINSTANCE gLibMyDLL = NULL;

        DOCASE _docase;

       gLibMyDLL = LoadLibrary("test.dll");

      if(gLibMyDLL != NULL)

          {

                _docase = (DOCASE)GetProcAddress(gLibMyDll, "DoCase");

         }

      //调用函数

      int s=_docase(1,1000);
分享到:
评论

相关推荐

    彻底理解指针,指针数组和数组指针,指针函数和函数指针

    ### 彻底理解指针,指针数组和数组指针,指针函数和函数指针 #### 一、基础知识 在计算机编程中,指针是一个非常重要的概念,尤其是在C/C++这样的语言中更是如此。简单来说,指针是一种变量,但它存储的不是普通的...

    函数指针与函数指针数组,多层

    在这个例子中,我们看到如何使用函数指针以及多层函数指针数组。 首先,`Drive`函数接受三个参数:目标距离`_distance`、现有燃油`hasoil`和一个名为`engine`的函数指针。函数指针`engine`指向一个接受整型燃油`oil...

    指针进阶之函数指针和函数指针数组

    函数指针和函数指针数组 函数指针是一种特殊的指针,它是指向函数的指针。函数指针可以用来存放函数的地址,并且可以通过函数指针来调用函数。 1. 简单介绍 函数指针是指向函数的指针,它可以用来存放函数的地址...

    彻底了解指针数组,数组指针以及函数指针

    ### 彻底了解指针数组、数组指针以及函数指针 #### 一、指针与内存分配...通过上述介绍,我们可以看到指针数组、数组指针以及函数指针在C语言中的重要性和灵活性。熟练掌握这些概念对于编写高效、灵活的代码至关重要。

    指针, 指针的指针, 数组, 指针数组, 数组指针, 指针函数, 函数指针 CC++中函数指针的含义

    9. **typedef 和函数指针**: `typedef` 关键字可以用来定义新的类型别名,使得函数指针的定义更加简洁。例如,`typedef int (*fp)(int a);` 定义了一个名为 `fp` 的类型,代表了接受一个整数参数并返回整数的函数...

    c++函数数组指针的使用方法

    本文将详细介绍如何在C++中使用函数指针以及函数数组指针,特别是如何通过这些技术来减少代码量、提高代码的复用性和可读性。 #### 函数指针基础 函数指针是指向函数的指针变量。它们可以存储函数的地址,并且可以...

    多线程函数指针数组.rar

    函数指针本质上是一个指向函数的指针变量,可以像操作普通数据一样操作它,包括赋值、传递和调用。在多线程环境中,函数指针常用于创建线程时指定线程的入口点,即线程开始执行的函数。通过函数指针数组,我们可以...

    函数指针数组

    接下来是一个更复杂的示例,涉及到多级指针以及函数指针数组的使用: ```cpp char*(*(*pf)[3])(char *p); ``` 这段代码定义了一个多层嵌套的指针类型`pf`。这里`pf`是一个指向一个包含三个元素的数组的指针,每个...

    C语言指针数组函数笔记

    "C语言指针数组函数笔记" ...本笔记总结了C语言中的指针和数组相关知识点,涵盖了变量、指针变量、指针运算符、数组和指针数组函数等内容。通过阅读本笔记,读者可以更好地理解和应用C语言中的指针和数组。

    函数指针数组的妙用

    在此基础上,我们可以创建函数指针数组,即一个数组中存储多个函数指针,这些函数具有相同的参数列表和返回类型。函数指针数组能够根据不同的条件或需求,动态地选择调用不同的函数,极大地提高了代码的灵活性和效率...

    函数指针数组示例

    C语言中对函数指针数组不是很了解,老师最近布置了一个作业,就搜集资料写了一个,希望能给大家启发,如果对C语言复杂指针的分析不是很懂得话,可以网上搜索“右左法则”

    【C语言指针】深入浅出:指针与取值、数组、函数; 详细剖析:指针函数、函数指针、指针数组、数组指针、双重指针、指针与动态内存分配

    详细剖析:指针函数、函数指针、指针数组、数组指针、双重指针、指针与动态内存分配 个人总结要点: 本质: 地址要用指针来存储,指针是用来存储地址的!!! 重难点: 指针指向的地址,也就是指针存储的地址!!...

    自己整理的经典程序,数组,指针,函数那是相当有用

    自己整理的经典程序,数组,指针,函数那是相当有用

    数组指针,函数指针应用

    在C/C++编程语言中,数组和指针是两个核心概念,它们的结合以及与函数指针的交互能实现强大的功能。本主题将深入探讨数组指针和函数指针的应用,通过提供的源代码实例,我们可以更好地理解这两种概念的实用性和灵活...

    C++指针——数组指针/函数指针

    本篇文章将深入探讨两种特殊的指针类型:数组指针和函数指针。这两种类型的指针在处理数据集合和调用函数时具有显著的优势。 首先,让我们了解数组指针。在C++中,数组本质上是一系列相同类型的数据元素的连续存储...

    函数指针和指针函数的区别

    在C/C++编程语言中,函数指针和指针函数是两个不同的概念,虽然它们都涉及到指针和函数,但其用法和含义各有特点。理解这两者的差异对于编写高效、灵活的代码至关重要。 首先,我们来解释"函数指针"。函数指针是一...

    数组与指针区别(很全面)

    本文旨在澄清关于数组名是否等同于指针这一常见的误区,并通过具体的代码示例来深入探讨数组和指针之间的关系及其差异。 #### 二、数组与指针的基本概念 1. **数组**: - 数组是一系列相同类型的数据项的集合。 ...

    函数指针和函数指针数组的使用

    函数指针和函数指针数组的使用 函数指针和函数指针数组是C语言程序设计中的一种重要概念,它们可以解决实际程序编写过程中的多种情况问题。在本文中,我们将介绍函数指针和函数指针数组的概念、定义、使用方法,并...

    C语言中指针、数组和函数的综合应用与实例解析.pdf

    C语言中指针、数组和函数的综合应用与实例解析 本文对C语言中指针、数组和函数的概念、运算和应用进行了详细的探讨和分析。指针是C语言的重要特色,是一种特殊的数据类型,通过存储空间的地址或编号来访问数据。...

    指针函数和函数指针变量

    函数指针的声明需要包括函数的返回类型、参数列表以及函数名前的星号。例如: ```c void print_message(char *); void (*func_ptr)(char *) = print_message; // 声明并初始化一个函数指针变量 func_ptr("Hello"); ...

Global site tag (gtag.js) - Google Analytics