Re: [問題] 函數指標
※ 引述《purpose (purpose)》之銘言:
→
03/22 21:14,
03/22 21:14
→
03/23 00:10,
03/23 00:10
→
03/23 00:12,
03/23 00:12
其實我也不太懂,尤其是對於 C++。不過就 C 的部份我可以稍微分享一下個人的理解。
int a[3];
就陣列來說,陣列名稱本身的型別是陣列 (如上面宣告的 a 其型別是 "長度為 3 的
int 陣列")。
在 C 標準裡面的規則是在運算時,除非做為 sizeof、取址 (&) 或 _AlignOf (C11)
的運算元,或陣列本身為 register storage,其他運算一律被轉為指向陣列第一個元素
的指標 (a 會轉為 &a[0])。而這個指標不是一個左值 (換句話說是無法被賦值 (=) 的)
依照這個規則,造成我們常理解成:在 C 裡面,一般情況下,陣列名稱就是當作指向第
一個陣列元素的指標在 "用"。甚至因為它不是一個左值,有些人會說它是個常數。
而這邊所指的一般情況甚至包含了我們最常用的陣列元素存取。
例如 a[2] 這個陣列元素存取的運算實際上會被轉為 (&a[0])[2],而 (&a[0])[2] 會用
*(&a[0] + 2) 去解釋。雖然就結果而言我們就是得到了 a 陣列的第三個元素,但是
就標準來說我們是透過指標運算去存取的。
這種種現象可能就是造成為什麼書裡面總是把陣列跟指標弄得一團亂的原因。
那函數呢 ?
void f();
C 標準裡對於函數的企圖在某些層面上跟陣列有點像,但是不幸的是函數本身更複雜。
就函數來說,函數名稱本身的型別是函數 (如上面宣告的 f 其型別就是回傳 void 型態
的函數)。
在 C 標準裡面的規則是在運算時,除非做為 sizeof、取址 (&) 或 _AlignOf(C11)
的運算元,其他運算一律轉為指向函數的指標。而這個指標不是一個左值。
你看看,這不是跟陣列很像嗎?
依照這個規則,造成我們常理解成:在 C 裡面,一般情況下,函數名稱就是當作指向
函數的指標在 "用"。甚至因為它不是一個左值,有些人會說它是個常數。
但是為甚麼上面這句聽起來怪怪的,如果我們呼叫 f() 會發生甚麼事?
就標準而言就是會把 f 轉型成 &f 然後呼叫指標所指向的函數。也就是說 f() 會變成
(&f)() 然後去呼叫 &f 所指向的函數 (阿不就是 f)。
換句話說,就 C 來說,存取陣列元素 ([]) 跟呼叫函數 (()) 概念上都是透過指標。
但是指向的東西本質上卻有很大的不同。
這兩者的差別最容易理解的應該就是 sizeof,因為不論陣列或函數名稱都不會對他自動
轉型,所以我們可以用來分辨其本質的不同。
sizeof(a) 是求陣列 a 所佔據的空間大小,其結果就是整個陣列所佔據的大小,相當和
藹可親。
那 sizeof(f) 呢?
C 標準跟我們說,"不可問、不可說"。對,這是個謎,而你不需要知道。
而陣列跟函數的指標運算還有一個很明顯的不同:
*a 會轉成 *(&a[0]) 去存取 a 陣列第一個元素
那 *f 呢?
照剛剛的規則會變成 *(&f) 然後變成 f,接著又會套用一次同樣的規則,又變成 &f
所以就運算上 *a 跟 a 型態就已經不同,但是 *f == f 而且 *f == &f
更莫名的就是 f == **f 還有 f == *********f
至於 C++ 的話, 我只能跟你說兩者在設計的哲學上就已經不一樣. 但是我不懂 C++ 就
不好說甚麼
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.112.29.148
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1427072788.A.545.html
推
03/23 10:18, , 1F
03/23 10:18, 1F
→
03/23 10:22, , 2F
03/23 10:22, 2F
推
03/23 11:01, , 3F
03/23 11:01, 3F
→
03/23 11:03, , 4F
03/23 11:03, 4F
→
03/23 11:03, , 5F
03/23 11:03, 5F
推
03/23 12:33, , 6F
03/23 12:33, 6F
推
03/23 12:50, , 7F
03/23 12:50, 7F
→
03/23 13:13, , 8F
03/23 13:13, 8F
→
03/23 13:14, , 9F
03/23 13:14, 9F
→
03/23 13:25, , 10F
03/23 13:25, 10F
→
03/23 13:26, , 11F
03/23 13:26, 11F
→
03/23 13:27, , 12F
03/23 13:27, 12F
→
03/23 13:28, , 13F
03/23 13:28, 13F
→
03/23 13:29, , 14F
03/23 13:29, 14F
→
03/23 13:29, , 15F
03/23 13:29, 15F
→
03/23 13:32, , 16F
03/23 13:32, 16F
※ 編輯: Feis (140.112.29.148), 03/23/2015 13:44:00
推
03/23 15:17, , 17F
03/23 15:17, 17F
推
03/23 22:31, , 18F
03/23 22:31, 18F
→
03/23 22:31, , 19F
03/23 22:31, 19F
→
03/23 22:31, , 20F
03/23 22:31, 20F
→
03/23 22:31, , 21F
03/23 22:31, 21F
→
03/23 22:32, , 22F
03/23 22:32, 22F
→
03/23 22:32, , 23F
03/23 22:32, 23F
推
03/25 03:11, , 24F
03/25 03:11, 24F
推
04/05 16:29, , 25F
04/05 16:29, 25F
→
04/05 16:29, , 26F
04/05 16:29, 26F
討論串 (同標題文章)