理解函数指针
在學習函數指針, 我遇到了問題, ?我定義一個指針指向負責打印參數的函數, ?
?1 void (*p)( int ) = Fun;?
好奇該指針存放的是什么(?原以為是函數的入口地址),便調試觀察一下他們的內存, ? Fun的值是?函數入口地址 0x00401030 Fun(int), ? 而p的值是函數指針存放的內容 0x00401005 _Fun。 ? 竟然不一樣。?
? ? ?難道說0x00401005是函數名Fun所存放的內存地址??
?看來我們在弄懂函數指針前, 需要知道函數名是個什么鬼? )
? ? ?首先它是個標識符, 其次它是一個常量指針, 因為當我試圖把 3 賦值給Fun, 編譯器告訴我warning C4047: '=' : 'void (__cdecl *)(int )' differs in levels of indirection from 'const int '。 ?這是一個函數指針。 ? ?我查看下資料, 函數名被使用時總是由編譯器把它轉換為函數指針。 在這里, 函數名標識了一個函數指針常量。
? ? ?接下來,我們探討函數指針是什么鬼??
? ? ?按理論講,函數指針指向函數的入口地址。 查看匯編代碼, 我在調用Fun處設置個斷點, 然后進入這個函數,我發現沒有直接進入,如圖
?@ILT+0(_Fun): 00401005 E9 26 00 00 00 jmp Fun (00401030)?
它是跳轉到我的Fun函數。 ?所以,函數指針指向的是跳轉命令所在地址。 這不就和書本上的矛盾了。 ?我又嘗試了一下strcmp函數, 這是一個庫函數,是否也是這樣呢? ?于是,我寫了一個字符串比較,?
? ??
1 #include <string.h> 2 #include <stdio.h> 3 4 void 5 main () 6 { 7 int (*p)( const char *, const char * ) = strcmp; 8 char *str1 = "afdf"; 9 char *str2 = "afdf"; 10 11 if ( !p( str1, str2 ) ){ 12 printf( "same\n" ); 13 } 14 }調試時進入匯編界面, 在If判斷語句處設置斷點,進入p。我 發現直接進入strcmp函數內,
--- intel\strcmp.asm ---------------------------------------------------------- strcmp: 0040D830 8B 54 24 04 mov edx,dword ptr [esp+4] 0040D834 8B 4C 24 08 mov ecx,dword ptr [esp+8]奇怪,這跟剛才執行跳轉命令不一樣。為什么? ?這是我自己的想法。 ?因為庫函數已經指定了函數所在的路徑, 而用戶函數沒有,所以需要臨時跳轉到用戶函數的入口地址。
最后,歸納一下, ?如果是庫函數, 函數指針指向函數入口處; 如果是用戶函數, 函數指針指向跳轉到用戶函數的指令所在地址。 ? ? 把跳轉指令看作用戶函數的一部分,其實就和書本上的不矛盾。 ? 所以, ?結論是 ?函數指針指定了函數所在內存的位置。
?
? ? ? ? ??
?
轉載于:https://www.cnblogs.com/the-one/p/4671274.html
總結
- 上一篇: 使用静态工厂方法而不是构造器
- 下一篇: 【代码升级】【iCore3 双核心板】例