如何解讀返回函數指針的函數聲明


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

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

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

  其次,要確定在聲明中標識符與某個操作符結合起來的時候有什么意義。例如:

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

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

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

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

  

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

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;  
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM