1) 函數指針的初始化。

函數如下:

int CompareString(const string& str1, const string& str2)
 {
    return str1.compare(str2);  

 }

函數的初始化有兩種方式:

第一種,也是最普遍的方式:

int (*CompareFunction)(const string&, const string&) = CompareString;

第二種,是使用typedef定義函數類型,這種寫法有助於對代碼的理解:

typedef int (*CompareFunctionType)(const string&, const string&);
CompareFunctionType CompareFunction = CompareString;

2) 函數指針賦值。

函數名可以理解為該類型函數的指針。當然,取地址操作符作用於函數名上也能產生指向該類型函數的指針。也就是説下面兩種賦值都是可行的:

CompareFunctionType CompareFunction = CompareString;
CompareFunctionType CompareFunction = &CompareString;

3) 函數調用。

無論是用函數名調用,還是用函數指針調用,還是用顯式的指針符號調用,其寫法是一樣的:

CompareString("abc", "cba");
CompareFunction("abc", "cba");
(*CompareFunction)("abc", "cba");

4) 函數指針的數組。

對於函數指針的數組,強烈建議使用typedef方式定義類型之後再使用,不然影響代碼的閲讀性,繼續以以上例子為例:

//without typedef
 int (*CompareFunctionArray[3])(const string&, const string&);
 //with typedef
 CompareFunctionType CompareFunctionTypeArray[3];

5) 函數指針用做函數返回值的類型。

到這一步,會發現typedef是多麼的好用了。不然我是完全讀不懂下面語句的意思的:

//without typedef
 int (*func(int*, int))(const string&, const string&);

上面的聲明,將func(int*, int)聲明為一個函數,返回值為函數指針,函數類型為 int (*)(const string&, const string&)。

多麼的晦澀啊!

如果寫成typedef就不用這麼糾結了,足見typedef的作用:

CompareFunctionType func(int*, int);

6) 指向extern “C”函數的指針。

《C++ primer 3》中有指出,指向C函數的指針和指向C++函數的指針類型不同,但是現在的很多編譯器都有語言擴展,認為這兩種函數的指針具有相同的特性。

所以,我在vs 2010中做了嘗試,結果證明是支持這種語言擴展的。

函數聲明如下:
複製代碼

extern "C" int InsideFunctionC(const string& str1, const string& str2)
 {
     return str1.compare(str2);
 }

 int InsideFunctionCPlusPlus(const string& str1, const string& str2)
 {
     return str1.compare(str2); 

 }

函數指針的初始化和調用,允許賦值為指向C函數的指針:

int (*CompareFunction)(const string&, const string&) = InsideFunctionC;

另外還有一點,當extern “C”應用在一個聲明上時,所有被它聲明的函數都將受到影響。舉個例子:

extern "C" void OutSideFunction(int (*fc)(const string&, const string&))
{
    cout<<fc("abc", "cba")<<endl;;
}

這裏的OutSideFunction和fc都將受到extern “C”的影響,但是vs2010編譯器是支持一個指向C++函數的指針作為OutSideFunction的參數。如下:

int main()
{
     OutSideFunction(InsideFunctionC);
     OutSideFunction(InsideFunctionCPlusPlus);

     return 0; 

}

到此就差不多了。昨天看了一遍,今天又寫博客温習了一遍,應該算是加深記憶了。