C++中的函數指針,函數指針
寒假這些天在看《The C++ Programming Language, 3rd》。
今天看到Chapter7 Function,裡頭好一些東西是C語言裡沒有的,比如overload、passing by reference。這裡不講這些,講C語言也有的 pointer to function。以前學C語言的時候,簡單學過pointer to function,還在大一用過那麼一會。當時是在MCS-51上的delay函數,因為發現while語句與for語句在相同參數下花費時間不一樣,寫了一個小程序驗證強化對比我的直觀感受。代碼如下:

![]()
1 #include <reg51.h>
2
3 sbit beep = P2^3;
4
5 void delayms_v1(unsigned int);
6 void delayms_v2(unsigned int);
7 void delayms_v3(unsigned int);
8 void delayms_v4(unsigned int);
9
10 // void leftmove();
11 // void leftmove_one();
12 void leftmove_one_test();
13
14 void main()
15 {
16 leftmove_one_test();
17
18 }
19
20 // void leftmove()
21 // {
22 // P1 = 0xFE;
23 // while (1)
24 // if (P1 == 0) {
25 // P1 = 0xFF;
26 // delayms_v1(500);
27 // } else {
28 // P1 = P1 << 1;
29 // delayms_v1(500);
30 // }
31 // }
32
33 void leftmove_one_test()
34 {
35 unsigned char apoint, pos, i;
36 void (*delay_funcs[4])(unsigned int) = {delayms_v2, delayms_v3, delayms_v4, delayms_v1 };
37
38 for (i = 0; i < 4; i++) {
39 apoint = 1;
40 for (pos = 0; pos < 8; pos++) {
41 P1 = ~apoint;
42 beep = 0;
43 (*delay_funcs[i])(10);
44 beep = 1;
45 apoint = apoint << 1;
46 (*delay_funcs[i])(500);
47 }
48 }
49 }
50 /*
51 void leftmove_one()
52 {
53 unsigned char apoint = 1;
54 while (1)
55 if (apoint == 0)
56 apoint = 1;
57 else {
58 P1 = ~apoint;
59 beep = 0;
60 delayms_v3(10);
61 beep = 1;
62 apoint = apoint << 1;
63 delayms_v3(480);
64 }
65 } */
66 void delayms_v1(unsigned int time)
67 {
68 unsigned char i = 110;
69 while (time--)
70 while (i--);
71 }
72 void delayms_v2(unsigned int time)
73 {
74 unsigned char i;
75 while (time--)
76 for (i = 0; i < 110; i++);
77 }
78 void delayms_v3(unsigned int time)
79 {
80 unsigned char i, j;
81 for (i = time; i > 0; i--) //為什麼不可以寫成 for (i = 0; i < time; i++) ???
82 //for (i = 0; i < time; i++)
83 for (j = 0; j < 110; j++);
84 }
85 void delayms_v4(unsigned int time)
86 {
87 unsigned char i = 0;
88 while (time--)
89 for (i; i < 110; i++);
90 }
View Code
以上代碼有嚴重bug,當時怎麼也想不明白,現在一眼看得出。不過我還是不想改,就這樣原封不動貼出來比較好。
言歸正傳,看完bj大大的文字與代碼,確實感觸良多。這裡只講其中一小點(一個Chapter裡的一個section裡的一小點:-) )。
這裡用這章的exercise 1做展開(其實只是我做這道題遇到一些bj大說的silly mistakes,想記錄而已,哈哈)。
這道題要我寫幾個declarations,第一個:a function taking arugments of type pointer to character and reference to integer and returning no value.
這個好辦。
1 void f1(char*, int&);
第二個:a pointer to such a function.
這個也好辦。
void (*pf1)(char*, int&);
第三個:a function taking such a pointer as an argument.
這個我真想了挺久的(這就是我寫這篇博客的最初動機)。後來看到題目後面的hint:Use typedef 才恍然大悟。連同第四個:a function returning such a pointer。這四個declaration如下:
typedef void FUNC(char*, int&);
FUNC f1;
FUNC (*pf1);
void f2(FUNC*);
FUNC* f3();
本著人道主義精神,我還是把整個文件貼出來吧...

![]()
1 #include <iostream>
2 #include <string>
3 #include <typeinfo>
4 using namespace std;
5
6 typedef void FUNC(char*, int&);
7 FUNC f1;
8 FUNC (*pf1);
9 void f2(FUNC*);
10 FUNC* f3();
11
12 int main()
13 {
14 char str[] = "hello";
15 int i = 2;
16 f1(str, i);
17 pf1 = f3();
18 pf1(str, i);
19 f2(f1);
20
21 return 0;
22 }
23
24 void f1(char* st, int& it)
25 {
26 cout << "type of " << st << " is " << typeid(st).name() << endl;
27 cout << "type of " << it << " is " << typeid(it).name() << endl;
28 }
29
30 void f2(FUNC* foo)
31 {
32 char xi[] = "xixi";
33 int haha = 3;
34 foo(xi, haha);
35 }
36
37 FUNC* f3()
38 {
39 return f1;
40 }
View Code