指向函式的指標 轉

2021-06-19 21:05:19 字數 2844 閱讀 9446

5.1.2 指向函式的指標

c語言通過&和*操作符來運算元據的位址,但它並沒有提供乙個用一般的方式來操作**的位址。然而,c語言並沒有完全切斷程式設計師操作**位址的可能,它提供了一些"受限制的"方式來操作**的位址。之所以說這些方式是"受限制的",那是因為這些方式並不像運算元據位址那樣自由和靈活。

在c語言中,指標變數也可以指向乙個函式。我們已經知道**也是有位址的,乙個函式在編譯時會被分配給乙個入口位址,這個入口位址就是該函式中第一條指令的位址,這就是該函式的指標。當呼叫乙個函式時除了通過函式名來呼叫以外,還可以通過指向該函式的指標變數來呼叫。乙個指向函式的指標其初始值不能為空,因為它在使用之前必須被賦予乙個真實的函式位址。指向函式的指標變數的一般定義形式如下(其中的函式型別是指函式返回值的型別):

函式型別 (*指標變數名) (); 

請看下面這段示例**,它使用普通的函式名方式來實現函式的呼叫,此函式用於實現矩形法求解

函式定積分的功能。

#include "stdio.h"

#include "math.h"

//intergal(x^2)

double func1(double a , double b)  

return sum;  

}  void main()   

現在我們改寫上面的**,使用乙個指向函式的指標變數來呼叫函式。

#include "stdio.h"

#include "math.h"

//intergal(x^2)

double func1(double a , double b)  

return sum;  

}  void main()   

關於上面的**,有如下幾點需要說明。

①語句"double (*p)(double, double);"定義p是乙個指向函式的指標變數,此函式的返回值型別為double型。特別地,double (*p) ()並非是指向某一固定函式的,它僅僅表示定義了這樣乙個型別的變數,在程式中可以將不同的函式位址賦給它,由此它所指向的函式就會隨之變化。

②(*p)兩側的括號不能省略,這樣的語法意味著p先與*結合,是乙個指標變數;再與後面的括號()結合,表示此指標變數指向函式而非變數。如果將*p兩側的括號去掉,則變成double *p(),這樣表示的意思是函式p()的返回值型別是乙個指向double型變數的指標。本書前面也介紹過因為()的優先順序高於*,所以p會先與()結合,由此就宣告了乙個函式而非指標。

③賦值語句"p = func1;"的意思是將函式func1的入口位址(即函式中首條指令的位址)賦給指標變數p。易見,在給函式指標變數賦值時,只需要給出函式名即可,並不需要給出引數,因此如果將上面的賦值語句改寫成"p = func1(0.0, 1.0);"則是錯誤的!但是由於這裡僅僅使用了函式名,而不帶括號和引數,為了不讓編譯器將其與變數混淆,必須在使用之前進行宣告,表明func1是函式名而非變數名,這樣編譯時它們才會被當作函式名來處理。

④在使用函式指標時,只需將(*p)替代函式名即可,但是需要在其後的括號裡顯式地新增實參,即使函式不傳遞任何引數,該括號也不可省略。

⑤陣列名可以代表陣列的起始位址(陣列中首元素的位址),所以函式名也可以代表函式的入口位址(函式中的首條指令的位址)。但是對於指向函式的指標變數,它只能指向函式的入口處而無法指向函式中某一條具體的指令,因此對於p+n、p++等指標運算對於指向函式的指標是沒有意義的。

⑥獲得乙個函式位址的方法與獲得乙個變數位址的方法一樣,於是前面程式中的語句"p = func1;"也可以寫作"p = &func1; "。但是,必須保證函式func1已經在某個地方被宣告過了。

指向函式的指標可以獲得函式的入口位址,但它並不能像運算元組一樣獲得函式中每一條指令的位址,這樣的操作是相對受限的。但人們不禁要問,這種語法有什麼用處呢?函式指標最常用的地方是作為引數傳遞給其他的函式。指向函式的指標也可以作為引數以實現函式位址的傳遞,也就是將函式名傳遞給形式引數。但是我們知道,在某個函式中呼叫另外乙個函式僅僅需要在此函式中直接呼叫所需的函式就可以了,這是c語言所支援的非常基本的函式呼叫語法。如此看來,將函式指標作為引數來傳遞,然後在函式體中使用實在是多此一舉、畫蛇添足。然而,將函式指標作為引數來使用還是非常有用的,尤其當每次函式所呼叫的其他函式無法固定時,這就顯得尤為重要了。假設有函式fun,在某次執行過程中需要呼叫函式func1,而下一次就需要呼叫函式func2,再下一次又可能呼叫func3。如果使用函式指標,則不必對函式fun進行修改,只需要讓其每次呼叫函式時通過不同的函式名來作為形參傳遞即可。這種方法極大地增加了函式使用的靈活性,我們可以編寫乙個通用的函式來實現各種專用的功能,這是符合結構化程式設計思想的方法。

下面通過乙個簡單的示例程式來說明這種方法的應用。該例子編寫了乙個求定積分的通用函式,用它可以分別求得3個函式的定積分:

#include "stdio.h"

#include "math.h"

//intergal(x^2)

double func1(double a , double b)  

return sum;  

}  //intergal(sinx)

double func2(double a , double b)  

return sum;  

}  //intergal(e^(x^-2))

double func3(double a , double b)  

return sum;  

}  void intergal(double a, double b, double (*fun)(double, double))  

void main()   

完成編碼後,編譯並執行程式。

指向函式的指標 函式指標

如果在程式中定義了乙個函式,在編譯時,編譯系統為函式 分配一段儲存空間,這段儲存空間的起始 又稱入口 位址 稱為這個函式的指標。指標即是位址 我們定義乙個指標變數,這個指標變數指向乙個整型資料變數的位址,我們稱指向乙個整型資料的指標變數 那麼它指向乙個函式的位址,稱為指向乙個函式的指標變數。形如 i...

函式指標 指向函式的指標

乙個函式總是占用一段連續的記憶體區域,函式名在表示式中有時也會被轉換為該函式所在記憶體區域的首位址,這和陣列名非常類似。我們可以把函式的這個首位址 或稱入口位址 賦予乙個指標變數,使指標變數指向函式所在的記憶體區域,然後通過指標變數就可以找到並呼叫該函式。這種指標就是函式指標。函式指標的定義形式為 ...

指向函式的指標,指向函式的指標作為函式引數

1.基本法 include pragma warning disable 4996 pragma warning disable 4715 指向函式的指標作為函式的引數 有兩個整數a,b,讓使用者輸入1,2或者3,當輸入1時,給出相對大值,當輸入2時,給出相對小值,當輸入3時,給出兩者之和 1.可以...