1. 程式人生 > >C語言 複雜指標的申明問題 陣列指標 指標陣列 函式指標 指標函式一覽無遺! C/C++求職面試必備考點(四)

C語言 複雜指標的申明問題 陣列指標 指標陣列 函式指標 指標函式一覽無遺! C/C++求職面試必備考點(四)

       首先,看如下8個題,如果您能不看任何資料的情況下做對。那麼恭喜您,這塊應該基本沒問題了。因為再複雜的組合都是從這上面8種裡變出來的。

1,定義一個整形數

2,定義一個指向整形數的指標

3,定義一個指向指標的指標,它指向的指標,是一個指向整形數的指標

4,定義一個具有10個整形數的陣列

5,定義一個具有10個指標的陣列,這些指標都是指向整形數的

6,定義一個指向有10個整形數 陣列的指標

7,定義一個指向函式的指標,該函式有一個整形引數 並返回一個整形資料

8,定義一個有10個指標的陣列,每個指標指向一個函式,該函式有一個整形引數,返回一個整形數

答案如下:

1,int a

           這沒啥好說的。

2,int *a,

            *a表示a是一個指標,左邊的int表示指標指向資料的型別。也許這會覺得是廢話,但後面一複雜,往往不知所指了。

3,int **a

4,int a[10]

5, int *a[10]    

         注意從這裡往下開始繞了,當* 和[]同時出現時,[]的運算級別高於*,因此首先是a[10]表示陣列a有個10個元素,*a[10]表示每個元素都是一個指標,*修飾的是a[10],而不是a。加上int表示指向資料型別

6,int (*a)[10]  

           首先是要求一個數組,數組裡有10個整數,也就是int a[10],然後要求有一個指標來指向這個陣列,注意是指向這個陣列,而不是上面5題裡的指向數組裡的每一個元素a[0] a[1]。。。因此指標修飾的是陣列名字a,所以寫成int (*a)[10].由於加了括號,*優先作用於a

7, int (*f)(int) ,

        這裡假設函式名字為f,指向函式的指標寫成(*f),外面帶括號,這個要切記!原因下面總結裡會有。函式裡面有引數,且引數為Int型,寫成(*f)(int).最後,返回型別為int ,在前面加上int就行了。表示返回型別.

8,  int (*a[10])(int)  

要求要定義一個有10個指標的陣列,也就是5題型別,*a[10],這裡面的a[0] a[1]............都是指標。下面要求指標指向一個函式,寫成(*a[10])()。這裡注意衡量是否是函式的標誌就是後面要有個括號。 下面要求函式的引數是int,且返回int。故答案是int (*a[10])(int). 最終的意思是a[0] a[1] a[2]..........都是指標,每個指標都指向函式,函式裡的引數是int返回int.

        有了上面8個題的基礎,理解下面的就容易了。如果上面8個題,您不僅能答對題目,還能把題目本身用語言文字描述清楚,下面就是小case。

       題目1,定義一個指向函式的指標func,這個函式裡有一個引數是指向int資料的指標,返回一個int資料

答案:首先寫出(*func)(),注意這裡要帶括號,函式指標申明時左右一定有兩個括號。第一個括號表示本身的函式指標的名字,除非是int sum(int , int),sum不用括號括起來。如果是函式指標則要括起來。第二個括號表示裡面的引數。加上引數int*,和返回型別。答案是 int (*func)(int *)

       題目2,定義一個指向函式的指標 func,該函式有兩個引數一個是int *p, 一個是int(*f)(int*),返回一個int。合起來就是int (*func)(int *p , int(*f)(int*))  注意這裡的*f儘管f就一個字母但還是要括起來。其他不多解釋了。

     題目3,int(*func[5])(int *p)

釋義:再複雜的組合都逃不掉上面8種類型。由兩個括號,則肯定是函式。函式的引數是一個指向int的指標。函式的返回值是一個int。接下來就是(*func[5])這塊了,它表示func是一個指標陣列,他裡面的每一個元素都是一個指標,這些指標指向一個函式。

      也就是說,func是一個數組,數組裡的每個元素都是指標。準確說,(由(int*p)可以看出)數組裡的每一個元素都是函式指標,它指向的函式引數為int*P,返回型別為int。

        題目4,int(*(*func)[5])(int *p)

釋義:首先來看模組(*func)[5],上面已經說過,他表示func是一個指向有5個數據元素的陣列的指標。陣列我們都知道int a[50],還記得我們上面說的,50表示數組裡面元素的個數,左邊的int表示陣列元素的資料型別。只要是陣列,一定要告訴他裡面所放元素的型別!我們看(*func)[5]左邊還有一個*號,然後外面才是括號。所以我們要先解析這個*號。這裡*就是告訴陣列指標func所指向的具有5個元素的陣列,裡面所放元素的型別是指標。好了,跳出括號。右邊又是一個括號。表示是函式。函式輸入引數為int*p,返回型別為int。

       即:func是一個指向陣列的指標,這個陣列有5個元素,每個元素的資料型別是函式指標,這些函式指標指向具有int*形參,返回int的函式。

       題目5,int(*(*func)(int *p))[5]

釋義:首先看模組(*func)(int *p)表示func是一個函式指標,多餘的不羅嗦了,將此模組用a表示。也即int(*a )[5],這塊意思是a是一個指向陣列的指標。等會,上面我們提到陣列必須有陣列個數,以及陣列元素的型別。而函式必須有引數和返回型別。對於本題,將上面合在一起,也就是func是一個函式指標,它指向的函式輸入引數為int *型別,返回型別是一個指向陣列的指標,它指向的數組裡面元素個數是5,資料型別為int。

至此,我們總結下:

一、指標陣列和陣列指標的概念

      指標陣列是說數組裡的元素都是指標,如int *a[5],陣列a裡面有5個元素,每個元素都是指向int的指標。

陣列指標是說,有一個數組int a[5],數組裡元素個數為5,型別為int,現在要有個指標來指向這個陣列,申明為int (*a)[5]

二、指標函式和函式指標的概念

      指標函式的意思是,函式的返回型別是一個指標。如int *f(int x), 這裡f是一個函式,他的返回型別是一個指向int資料的指標。

       什麼是函式指標呢?我們趁熱打鐵,int(*f)(int x),則f就是函式指標,即指向一個函式的指標叫函式指標。這就是上面為啥(*f)加()的原因。

       為啥需要函式指標呢?因為函式程式碼是程式中的演算法指令部分,他和整形資料、各種資料一樣也是佔記憶體的。我們可以通過char *p = "hello!", printf("%s",p),通過字串的首地址來列印字串。因此也可以通過函式的首地址來呼叫這個函式,這就是函式指標的由來。他的使用如下:

        假設現在有個函式int sum(int  a, int b),我們再申明個函式指標,int (*pSum)(int a, int b)然後pSum = sum,注意sum後面不要帶括號。sum表示這個函式的首地址,這和字串陣列一樣。如此初始化函式指標後,sum(3,4)的效果和(*pSum)(3, 4)是一樣的!函式指標的用法有爭議,(*pSum)(3,4)和pSum(3,4)都可以,參見http://blog.csdn.net/megaboy/article/details/482767。但函式指標,也就是指向函式的指標申明時,*和指標名字號一定用括號括起來!函式返回的資料型別為指標,叫指標函式,這時*和函式名是不括在一起的!

將陣列指標、函式指標總結在一塊:

陣列指標、函式指標,*和指標名字一定要括號括起來!

三、在解析複雜指標申明時,一定要記著大原則:陣列一定要告訴它元素個數和資料型別,函式一定要有形參型別和返回資料型別。