天天看點

C語言中的指針類型——從簡單幼稚到變态瘋狂

說實話,接觸C已經很多年了,但是我對C裡面的指針類型依然缺乏一個系統的概念,最近翻閱了一些資料,把這個東西好好再研究了一次,現在就來總結一下。

C語言中的指針類型——從簡單幼稚到變态瘋狂

關于上面表中的定義式,不知你看明白沒有?

其中 :

        int (*f[])(); 和  int **(*f[])(); 還有 int **(*(*f[])())[10], 都存在未定義長度的數組表達形式,這在兩種情況下是合法的,即:用extern辨別連結屬性和作為函數參數時,如果直接在代碼内定義未加extern,那麼需要填充長度(即使是一個之前聲明過的整數變量),例如:int **(*(*f[5])())[10]; or int n = 2; int **(*(*f[n])())[10];

        倒數第三個例子, int *(*(*f)())[10](),其實是錯誤的,對于編譯器是非法的。雖然編譯器能夠分析它的邏輯含義,但是無法産生對應的代碼。你會見到諸如:error: declaration of ‘f’ as array of functions 這樣的編譯錯誤資訊。在這裡,編譯器認為這段代碼中 最後部分的 [10]()定義了一個關于函數的數組,又因為這一段代碼是關于f的定義,是以它會了解成你試圖在定義f為關于函數的數組,這裡它直接将f與函數的數組兩個概念連接配接起來,而不同的函數可能具有不同的長度,數組的元素必然是具有一緻的長度,是以它報出了錯誤。編譯器就是這種尿性,你隻能順從。 而如果将它稍微改一改,成為諸如 int (*(*(*f)())[10])(); 或者 int (*(*(*f)()))(); 這樣的形式,又是合法的(有沒有興趣解析一下其意義?)。 

      剛接觸上面這些不同種類的指針或者數組時,我的内心也是崩潰的,寫程式很多年了,早已在實際編碼中了解到幾乎沒有可能接觸到後面的幾種類型。夠用就好,這就是對待寫代碼的知識的實用法則,這次我主要把它們作為一種訓練。

      其實還有更更變态的指針相關的類型存在,而且就在一些高人寫的外星代碼裡面。這些代碼放在那裡,不需要經常維護,是以也就不存在很多常見的麻煩。多級間接指針是相當消耗性能的,比如幫助C++實作多态的虛函數表vtable,它的性能就要差些,如果實際編碼中确實要用到多級指針,建議不要用在多次執行的疊代和循環中,一次或者整個程式運作期間隻會少量運作的場合,比如子產品初始化,是可以用的,前提是你知道自己在幹什麼,并且不太影響後期了解和維護。

本文參考(幫助非常大,牆裂推舉):

         1 .  《Pointer On C》 --Kenneth A.Reek 1998

         2.  《讓你不再害怕指針——C指針詳解(經典,非常詳細)》,原出處沒有搜到,我是看的這裡的轉載。

繼續閱讀