[C/C++]如何解讀返回函數指針的函數聲明

今天在看《深刻理解C++11》的時候,看到一段有意思的代碼:ios

int (*(*pf())())() {
    return nullptr; 
}

 

我馬上就懵了——歷來沒有見過這樣的函數聲明。那麼它到底是一個怎樣的函數呢?我努力回憶起《C專家編程》一書的內容,把其中解讀變量聲明的方法應用於該函數上,最終讀懂了該函數。下面是大體的解讀過程。編程

 

首先,要肯定聲明中出現的操做符的優先級。顯然,函數調用操做符()的優先級是高於指針解引用操做符*的。另外,小括號老是具備最高優先級。函數

 

其次,要肯定在聲明中標識符與某個操做符結合起來的時候有什麼意義。例如:測試

a()    a是一個函數
*a     a是一個指針spa

因爲函數聲明的特殊性,當指針解引用操做符*與一個表示函數的標識符結合時,表示這個函數的返回值是一個指針。例如 *a() 表示a是一個返回值爲指針的函數。指針

 

有了以上的基礎,接下來咱們就能夠從聲明中的標識符開始,按照操做符的優先級,由內向外逐步來解讀:code

            pf()            pf是一個無參數函數
          * pf()            pf是一個無參數函數,它的返回值是一個指針
        ( * pf() ) ()       pf是一個無參數函數,它的返回值是一個無參數函數的指針
      * ( * pf() ) ()       pf是一個無參數函數,它的返回值是一個無參數函數的指針,這個函數的返回值又是一個指針
    ( * ( * pf() ) () ) ()  pf是一個無參數函數,它的返回值是一個無參數函數的指針,這個函數的返回值又是一個無參數函數的指針
int ( * ( * pf() ) () ) ()  pf是一個無參數函數,它的返回值是一個無參數函數的指針,這個函數的返回值又是一個無參數且返回值爲int的函數的指針。

 

最終的解讀結果冗長拗口。能夠看出,這其實是返回值爲函數指針的函數的遞歸聲明。下面是可讀性更強的等效代碼:blog

typedef int (*pa)(); 
typedef pa (*pb)(); 
pb pfex() {  
    return nullptr; 
}

 

下面是驗證解讀結果的測試代碼。不得不說,測試代碼也不容易理解……遞歸

#include <iostream>

int a() {
    return 29; 
}

int (*b())() {
    return a; 
}

int (*(*pf())())() {
    return b; 
}

typedef int (*pa)(); 
typedef pa (*pb)(); 
pb pfex() {  
    return b; 
}

int wmain() {

    int r = pf()()();  
    std::wcout << r << std::endl;

    r = pfex()()();  
    std::wcout << r << std::endl;  
}

 

最終的輸出是兩個數字29。io

相關文章
相關標籤/搜索