Re: [心得] Function pointer 原來也可以這樣子搞

看板C_and_CPP (C/C++)作者 (Wayne)時間14年前 (2011/11/13 17:02), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串2/2 (看更多)
※ 引述《keying (意志決定勝負)》之銘言: : 想請問這一題 : 敘述如下 : ※ 引述《sawfish (板釘龍史)》之銘言: : : 學完 pointer 之後,接下來到了 function pointer 的內容,將轉型的概念拿來運 : : 用,竟然可以這樣子搞 O_o ... 範例如下: : : /*****************************************/ : : #include <stdio.h> : : #include <stdlib.h> : : #include <string.h> : : typedef struct struct1 { : : int a,b; : : } struct1; : : typedef struct struct2 { : : int a,b,c; : : } struct2; : : typedef void (*pFunc1)(struct1 *); : : typedef void (*pFunc2)(struct2 *); : : void func1(struct1 *s1) { : : printf("a*b=%d\n", s1->a * s1->b); : : } : : void func2(struct2 *s2) { : : printf("a=%d, b=%d, c=%d\n", s2->a, s2->b, s2->c); : : } : : int main() : : { : : struct1 *s1; : : struct2 *s2; : : pFunc1 pf1; : : s1 = calloc(sizeof(struct2), 1); : : s2 = calloc(sizeof(struct2), 1); : : s1->a = 12; : : s1->b = 12; : : s2->a = 3; : : s2->b = 4; : : s2->c = 5; : : pf1 = func1; : : pf1(s1); : : free(s1); : : s1 = (struct1 *)s2; : : pf1 = (pFunc1)func2; : : pf1(s1); : 雖然這題是錯誤示範 : 但是想知道compiler是如何思考的 : 就原PO所說的執行結果來看 : pf1把func2換成type = pFunc1, s1把s2換成struct1* : 執行"pf1(s1)",仍然有print c=5的值 : 表示 : 1).struct1裡面沒有c的元素, 執行pf1也就是func2, : 卻可以print c=5, compiler自動把s1轉回struct2 ? 程式執行 pf1 其實就是跳到 pf1 所指的地方去執行 而 pf1 所指的是 func2,所以會去執行 func2 的程式碼 你看 func1和 func2 的參數分別是 struct1*, struct2* 實際上就是傳 address func1, func2 內的程式碼會根據 struct 的內容去算 offset, 然後和 address 相加以取到正確的 member 所以並沒有問題 : 2)."pf1 = (pFunc1)func2"這一行,是強制轉換func2的type, : 因為pFunc1 and func2 皆return void : 所以只對傳入值做強制轉換,struct2轉成struct1 : 為什麼這一行compile的時候不會有error? : 如果改成宣告func2為"int func2(struct2 *s2)", 也就是func2會return int : "pf1 = (pFunc1)func2"還能強制轉換嗎 struct1*, struct2* 的互轉 address 值是不會變 address 值指到的內容也不會變 同樣的 fun2 轉成 pFunc1,也只是轉 semantic,實際上的 address 和 address 所指的內容都不變 既然你都明確告知 compiler 你要強制轉型 而 compiler 檢查 pf1 和 (pFunc1)func2 兩者的 type 相同 所以不會有 error 你將 func2 改成有 return int,然後將它轉成 pFunc1 因為是明確寫出來的強制轉型,所以我想 compiler 不會給你 error -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 111.248.167.155 ※ 編輯: imprazaguy 來自: 111.248.167.155 (11/13 17:03)
文章代碼(AID): #1EluU_ha (C_and_CPP)
文章代碼(AID): #1EluU_ha (C_and_CPP)