2010-10-14 45 views
7

試圖瞭解指向函數的指針實際表示什麼?它是函數所在代碼段中的地址嗎?函數指針的指針值代表什麼?

對於例如:這段代碼:

#include <stdio.h> 

void foo(void) 
{ 
} 

int main(void) 
{ 
    int a = 10; 
    printf("a's address: %p\n", &a); 
    printf("foo's address: %p\n", foo); 
    return 0; 
} 

...打印此:

[sh/prog-exercises/adam]:./a.out 
a's address: 0xbfffb414 
foo's address: 0x8048430 

我想我有多麼精確地疊加有點糊塗了/一個進程的堆有涉及ELF數據段/代碼段。任何有用的指針將非常受歡迎。另外,我的第一個問題,所以請溫柔,我真的想學習。謝謝!

回答

5

這是函數入口點的地址 - 它的代碼的開始。 a變量位於堆棧中,因此它的地址顯着不同 - 堆棧和代碼被分配不同的代碼區域,可能相距很遠。

+0

對,所以這裏的輸出表示這個特定函數已經作爲代碼段的一部分加載的位置?有沒有辦法讓C程序打印數據段,代碼段的開始/結束地址? – helpmelearn 2010-10-14 05:37:47

+0

@helpmelearn:是的,這是函數啓動所在的地址。我不知道找到段地址的解決方案,我想這將取決於實施。也許有一些實用程序可以爲任何進程做到這一點。 – sharptooth 2010-10-14 05:42:52

3

這本書中的圖片UNIX: Systems Programming應該說清楚。

在圖的底部,您有您的程序文本(低地址)。可以從您的程序中驗證。這就是foo()所在的地方。

alt text

2

有一點要記住的是,你的代碼是不完全符合標準。如果您使用gcc -Wall -Wextra -pedantic -ansi,您將收到關於打印函數指針的行的投訴。這是因爲該標準不能保證函數指針可以轉換爲void指針。 C被設計用於許多不同的體系結構,如果體系結構是哈佛體系結構(單獨的指令和數據存儲器),則可能有充分的理由使這些指針具有不同的大小。

我想在實踐中它不太可能很重要,但要注意一個好的事實。 Esp當你試圖學習C的私密細節時。