一点也不神秘的函数的指针

/ 1评 / 0

大家都知道指针就是东西的地址.变量有指针,函数也有.而且很巧妙.
看一个简单例子.

#include <stdio.h>
int testfunc(int a)
{
    printf("My a = %d", a);
}
int main()
{
    int (*myfunc)(int) = testfunc;
    myfunc(5);
    return 0;
}
~

结果就是执行了testfunc,并且传入了5.好像这挺无聊的,看不出什么优势.如果是多个一组函数呢.

#include <stdio.h>
int test1(int a)
{
    printf("My a = %d
", a);
}
int test2(int b)
{
    printf("My b = %d
", b);
}
int main()
{
    int (*myfunc[2])(int) = {test1, test2};
    (myfunc[0])(5);
    (myfunc[1])(5);
    return 0;
}

我相信你已经看得出声明格式了.

#include <stdio.h>
int test1(int a, int b)
{
    printf("My a = %d
", a + b);
}
int test2(int c, int d)
{
    printf("My b = %d
", c * d);
}
int main()
{
    int (*myfunc[2])(int, int) = {test1, test2};
    (myfunc[0])(5, 4);
    (myfunc[1])(5, 4);
    return 0;
}

来个复杂的,这个应该知道结果了吧.
My a = 9
My b = 20
好的,那么继续.不知道具体类型怎么办.那就void.void兼容性是一流的.但是,void一定要指针方式传入,否则是incomplete type,另外void是万能类型,需要转化.

#include <stdio.h>
int test1(void *a, void *b)
{
    printf("My a = %d
", *(int *)a + * (int *)b);
}
int test2(void *c, void *d)
{
    printf("My b = %d
", *(int *)c * *(int *)d);
}
int main()
{
    int val1 = 5;
    int val2 = 10;
    int (*myfunc[2])(void *, void *) = {test1, test2};
    (myfunc[0])(&val1, &val2);
    (myfunc[1])(&val1, &val2);
    return 0;
}

我们用int *转换了void类型,使得变量成为int *,然后用*取出真内容,因为我们用&传进去了一个地址.所以要*取出.
如果要加修饰符,怎么办呢.直接加就是了.

#include <stdio.h>
int test1(const void *a, const void *b)
{
    printf("My a = %d
", *(int *)a + * (int *)b);
}
int test2(const void *c, const void *d)
{
    printf("My b = %d
", *(int *)c * *(int *)d);
}
int main()
{
    int val1 = 5;
    int val2 = 10;
    int (*myfunc[2])(const void *, const void *) = {test1, test2};
    (myfunc[0])(&val1, &val2);
    (myfunc[1])(&val1, &val2);
    return 0;
}

既然void是万能的,那么字符串呢?先复习下基本main函数的样子.

#include <stdio.h>
int main(int argc,char *argv[]){
}

其中argv是字符串的数组,而数组又是指针,也就是char b[] ≈ char *b(区别只差在是否申请了空间,都是字符串),那么实际上可以写char **argv,就是字符串数组的指针了.(当然,很拗口的读法是字符串指针[数组越≈指针]的指针).如果一个不小心,就会发生Segmentation fault.我到群里随便问了下,有人答案是这样的.

int test1(const void *a, const void *b)
{
    if(strcmp((*(char **)a, *(char **)b))
{
    printf("a bigger than b
");
    }
    else
    {
        printf("b bigger than a
");
    }
}

想得太复杂不说,实际上很简单啊.

int test1(const void *a, const void *b)
{
    if(strcmp((char *)a, (char *)b))
    {
        printf("a bigger than b
");
    }
    else
    {
        printf("b bigger than a
");
    }
}

因为strcmp已经是传入const char *了,所以...
但是,我们现在依然一个一个调用,好像没有体验出优势啊.实际上,函数也可以作为参数,传递进别的函数里面.
 

  1. 叶子说道:

    函数指针我习惯上用来做动态的驱动加载。我觉得这样,我就可以同时准备多个驱动,然后动态切换了。从整个程序上看,就变成修改硬件的时候,我只需要更改下驱动函数的指针的值。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注