C語言-函數指標

1.函數指標

在C語言中,指標是個強大的工具,透過記憶體定址,我們可以修改任何地址中的資料內容,除了將指標用於變數外(指標變數)我們也可將指標用於函數上即稱為函數指標。

2.概念

2.1指標變數的概念

我們如果以組合語言的角度觀之,其C語言編譯出來的東西最終會變成機器碼,如果當我們使用指標變數的時候,我們會將某指標變數如「*ptr」給予一地址,可能會類似如下

char count;
char *ptr;

ptr = &count;

*ptr = DATA_TMP;

如此我們可以說「*ptr」=「count」,其組合語言(偽代碼)可能如

	MOVLW	0x20;假設0x20是count地址
	MOVWF	ptr;將地址存入  
	MOVF	DATA_TMP,ptr;將DATA_TMP放入ptr中

好吧!類似這樣的代碼希望可以理解,總之透過一個地址的容器我們可以間接存取到該原始變數之內容。

2.2函數指標的概念

在提函數指標之前,我們必須先建立一個觀念,即函數在C語言中,其入口本身為一個地址,相信在任何程式語言上均是如此,只因為C語言提供指標這項工具,才得以強化這個概念,所以說既然他也是一個地址,所以也可以使用指標來進行操作。

例如我們可能會有一段代碼,如下:

C語言偽代碼		組合語言偽代碼
void foo(void)		foo:
	{				
	...		...
	...		...
	return;		ret;
	}

int main(void)		main:
	{
	foo();		call foo;
	...		...	
	..		..
	}

然而我們可以將foo();這個呼叫理解成跳躍至foo這個位置執行,直到return為止,所以說,我們可以利用指標的方式,代換不同的地址,使其呼叫不同的函數,我們可以類似這樣做

C語言偽代碼				組合語言偽代碼
void foo(void)				foo:		;假設foo地址為0x20
	{				...											...
	...				...
	return;				ret;
	}

int main(void)				main:
	{
	void (*ptr)(void);						
	
	ptr = foo;			movlw 0x20;	;假設foo地址為0x20
					movwf ptr;
	(*ptr)();			call ptr;
	...				...	
	..				..
	}

所以說,當函數呼叫的時候,CPU僅只是跳躍到某地址繼續執行程式,故我們可以透過指標方式操作函數。

3.函數指標宣告

函數指標宣告需要注意其型別宣告需要與被代用函數相同,其宣告方式如下

資料回傳型態 (*函數指標名稱) (函數參數);

例如:

void (*function)(void);			//無回傳值及參數
void (*functtion)(uint8, int16);	//無回傳值有兩個參數
uint8 (*function)(uint8);		//有回傳值及一個參數

類似這樣的宣告,即可定義一函數指標,使用時請務必注意需要與呼叫函數相同原型。

Example:

4.其他

其他的部份我想分享一下關於函數指標的一些應用方法

4.1多函數判斷的時候

假設有多個函數需要進行選擇判斷時它的結構可能會像是

然而類似這樣的情況我們就可以使用函數指標來簡化程式,可以變成這樣子

4.2函數回呼Callback的時候

Callback可以再讓我們在某些時候做到一些很方便的事情,例如,今天我在MCU上面設計了一個通訊程式,然而每次進入該通訊程式的時候,此函數會回傳一狀態值給我,進行判斷是否有正常通訊,此時,我們可以在此通訊程式中加入一回呼機制,就是當通訊發生狀態改變時,則呼叫某個函數進行處裡(例如狀態指示)等功能,此功能即可利用函數指標進行設計。

 

什麼?什麼?其他自行發想...XD

發表迴響