1. 程式人生 > >Linux核心 指標函式和函式指標

Linux核心 指標函式和函式指標

       首先,要區分函式指標和指標函式。函式指標和指標函式從語文的角度看,應該算是一個偏正短語,函式指標說明是一個指標,而指標函式說明是一個函式;其是什麼樣的指標、什麼樣的函式,我們先暫且不論。明確函式指標是指標,指標函式是函式,這才是最重要的。下面在來看這是一個什麼樣的指標、什麼樣的函式。

       1.指標函式

        指標函式就是返回值為指標的函式,就這麼簡單,其具體定義為:

       型別名 *函式名(引數列表)

其中,括號“()”表示這是一個函式,其運算子“*”表示此函式為指標型函式,其函式返回值為指標,“型別名”表示函式返回的指標所指向的型別。 我們注意到,指標函式的定義和普通函式的定義差不多,只不過在普通函式定義的函式名前加上“*”就變為相應的指標函數了。

“(引數表列)”在呼叫語句中,即使函式不帶引數,其引數表的一對括號也不能省略。其示例如下:

 int *func(int, int)

由於“*”的優先順序低於“()”的優先順序,因而func首先和後面的“()”結合,也就意味著,func是一個函式。接著再和前面的“*”結合,說明這個函式的返回值是一個指標。由於前面還有一個int,也就是說,func是一個返回值為整型指標的函式。

2.函式指標

函式指標是指向函式的指標變數,因此其實指標變數,只不過這個指標變數是指向某個函式,就如同指標變數可以指向整型、字元型等,僅此而已。C在編譯時,每一個函式都有一個入口地址,該入口地址就是函式指標所指向的地址。有了指向函式的指標變數後,可用該指標變數呼叫函式,就如同用指標變數可引用其他型別變數一樣。

這裡我們要記住函式指標的兩個用途:呼叫函式和作為函式的引數。這兩個用途對於分析複雜的指標函式有很大的指導作用。其具體定義為:

函式型別 (* 指標變數名) (形參列表)

“函式型別”說明函式的返回型別,“(標誌符 指標變數名 )”中的括號不能省,若省略整體則成為一個函式說明,說明了一個返回的資料型別是指標的函式,後面的“形參列表”表示指標變數指向的函式所帶的引數列表。“形參列表”可有可無,視情況而定。其示例如下:

int func(int x); /* 宣告一個函式 */ 
  int (*f) (int x); /* 宣告一個函式指標 */ 
  f=func; /* 將func函式的首地址賦給指標f */

賦值時函式func不帶括號,也不帶引數,由於func代表函式的首地址,因此經過賦值以後,指標f就指向函式func(x)的程式碼的首地址。

這裡看一個複雜一點的例子:

 int (*ff(int))(int *, int);

我覺得這裡只需要說明一點,這裡的指標不是一個我們所理解的簡單變數,這裡的函式指標是一個由指標函式返回的指標來充當的;ff首先與後面的“()”結合,接著與前面的“*”結合,說明ff函式的返回值是一個指標,即:int (*(ff(int)))(int *, int)。就像普通指標和指標函式返回的指標的關係那樣。只要理解這一點,我覺得這個例子就很好理解了。

linux核心中例子:void (*signal (int signr,void (*handler)(int))) (int)

這裡的void (*handler)(int))的用途是作為函式引數,這裡面相當於函式指標巢狀函式指標,(*signal (int signr,void (*handler)(int))) 是指標函式的返回值充當函式指標。