2009-08-17 108 views

回答

10

要回答你什麼時候可以使用他們的問題,幾個簡單的例子:

靜態指針可以用來實現總是返回相同的緩衝區程序的功能,第一次分配它它被稱爲:

char * GetBuffer() { 
    static char * buff = 0; 
    if (buff == 0) { 
     buff = malloc(BUFSIZE); 
    } 
    return buff; 
} 

一個外部的(全球)指針可以用來允許其他編譯單元訪問的主要參數:

extern int ArgC = 0; 
extern char ** ArgV = 0; 

int main(int argc, char ** argv) { 
    ArgC = argc; 
    ArgV = argv; 
    ... 
} 
+0

爲什麼buff是char?不可能是int嗎? – tetris 2012-05-23 21:27:10

+2

它是char,因爲它是一個例子。它可以是int,double,yada yada。 – 2013-03-07 19:55:15

2

簡短的回答。 靜態是持久的,所以如果你在一個函數中聲明它,當你再次調用該函數時,該值與上次相同。如果你在全球範圍內聲明它,它只是在該文件中是全局的。

Extern表示它在全局聲明,但在不同的文件中。 (它基本上意味着這個變量確實存在,這就是它的定義)。

7

簡短的回答:他們不存在。 C99 6.7.1表示「最多可以在聲明中的聲明說明符中給出一個存儲類說明符」。 externstatic都是存儲類別說明符。

+3

這回答了這個問題的一個令人驚訝的解釋。我希望問題的意思是:靜態指針的用途是什麼,以及extern指針的用途是什麼(因爲我知道兩者都存在,我會忽略該限定)。 – 2009-09-16 15:02:03

2

假設我有一個指針,我想使全局可用於多個翻譯單元。我想定義爲它在一個地方(foo.c),但允許在其他翻譯單位多個聲明。 「extern」關鍵字告訴編譯器,這不是定義對象的聲明的;實際的定義將出現在其他地方。它只是使對象名稱可用於鏈接器。當代碼被編譯並鏈接時,所有不同的翻譯單元將通過該名稱引用相同的對象。

假設我也有一個指針,我希望在單個源文件中使函數全局可用,但對其他翻譯單元不可見。我可以使用「static」關鍵字來指示對象的名稱不會被導出到鏈接器。

假設我也有一個指針,我只想在單個函數中使用,但是在函數調用之間保留了該指針的值。我可以再次使用「static」關鍵字來指示對象具有靜態範圍;它的內存將在程序啓動時分配,直到程序結束才釋放,所以對象的值將在函數調用之間保留。

/** 
* foo.h 
*/ 
#ifndef FOO_H 
#define FOO_H 

/** 
* Non-defining declaration of aGlobalPointer; makes the name available 
* to other translation units, but does not allocate the pointer object 
* itself. 
*/ 
extern int *aGlobalPointer; 

/** 
* A function that uses all three pointers (extern on a function 
* declaration serves roughly the same purpose as on a variable declaration) 
*/ 
extern void demoPointers(void); 
... 
#endif 

/** 
* foo.c 
*/ 
#include "foo.h" 

/** 
* Defining declaration for aGlobalPointer. Since the declaration 
* appears at file scope (outside of any function) it will have static 
* extent (memory for it will be allocated at program start and released 
* at program end), and the name will be exported to the linker. 
*/ 
int *aGlobalPointer; 

/** 
* Defining declaration for aLocalPointer. Like aGlobalPointer, it has 
* static extent, but the presence of the "static" keyword prevents 
* the name from being exported to the linker. 
*/ 
static int *aLocalPointer; 

void demoPointers(void) 
{ 
    /** 
    * The static keyword indicates that aReallyLocalPointer has static extent, 
    * so the memory for it will not be released when the function exits, 
    * even though it is not accessible outside of this function definition 
    * (at least not by name) 
    */ 
    static int *aReallyLocalPointer; 
}