首页 文章

是否可以在C中增加函数指针

提问于
浏览
3

我有以下代码,我得到分段错误,因为我的函数指针指向一个函数指针数组,并且在函数指针的增量未指向函数指针数组中的下一个元素之后 .

int f2(int);
int f1(int);
int(*fp[2])(int) = {f1,f2};

int f1(int x)
{
return (x+10);
}


int f2(int y)
{
return (y+20);
}

int main() {
    int sum = 0;
    int (*fp1) (int);

    fp1 = fp;
    printf("addr of fp1 is %x\n",fp1);
    ++(fp1);
    printf("after increment addr of fp1 is %x\n",fp1);
    sum = (*fp1)(sum);
        printf("%d \n",sum);
        return 0;
    }

但是,当我使用指向函数指针的指针时,如:

int(** fp1)(int);然后代码工作正常 . 请告诉:

1-为什么只是函数指针不起作用 .

2指向函数的指针,即fp1仅在执行fp1时将地址递增1 .

3-当我通过fp1 = fp [0];那么它也不能同时使用指向函数的指针...以及指向函数的指针 . fp和fp [0]指向不同的地址吗?

4 回答

  • 2

    Pointers to functions

    递增和递减运算符对于指向函数的指针无效 .

    以下是C标准草案(N3337)的相关文字:

    5.3.2递增和递减1前缀的操作数通过添加1来修改,或者如果它是bool则设置为true(不推荐使用此用法) . 操作数应是可修改的左值 . 操作数的类型应为算术类型或指向完全定义的对象类型的指针 . 该值是操作数的新值;这是一个左值 . 如果x不是bool类型,则表达式x等于x = 1 .

    指向函数的指针的类型既不是算术类型,也不是指向完全定义的对象类型的指针 . 因此, ++ 不能应用于指向函数的指针 .

    就C而言,C99标准(n1256)说:

    6.5.3.1前缀递增和递减运算符1前缀递增或递减运算符的操作数应具有限定或不合格的实数或指针类型,并且应为可修改的左值 . 2前缀运算符的操作数的值递增 . 结果是增量后操作数的新值 . 表达式E等于(E = 1) . 有关约束,类型,副作用和转换以及操作对指针的影响的信息,请参阅加法运算符和复合赋值的讨论 .

    6.5.6加法运算符2另外,两个操作数都应具有算术类型,或者一个操作数应为指向对象类型的指针,另一个操作数应为整数类型 . (递增相当于添加1.)

    同样,由于相同的原因,指向函数的指针不能递增 .

    Array of pointers to functions / Pointers to pointers to functions

    这条线

    int(*fp[2])(int) = {f1,f2};
    

    声明一个指向函数的指针数组 . 因此,表达式 fp[0]fp[1] 是有效的表达式 . 您可以指向指向函数对象的指针,该指针与increment运算符一起使用 .

    int (**fpp)(int) = fp;
    (*fpp)(10);  // Calls f1(10)
    fpp[0](10);  // Calls f1(10)
    fpp[1](10);  // Calls f2(10)
    ++fpp;
    (*fpp)(20);  // Calls f2(20)
    fpp[0](20);  // Calls f2(20)
    

    不幸的是,gcc 4.7.3允许编译以下语句,而g则不允许 .

    int(*fp[2])(int) = {f1,f2};
    int (*fpp)(int) = fp;
    

    调用

    fpp(10);
    

    在这种情况下导致未定义的行为 .

  • 1

    fp1 被定义为 int (*fp1) (int); 这是 NOT 指向函数指针数组的指针 . 它是一个指向函数的指针 . 你 can't 增加它 .

    但是,您可以/应该增加指向数组元素的指针:

    int (**fp_array)(int) = fp;
    
    fp1 = *fp_array;
    printf("addr of fp1 is %x\n",fp1);
    fp1 = *(++fp_array);
    printf("after increment addr of fp1 is %x\n",fp1);
    

    但在这种情况下,这是无稽之谈,为什么不简单地写:

    fp1 = fp[0];
    printf("addr of fp1 is %x\n",fp1);
    fp1 = fp[1];
    printf("after `increment` addr of fp1 is %x\n",fp1);
    
  • 5

    只是为了添加已经回答你问题的给定响应,我想建议你输入dede函数类型:

    typedef int function(int);
    function* fp[] = { &f1, &f2};
    function** f = fp; // array-to-pointer decay
    

    f 现在可以按照预期的方式递增 .

  • 3

    你试图做的是可能的 . 但是,这显然很棘手,或者你不会在这里发帖 .

    使用索引到数组fp更简单 .

    int i = 0;
    printf ("First result = %d\n", (* (fp [i++])) (10));
    printf ("Second result = %d\n", (* (fp [i++])) (10));
    

    这样,读取代码的人就有机会弄清楚它的作用 .

相关问题