【问题标题】:How can I pass arguments to the function pointer in following code?如何在以下代码中将参数传递给函数指针?
【发布时间】:2016-01-11 10:29:33
【问题描述】:

我尝试了这些代码,但参数 a 和 b 的范围存在一些问题。请有人帮助我。

#include<conio.h>
#include<stdio.h>
int add(int x, int y) {
    return (x + y);
}
void passptr(int( * fp)(int a, int b)) {
    int result = ( * fp)(a, b);
    printf("%d", result);
}
int main() {
    add(3, 5);
    passptr( & add);
    getch();
    return 0;
}

【问题讨论】:

  • 没有ab 参数被传递。您正在传递一个函数指针。
  • 编译器警告是有充分理由的!
  • 您混淆了“命名函数”和“调用函数”的概念。
  • 那是纯C。不要为不相关的语言添加标签。
  • 参数类型中的名称仅供人类阅读,编译器会忽略 - 您的原型等效于void passptr(int (*fp)(int, int))

标签: c function-pointers


【解决方案1】:

如果你typedef你的函数指针,这种调用更容易理解:

#include<conio.h>
#include<stdio.h>

// addFuncPtr_t is a pointer to a function that:
// - returns int
// - takes two int arguments
typedef int ( *addFuncPtr_t )( int, int );

int add(int x, int y) {
    return (x + y);
}
void passptr(addFuncPtr_t fp, int a, int b) {
    int result = fp(a, b);
    printf("%d", result);
}
int main() {
    add(3, 5);

    // note that the function is passed separately from
    // the arguments - add(3,5) would *call* the function
    // instead of passing the address of the function
    passptr( add, 3, 5 );
    getch();
    return 0;
}

【讨论】:

  • 我不确定 typedef 节省了多少打字?还有,main()add(3, 5); 的第一行是做什么的?
  • @DavidC.Rankin 这不是为了节省打字,而是为了帮助理解,因为很明显,当类型变得不透明时,函数指针的参数与passptr的参数无关。跨度>
  • 是的,typedef 将消除在声明 using 函数时使用整个形式函数指针声明作为参数的要求,并且在某种程度上使它更容易理解,但是哇,那是巨无霸:)
  • @DavidC.Rankin main() 的第一行 add(3, 5);这样做? 我只是复制了问题的原始代码,但添加了typedef。你必须问 OP 为什么会这样。使用typedef 不会在此处保存击键,因为它只使用一次,但如果经常使用该类型会有所帮助,尤其是对于更复杂的类型。 typedef 将极大地提高代码的可读性,例如返回复杂函数的指针。
  • @Endra typedef 被定义为一个指针。该代码适用于passptr(add,3,5)passptr(&amp;add,3,5),原因与您可以仅使用数组的未修饰名称传递数组的原因相同:未修饰名称作为地址传递。根据 C Standard 的 6.3.2.1:类型为“返回 type”的函数的函数指示符被转换为类型为“返回 type 的函数的指针”的表达式。 前面的段落涵盖了数组。
【解决方案2】:
void passptr(int (*fp)(int a,int b))
{
    int result=(*fp)(a,b);
    printf("%d",result);
}

ab 这里只是你给函数指针参数的描述性名称,它们不是声明的变量。只需使用有效参数调用函数:

//call with literals
int result = (*fp)(1,2);

//or variables
int a = 1;
int b = 2;
int result = (*fp)(a,b);

//or pass as arguments
void passptr(int (*fp)(int,int), int a, int b) {
    int result = (*fp)(a,b)
}

//and call like this
passptr(&add, 1, 2);

【讨论】:

    【解决方案3】:

    你想要这个:

    void passptr(int (*fp)(int, int), int a, int b)  // corrected argument list
    {
     int result=(*fp)(a,b);
     printf("%d",result);
    }
    int  main()
    {
     add(3,5);              // this is useless leftover from your original code
     passptr(&add, 3, 5);   // added parameters 3 and 5 here
     getch();
     return 0;
    }
    

    在您的void passptr(int( * fp)(int a, int b)) 中,ab 不是passptr 函数的参数,而只是占位符。

    【讨论】:

    • 只是一个提示,add(3,5); 在你上面的代码中做了什么?
    • @DavidC.Rankin 这可能是来自 OP 的剩余测试代码。实际上没有任何目的。
    • 我相当肯定是这样,我只是想确保你知道它在那里,并且在答案中包含无意义的代码可能看起来不是最好的......
    【解决方案4】:

    你可能想试试这个:

    #include<conio.h>
    #include<stdio.h>
    int add(int x, int y) {
        return (x + y);
    }
    void passptr(int( * fp)(int a, int b)) {
        int result = ( * fp)(3, 5);
        printf("%d", result);
    }
    int main() {
        add(3, 5);
        passptr( & add);
        getch();
        return 0;
    }
    

    【讨论】:

    • 你在passptr()中使用ab做什么?
    【解决方案5】:

    如果您使用 C++,使用模板会简单得多:

    #include<conio.h>
    #include<stdio.h>
    int add(int x, int y) {
        return (x + y);
    }
    
    template<typename funcPtr>
    void passptr(funcPtr f,int a, int b) {
        int result = f(a, b);
        printf("%d", result);
    }
    int main() {
        passptr(add,3,5);
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-26
      • 2016-11-07
      • 2017-04-18
      • 2012-10-15
      • 1970-01-01
      • 1970-01-01
      • 2021-07-18
      相关资源
      最近更新 更多