全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2212
推到 Plurk!
推到 Facebook!

函式指標問題

答題得分者是:syntax
yshihyu
一般會員


發表:23
回覆:18
積分:8
註冊:2006-11-28

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-06-10 17:03:26 IP:59.104.xxx.xxx 訂閱
<textarea class="cpp" rows="10" cols="60" name="code"> #include using namespace std; typedef enum { Termination, Insert, my_delete, Print, Invalid } menu; typedef void (*mfunc)(void); //--- menu1 ---// void insert_data(void) { cout << "<資料追加>被選擇了。。\n"; } //--- menu2 ---// void delete_data(void) { cout << "<資料刪除>被選擇了。\n"; } //--- menu3 ---// void print_data(void) { cout << "<資料列印>被選擇了。\n"; } //--- menu選擇 ---// menu SelectMenu(void) { int ch; do { cout << "(0) 處理結束\n"; cout << "(1) 資料追加\n"; cout << "(2) 資料削除\n"; cout << "(3) 資料列印\n"; cin >> ch; } while (ch < Termination || ch >= Invalid); return (menu(ch)); } //---main---// int main (void) { menu menu; mfunc pmunu[] = {insert_data, delete_data, print_data}; do{ menu = SelectMenu( ); if (menu > Termination && menu < Invalid) pmunu [menu - 1](); } while (menu != Termination); return(0); } </textarea>
pmunu [menu - 1]();
我改成指針表達
(*(pmunu (menu - 1)))(); // 可正常編譯執行


(*(pmunu (menu - 1)))(); 再改成*(pmunu (menu - 1))(); 就無法編譯
請問這邊多() 括號跟沒有() 差在哪邊 , 為什麼需要多加上( )括號才可以?
謝謝
編輯記錄
yshihyu 重新編輯於 2007-06-10 17:12:17, 註解 無‧
yshihyu 重新編輯於 2007-06-10 17:13:39, 註解 無‧
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-06-10 20:40:30 IP:61.64.xxx.xxx 訂閱
(*(pmunu (menu - 1)))(); 再改成*(pmunu (menu - 1))(); 就無法編譯
請問這邊多() 括號跟沒有() 差在哪邊 , 為什麼需要多加上( )括號才可以?

差在順序,你不懂喔?那你該重新去看 C 或C 語言前幾章,介紹關鍵字與運算法則的基本觀念

這是一個非常新手的問題,不過牽涉到指標,總會讓人先心生畏懼,不過實際上,也不過是括號的遊戲而已

你的定義為
typedef void (*mfunc)(void); 所以使用前要解除 * 號一次,就是將執行處轉成函式真正位址

括號會先做,所以當沒有外括號,
(pmunu (menu - 1)) 會先被處理,然後後面還加上了 (); 所以會被解釋為函式
然後
"*" 會被處理就會解釋成轉址解讀,最後函式傳回值是 void ,對 void 做轉址解讀 ?當然編譯不會過

(*(pmunu (menu - 1)))(); 會先做 (xxx)(); 解釋成一個函式,*(pmunu (menu - 1)) 被解釋成將取得的位址,當成函式位址並執行

以下你也應該要知道吧,這也是基礎,不會就表示,你沒看書

xxx *ABC;

ABC 的值表示某物的位址, *ABC 表示跳到 ABC 記錄的位址取得該位址的值

如果 *ABC 是一個 function ,
*ABC 表示跳到 ABC 記錄的位址取得該位址的值(但是編譯不會過),*ABC(); 表使用該函數





yshihyu
一般會員


發表:23
回覆:18
積分:8
註冊:2006-11-28

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-06-10 20:55:38 IP:59.104.xxx.xxx 訂閱
syntax 謝謝

(*(pmunu (menu - 1)))(); 會先做 (xxx)(); 解釋成一個函式,
*(pmunu (menu - 1)) 被解釋成將取得的位址,當成函式位址並執行
我主要是搞不清楚它們被解釋成什麼 ..

我本來是認為 ,*(pmunu (menu - 1)) (); //這樣就可以做函式呼叫
編輯記錄
yshihyu 重新編輯於 2007-06-10 20:57:50, 註解 無‧
liang
一般會員


發表:0
回覆:2
積分:0
註冊:2002-10-03

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-06-10 21:08:34 IP:211.74.xxx.xxx 未訂閱
syntax 兄解釋的很清楚,造成這樣的結果主要是運算子優先權的問題。
*pFunc() 暫不論 pFunc 是什麼,()函式呼叫優先權大於*取值運算子
(*pFunc)() 的話就不會有上述優先權的問題,因為你已經告訴編譯器了。

syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#5 引用回覆 回覆 發表時間:2007-06-11 16:16:42 IP:61.64.xxx.xxx 訂閱
不客氣
說實在,每個語言的運算優先順序,運算型別轉換順序....等一堆順序,都不盡相同,更不用說編譯器實作也有所差異
所以要是你記不住,也沒人會說妳笨
像我就記不住
但是起碼要知道哪是什麼,在哪裡查資料

不過,寫程式多打幾個字或符號,不會花多少時間,卻可以省下許多麻煩,尤其是日後的除錯,與翻書找資料的時間
因此建議,括號可以多打,就多打,這樣編譯器,不需要計算,就知道你要的順序,編譯起來也比較快,越複雜的式子越是如此
同實際算型別,也最好能在設計時就考慮好,不要出現不同型別交互計算在同一式子內

總之,你先做完,在放進電腦,電腦就不用在多花時間處理,電腦是用來處理
1.重複
2.大量
的「指定」工作,凡是需要電腦「猜」的,大多跑不快算不准,人工智慧就是一例

所以很多程式要計算 log 時,都會直接使用事先計算好的表,而不是去使用 lon(); 這個函式

不過這樣也有缺點,就是設計外的問題,程式無法處理,不像人工智慧一般,還有可能「稍微」處理一下

但是程式沒有「通吃」的,適用就好,就像檔案格式一樣,否則也不會有那麼多種檔案格式來煩人了


===================引 用 yshihyu 文 章===================
syntax謝謝

(*(pmunu (menu - 1)))(); 會先做 (xxx)(); 解釋成一個函式,
*(pmunu (menu - 1)) 被解釋成將取得的位址,當成函式位址並執行
我主要是搞不清楚它們被解釋成什麼 ..

我本來是認為 ,*(pmunu (menu - 1)) (); //這樣就可以做函式呼叫
系統時間:2024-04-24 1:44:27
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!