在C语法中返回指å‘函数的指针

时间:2016-11-10 23:31:01

标签: c pointers syntax

在How do function pointers in C work?的答案之一中,一个用户解释了如何在返回值中使用函数指针。这是相关代ç ï¼š

// this is a function called functionFactory which receives parameter n
// and returns a pointer to another function which receives two ints
// and it returns another int

int (*functionFactory(int n))(int, int) {
    printf("Got parameter %d", n);
    int (*functionPtr)(int,int) = &addInt;
    return functionPtr;
}

对我æ¥è¯´ï¼Œå£°æ˜ŽfunctionFactory函数的方å¼éžå¸¸å¥‡æ€ª - 在我看æ¥ä½ æ··æ·†äº†è¿”回类型(指å‘函数的指针)和函数å本身(functionFactory)。

例如,当我们编写一个返回其å‚数的平方的简å•å‡½æ•°æ—¶ï¼Œæˆ‘们编写类似

的东西
int square(int n){
    return n*n;
}

显然,我们返回的类型在左侧,然åŽæˆ‘们编写函数å称,然åŽå†™å…¥å®ƒæŽ¥å—çš„å‚数。因此,当我们返回指å‘函数的指针时,为什么我们ä¸å†™ä¸‹è¿™æ ·çš„内容:

( int (*function)(int, int) ) functionFactory(int n) { ...

这里的返回类型(它是一个函数的指针)åŠå…¶ç»†èŠ‚(例如我们指å‘的函数返回以åŠå®ƒä½œä¸ºå‚数接å—的内容)显然ä½äºŽå·¦ä¾§ï¼Œå¹¶ä¸”函数å称函数本身在å³è¾¹ã€‚对我æ¥è¯´ï¼Œæˆ‘的版本似乎更符åˆé€»è¾‘和清晰,为什么我们ä¸è¿™æ ·å†™å‘¢ï¼Ÿ

2 个答案:

答案 0 :(得分:2)

è¿™ä¸ç¬¦åˆå£°æ˜Žå™¨è¯­æ³•çš„工作原ç†ã€‚在替代方é¢è€ƒè™‘å¯èƒ½ä¼šæœ‰æ‰€å¸®åŠ©ã€‚这是一ç§çœ‹å¾…它的方法:

T    f   (); // f is a function returning T
     |
     v
T  (*p)  (); // p is a pointer to a function returning T
     |
     v
T  (*q())(); // q is a function returning a pointer to a function returning T

所以我们从函数声明符f()开始。然åŽæˆ‘们用指针f替æ¢(*p),为我们æ供声明符(*p)()。最åŽï¼Œæˆ‘们使用函数p替æ¢q(),为我们æ供声明符(*q())()。

修改

在阅读毛茸茸的宣言员时,你å¯èƒ½ä¼šå¬åˆ°äººä»¬è°ˆè®ºâ€œèžºæ—‹è§„则â€ã€‚虽然它更åƒæ˜¯æŒ‡å¯¼è€Œéžå®žé™…规则,但它ä¸ç¬¦åˆä»¥ä¸‹ä¼˜å…ˆè§„则:

T *a[N];    // a is an array of pointer to T
T (*a)[N];  // a is a pointer to an array of T
T *f();     // f is a function returning T
T (*f)();   // f is a pointer to a function returning T

åŽç¼€[]å’Œ()è¿ç®—符的优先级高于一元*,因此在声明指å‘数组或函数的指针时需è¦æ‹¬å·ã€‚因此,当我们阅读T (*q())();时,我们从最左边的标识符q和“螺旋â€å‘外开始:

    +-----------+
    | +-------+ |
    | | +---+ | |         
    | | |   | | |
    T ( * q ()) ()
      | | | | | |
      | | +-+ | |
      | +-----+ |    
      +---------+

一点一点地打破它:

    q        -- q is a
    q()      -- function returning
   *q()      -- pointer to
  (*q())()   -- function returning
T (*q())();  -- T

ä½ ä¸èƒ½å£°æ˜Žå‡½æ•°ç±»åž‹çš„数组,也ä¸èƒ½å£°æ˜Žå‡½æ•°è¿”回数组类型:

T a[N]();    // NOT ALLOWED 
T f()[N];    // NOT ALLOWED 

因此,在函数和数组类型的任æ„组åˆä¸­ï¼Œå°†å§‹ç»ˆæ¶‰åŠæŒ‡é’ˆï¼Œå› æ­¤èžºæ—‹è§„则æˆç«‹ã€‚

答案 1 :(得分:1)

以下代ç å°†å为funcçš„å˜é‡å£°æ˜Žä¸ºæŒ‡å‘函数的指针,该函数返回int并将两个int作为å‚数:

int (*func)(int, int);

此语法模仿了如何在C:

中声明函数的语法
int func(int, int);

看看有多相似?事实上,C中的函数就åƒæŒ‡å‘函数的å˜é‡ï¼Œä¾‹å¦‚看这个样本:

int funcA(int a, int b) { ... }
int (*funcB)(int, int) = funcA;

如果您拨打funcA(a,b)或funcB(a,b),它在其余代ç ä¸­ä¸èµ·ä½œç”¨ï¼Œæ˜¯å—?所以尽管funcB是一个å˜é‡è€ŒfuncA是一个函数,但事实是,在内存中有一个函数,而funcAå’ŒfuncB都是指å‘它的指针。功能代ç çš„地å€ã€‚

如果你想挑剔,funcA是一个常é‡è€ŒfuncB是一个å˜é‡ï¼Œæ‰€ä»¥è°ƒç”¨funcA的编译器输出将ä¸åŒäºŽfuncB ;在一ç§æƒ…况下,它是直接呼å«ï¼Œåœ¨ä¸€ç§æƒ…况下是间接呼å«ï¼Œå› ä¸ºfuncB的目的地å¯ä»¥éšæ—¶é—´å˜åŒ–。这也是星å·æ‰€è¯´çš„,"我ä¸æ˜¯ä¸€ä¸ªåŠŸèƒ½ï¼Œæˆ‘是指å‘功能的指针"。

é‡è¦çš„是è¦æ³¨æ„,在C中,星å·æ€»æ˜¯åœ¨å˜é‡åæ—边,以标记一个指针å˜é‡ï¼Œé‚£ä¹ˆä½ æƒ³è¦æ€Žä¹ˆå†™å‘¢å‘¢ï¼Ÿå–œæ¬¢è¿™ä¸ªï¼Ÿ

// Careful! Wrong!
int (int, int) *func;

这看起æ¥æ›´å…·å¯è¯»æ€§å—?或者也许是这样的?

// Careful! Wrong!
int ()(int, int) *func;

è¿™ç§è¯­æ³•ä¹Ÿä¸æ˜¯å¾ˆæ¸…楚,也没有模仿任何其他现有的C语法。如果你使用函数指针工作很多,传递它们并将它们存储在å˜é‡ä¸­ï¼Œä½ åº”该为函数指针声明一个自己的类型:

#include  <stdio.h>

int sum ( int a, int b ) {
    return (a + b);
}

typedef int (* MathFuncType)(int, int);

MathFuncType getSumFunc ( ) {
    return &sum;
}

int main(void) {
    MathFuncType func = getSumFunc();
    printf("%d\n", func(3, 8));
    return 0;
}

http://rextester.com/GEKR20461