又是一對好基友之間的故事 函數指針vs指針函數: 函數指針:指向函數的指針,例如:void (*f) (int , int ); 指針函數:函數的返回值是指針,例如:void *f(int , int); 本是同根生,緣何要分開:緣自於( )和 *,兩者的優先級不同,前者的優先級大於後者 指針函數比較簡單,我們主要看函數指針 一、函數指針的初始化和賦值 函數:int func(int , int) 函數指針:int (*fptr) (int, int) 初始化:fptr = func,就這麼簡單 這裡我們提出兩點: 1.對於一個函數int func(int , int)的任何使用都會被隱式的轉換為int (*) (int, int),沒錯就是函數指針 例如:int (*fptr) (int, int)是一個函數指針,fptr = func (func轉換為了一個函數指針) 2.函數指針的類型要和函數的一樣,包括返回值,形參列表 例如:int (*fptr) (int, int)是一個函數指針,char *func1(int, int), int func2 (int, int, int); fptr = func1 //錯誤 類型不匹配 fptr = func2 //錯誤 形參不匹配 二、利用函數指針調用函數 學習函數指針當然是要用它去代替函數了,那怎麼調用函數呢,有兩種方式: fptr(3, 6);//推薦使用這種方式調用 (*fptr)(3, 6);//這個先把fptr解引用,然後*fptr等同於函數名,接著再調用 看一個例子:
#include <stdio.h> int add(int a, int b); void main() { int (*fptr) (int, int); fptr = add; int x = 2, y = 3, z; z = add(x, y); z = fptr(x, y); z = (*fptr)(x, y); printf("%d\n", z); } int add(int a, int b) { return a + b; }
三、函數指針用於形參 顧名思義,就是把函數指針用作另一個函數的形參,看如下的例子
#include <stdio.h> int add(int a, int b, int (*fptr)(int c, int d)); int bigger(int c, int d); void main() { int x = 2, y = 3, z; z = add(x, y, bigger);//how to use printf("%d\n", z); } int add(int a, int b, int (*fptr)(int c, int d)) { return a + b + fptr(a, b); } int bigger(int c, int d) { return c > d?c : d; }
四、返回一個指向函數的指針 在了解這種情況之前,我們先看一下typedef在此處的應用 typedef int (*func) (int , int),很好理解,func是一種函數指針類型,此類型為int (*) (int, int) 看一個比較復雜的: int (*fptr(int, int (*fptr1(int, int)))) (int , int) 暈了吧,不要慌,勇敢的去看,fptr是什麼?它是一個函數,這個函數有兩個參數,一個是int,另一個是一個函數指針,指向的是有兩個整形參數並且返回一個int的函數,fptr這個函數返回的是一個指針,簡化來看就是int (*)(int, int) ,fptr返回的就是一個函數指針 實際上我們可以簡化來看 typedef int (*FPTR) (int, int) FPTR fptr(int, FPTR fptr1); 五、關於函數指針數組 舉個例子看吧
#include <stdio.h> int func1(int *x) {(*x)++;} int func2(int *x) {(*x)++;} int func3(int *x) {(*x)++;} typedef int (*fptr)(int *); void main() { fptr fptr_array[]= { func1, func2, func3 }; //函數指針數組 int x = 2, i; for(i = 0; i < sizeof(fptr_array)/sizeof(fptr_array[0]); i++) fptr_array[i](&x); printf("%d\n",x); }
以上是關於函數指針和指針函數的總結