函数指针变量

C语言作为一门面向过程的语言,那么他的代码块一般是以函数为最小单位的,我们了解过栈帧之后都知道,代码也是有地址的,那么存放代码地址的变量就叫做函数指针变量。

对于一个函数而言,函数名或者&函数名都代表的是这个函数的地址。
那么这个地址怎么保存呢?请看下面的代码:

void test()
{
    printf("Hello\n");
}
int main()
{
    void (*p)() = test;
    p();
    (*p)();
    return 0;
}

这样我们就可以使用函数指针p来调用这个函数,在这里有一点比较特殊的地方,我们可以通过*解引用调用,也可以直接用指针名称来调用。

特别强调,函数指针不可以用来做加减运算,我们都知道,指针做加减时,会加上或者减去其指向类型的大小,但是函数的大小计算起来很不方便,而且这样的加减没有意义,所以C语言语法规定不能进行函数指针的加减运算,否则编译器会直接报错!

好了,讲清楚了基本概念,我们来看一点有意思的代码:

//代码1
(*(void (*)())0)();
//代码2
void(*signal(int, void(*)(int)))(int);

来看代码1,先看优先级最高的部分void(*)(),这是一个函数指针,那么给0前面加一个数据类型代表了什么意思呢?当然是把0强制转换成函数指针类型,然后在把他的外壳加上,可以得出结论,这是一个把0强制转换成函数指针的函数调用。

搞明白代码1之后来看代码2。依然是先看优先级void(*)(int)依然是一个函数指针,只是他现在被当成了signal函数的一个参数,另外一个参数当然是int,那么我们就搞清楚了signal(int,void(*)(int))这一部分内容。然后我们省略这一部分去看剩下的,void(*)(int)也是一个函数指针,这个类型自然是用来做函数返回值类型的类型了。所以,这是一个返回值为函数指针,参数为int和函数指针的函数调用。

好了,看了函数指针,你有没有兴趣了解一下函数指针数组呢?很容易可以想到,既然有函数指针,那当然有函数指针数组,那么函数指针数组是什么格式呢?

int (*p[10])(); //名称为p的函数指针数组

学以致用,我们拿这个小东西来写几行代码吧!下面用函数指针数组实现了一个简单的计算器,大家可以参考函数指针数组的基本使用:

int Add(int x, int y)
{
    return x + y;
}

int Sub(int x, int y)
{
    return x - y;
}

int Mul(int x, int y)
{
    return x * y;
}

int Div(int x, int y)
{
    return x / y;
}

int main()
{
    int input = 1;
    int(*p[5])() = { 0, Add, Sub, Mul, Div };//转移表
    while (input)
    {
        printf("请选择操作>:\n");
        printf("******************************\n");
        printf("***  1. Add      2. Sub    ***\n");
        printf("***  3. Mul      4. Div    ***\n");
        printf("***  0. Exit               ***\n");
        printf("******************************\n");
        scanf("%d", &input);
        if (input >= 1 && input <= 4)
        {
            int x, y;
            printf("请输入两个运算数据>:");
            scanf("%d", &x);
            scanf("%d", &y);
            printf("resault:%d\n", (*p[input])(x, y));
        }
        else if (input != 0)
        {
            printf("操作非法,请重新操作\n");
        }
    }
    system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zym1348010959/article/details/79726029