函式指標陣列

2021-09-29 04:28:13 字數 3818 閱讀 5637

首先回顧一下函式指標

函式指標是指向函式的指標主體是指標指向的是乙個函式的位址(函式也是有位址的!)

基本宣告形式:返回資料型別 + (*函式名) + (變數型別1,…);

注意 * 和函式名要用括號括起來,否則因為運算子的優先順序原因就變成指標函式了

e.g:

int (*fun) (int);
上面的宣告表示:函式返回型別為指標,什麼型別的指標呢?就是指向引數為int,返回值為int的函式的指標。(可以模擬於指向int型或者char型的指標,int*,char*) 

#includeint add(int x,int y)

int (*fun) (int,int);            //宣告函式指標

int main()

輸出結果:8 6

如果把多個函式指標放在乙個陣列中,就形成了函式指標陣列。

函式指標陣列形式如下:

int (*parr[10])(int,int);
parr先和[ ]結合,說明parr是陣列,陣列的內容是指向int (*)(int,int)型別的函式指標(函式本身的型別一定是引數為(int,int),返回值為(int)這裡用加減乘除4個函式為例,演示函式指標陣列的應用。

#includeint test_add(int a,int b)

int test_sub(int a,int b)

int test_mul(int a,int b)

int test_div(int a,int b)

void main()

;//定義函式指標陣列

printf("%d+%d = %d\r\n",a,b,(*parr[0])(a,b));

printf("%d-%d = %d\r\n",a,b,(*parr[1])(a,b));

printf("%d*%d = %d\r\n",a,b,(*parr[2])(a,b));

printf("%d/%d = %d\r\n",a,b,(*parr[3])(a,b));

}system("pause");

return 0;

輸出:

這裡需要注意函式指標陣列的呼叫,*parr[0]取的是函式指標,即函式的位址;(*parr[0])(a,b)即執行函式,(a,b)是對函式引數賦實參。這裡*加不加無所謂,加*可以清楚的指明這是通過指標的方式來呼叫函式。

第二章已經舉例說明了函式指標陣列的使用方式。但是,第二章的使用方式必須是函式指標的引數列表要和函式指標指向的函式的引數列表一致。那麼能否在函式指標陣列中放引數型別不一樣的函式指標呢?

比如

int test_mod2(int a)

能夠和第二章裡面的加減乘除函式都放進乙個函式指標陣列中呢?

這個問題我在實際應用中碰到過,有實際應用的意義。在做嵌入式時,應用程式(demo)需要呼叫boot中的函式,首先將boot中函式放在乙個函式指標陣列中;然後將此陣列放在乙個固定的位址;接著demo呼叫boot中的函式時,直接去這個固定位址取函式指標,最後傳參執行函式。需要呼叫的api引數型別、返回值是不一樣的。

上圖是demo呼叫boot中函式的示意圖。

這時候有乙個辦法:將型別一致的函式放在乙個函式指標陣列中。但當api較多時,且型別都不一致時,就會導致需要很多函式指標陣列。當需要新增函式或者減少函式時,相應的位址都需要變化,很不方便。

還有另乙個辦法,就是將函式指標陣列定義成指向引數和返回值都為void型的函式指標。

如下:

#includeint test_add(int a,int b)

int test_sub(int a,int b)

int test_mul(int a,int b)

int test_div(int a,int b)

int test_mod2(int a)

void(*apitable[128])(void)=;

#define test_add_table(a,b) ((*(int(*)(int,int))(*apitable[0]))(a,b))

#define test_sub_table(a,b) ((*(int(*)(int,int))(*apitable[1]))(a,b))

#define test_mul_table(a,b) ((*(int(*)(int,int))(*apitable[2]))(a,b))

#define test_div_table(a,b) ((*(int(*)(int,int))(*apitable[3]))(a,b))

#define test_mod2_table(a) ((*(int(*)(int))(*apitable[4]))(a))

void pointer_test()

輸出:

可見,我們將函式指標陣列定義成返回值和引數都為空型別即可。使用時,再進行強制轉換。

在我的實際應用中,函式指標陣列定義是在boot中,define定義是在demo中,這樣就能夠順利呼叫了。這裡我做兩個.c檔案,乙個表示boot中函式,乙個表示demo中呼叫。

//boot

int test_add(int a,int b)

int test_sub(int a,int b)

int test_mul(int a,int b)

int test_div(int a,int b)

int test_mod2(int a)

void(*apitable[128])(void) _attribute_((at(0x0000a000))) =;

這裡_attribute_((at(0x0000a000)))是arm編譯器規定的指定位址的用法,即將函式指標陣列放在0x0000a000位址。

//demo

#include #define apitable (int*)0x0000a000//與boot中定義在同一位置,強制轉換成指標

#define test_add_table(a,b) ((*(int(*)(int,int))(*apitable[0]))(a,b))

#define test_sub_table(a,b) ((*(int(*)(int,int))(*apitable[1]))(a,b))

#define test_mul_table(a,b) ((*(int(*)(int,int))(*apitable[2]))(a,b))

#define test_div_table(a,b) ((*(int(*)(int,int))(*apitable[3]))(a,b))

#define test_mod2_table(a) ((*(int(*)(int))(*apitable[4]))(a))

void pointer_test()

以上就是我在實際應用中用到的函式指標陣列的用法。

指標陣列 陣列指標 函式指標 函式指標陣列

陣列指標 指向陣列的指標,是乙個指標,其指向的型別是陣列 指標陣列 元素為指標的陣列,是乙個陣列,其中的元素為指標。例如 int a 5 這個是陣列指標。int a 5 這個是指標陣列。定義函式指標型別 int max int,int typedef int fun ptr int,int 申明變數...

指標陣列,陣列指標,指標函式,函式指標

int p 4 指標陣列。是個有4個元素的陣列,每個元素的是指向整型的指標。int p 4 陣列指標。它是乙個指標,指向有4個整型元素的陣列。int func void 指標函式。無參函式,返回整型指標。int func void 表示函式指標,可以指向無參,且返回值為整型指標的函式。右左規則 因為...

陣列指標,指標陣列,函式指標,指標函式

陣列指標,指標陣列,函式指標,指標函式 指標 變數,存放變數的位址。例 int ptr,ptr是乙個指向整形變數的指標 陣列 例 int a 10 定義了乙個具有10個元素的一維陣列,其中陣列的每個元素是乙個int型別。陣列指標 陣列首元素位址的指標,即是指向陣列的指標。例 int ptr 10 c...