在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) { ...
这里的返回类型(它是一个函数的指针)åŠå…¶ç»†èŠ‚(例如我们指å‘的函数返回以åŠå®ƒä½œä¸ºå‚数接å—的内容)显然ä½äºŽå·¦ä¾§ï¼Œå¹¶ä¸”函数å称函数本身在å³è¾¹ã€‚对我æ¥è¯´ï¼Œæˆ‘的版本似乎更符åˆé€»è¾‘和清晰,为什么我们ä¸è¿™æ ·å†™å‘¢ï¼Ÿ
ç”案 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 ∑
}
int main(void) {
MathFuncType func = getSumFunc();
printf("%d\n", func(3, 8));
return 0;
}