iT邦幫忙

1

C語言中的函數指標

最近在研究函數指標的使用,看到(*func)()與func()是一樣的用法(func為函數指標),不太懂為什麼,因此寫了下段程式,可以看到func與printf一樣,這是預期中的事情,然後*func與func一樣,代表func的指標指向的值(*func)與指標(func)剛好相同?

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int x;
    void (*func)() = printf;
    //scanf("%d", &x);
    func("&func=0x%x, \n func=0x%x, \n*func=0x%x, \
         \n&printf=0x%x, \n printf=0x%x, \n*printf=0x%x,", &func, func, *func, \
         &printf, printf, *printf);
    return 0;
}
/*以下為輸出*/
&func=0x60fefc,
 func=0x401bd0,
*func=0x401bd0,
&printf=0x401bd0,
 printf=0x401bd0,
*printf=0x401bd0,

然後我用debug模式去看0x401bd0位置的值,但看裡面似乎不是0x401bd0啊?所以為什麼(*func)==(func)呢
https://ithelp.ithome.com.tw/upload/images/20200122/20117357DoTIJJGCND.png

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

4
小碼農米爾
iT邦高手 1 級 ‧ 2020-01-23 10:28:49
最佳解答

https://ithelp.ithome.com.tw/upload/images/20200123/20106865ImF0JqyIGq.jpg

一般的指標結構如上圖,執行後結果如下

&b = 0x61ff14
b = 0x61ff18
*b = 0x1
  • &b: 指標自己的地址。
  • b: 指標內儲存的值。
  • *b: 指標指向的地址內儲存的值。

函數指標也是類似的概念,不過有一點比較特別

fptr() 會等同於 (*fptr)()

這樣便可直接使用指標的名稱呼叫函數而不必加星號

他們雖然代表不同的意思,但指向的位址卻是相同的,陣列也有類似的特性

總結:

  • &fptr: 指標自己的地址。
  • fptr: 等同於 *fptr。
  • *fptr: 指標指向的函數地址。

參考文章:
http://yhhuang1966.blogspot.com/2017/09/c.html [五. 函數指標]
https://stackoverflow.com/questions/9552663/function-pointers-and-address-of-a-function

看更多先前的回應...收起先前的回應...
wrxue iT邦好手 1 級 ‧ 2020-01-23 12:44:54 檢舉

那請問要怎麼得到fptr(而不是*fptr)呢?想看函數地址到底是被存到哪裡,然後fptr指向它。

你看看 0x60fefc 這個裡面的值,函數地址應該是存在這裡。

wrxue iT邦好手 1 級 ‧ 2020-01-23 15:24:20 檢舉

我查看了,的確函數地址在 0x60fefc,但若使用*func為何不是得到在0x401bd0的值呢?
或者換另一種方式問:由你舉的例子來說*b會為位置0x61ff18上的值,那*func為何不會是0x401bd0位置上的值呢。

可以把他們看成別名關係

那*func為何不會是0x401bd0位置上的值呢。

函數指標編譯器不會使用一般指標的方式處理

至於為什麼?

只能說是 C 語言的特性吧
因為以邏輯來看的確是蠻奇怪的

陣列也有類似的情況

int x[10];
printf("%d\n%d\n%d", x, &x, &x[0]);

三者的值都一樣。

wrxue iT邦好手 1 級 ‧ 2020-01-23 20:59:38 檢舉

x與&x的我可以理解,只能類比成這樣的狀況了XD,感謝您耐心回答

我要發表回答

立即登入回答