天天看點

函數指針與函數聲明

問題:當計算機啟動時,硬體将調用首位址為0的子例程,為了模拟開機啟動時的情形,如何設計出一個c語句,以顯示調用該子例程。

換個問法:有一段程式存儲在起始位址為 0的一段記憶體上,如果我們想要調用這段程式,請問該如何去做? 

《c陷阱與缺陷》給出答案:(*(void(*)())0)();

相關知識:函數指針

函數指針是指向函數的指針變量,即本質是一個指針變量。

在C語言中規定,一個函數總是占用一段連續的記憶體區,而函數名就是該函數所占記憶體區的首位址。我們可以把函數的這個首位址(或稱入口位址)賦予一個指針變量,使該指針變量指向該函數。然後通過指針變量就可以找到并調用這個函數。我們把這種指向函數的指針變量稱為“函數指針變量”,簡稱:函數指針

指向函數的指針包含了函數的位址,可以通過它來調用函數。聲明格式如下:

  類型說明符 (*函數名)(參數)

其實這裡不能稱為函數名,應該叫做指針的變量名。這個特殊的指針指向一個傳回整型值的函數。指針的聲明必須和它指向函數的聲明保持一緻。

問題分析:

  1、想要調用這段程式(子例程),設為func函數,由上述相關知識,我們可以使用最基本的指針函數void(*f) ()來調用子例程,調用方法:(*func)();

  2、子例程存儲在起始位址為 0的一段記憶體上,故可了解為0是這個子例程的入口位址,func函數入口位址為0。即func指向位址為0的函數;

  3、由2知,func為指向位址0的函數,是以func是一個函數指針,設func是一個指向傳回值為void類型的函數的指針,故可設func的函數指針聲明為void (*pfunc)();

  4、由函數聲明void (*pfunc)()類比于變量聲明,同樣,通過強制轉換,我們可以得到位址為0的入口函數位址(void (*)())0;

  5、将4代入1中,即有(*(void (*)())0)().

其他:

指針函數:

一個函數不僅可以帶回一個整型資料的值,字元類型值和實型類型的值,還可以帶回指針類型的資料,使其指向某個位址單元。

      傳回指針的函數,一般定義格式為:類型辨別符    *函數名(參數表)

  示例:int *f(x,y);

函數指針是一個指向函數的指針,而指針函數隻是說明他是一個傳回值為指針的函數。

void* 指針:

c++提供了一種特殊的指針類型void*,它可以儲存任何對象類型的位址(c++ primer)。

參考:http://lionwq.spaces.eepw.com.cn/articles/article/item/18258

         http://blog.csdn.net/norbe/article/details/624257

繼續閱讀