2009-08-17 16 views

risposta

10

per rispondere alla tua domanda su quando potrebbero essere utilizzati, un paio di semplici esempi:

Un puntatore statico potrebbe essere utilizzato per implementare una funzione che restituisce sempre lo stesso buffer per il programma, assegnando la prima volta si chiama:

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

Un extern (cioè globale) puntatore potrebbe essere utilizzato per consentire ad altre unità di compilazione di accedere ai parametri principali:

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

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

perché buff è char? non potrebbe essere int? – tetris

+2

È char perché è un esempio. Potrebbe essere int, doppio, yada yada. –

2

Vedi How to correctly use the extern keyword in C

E Internal static variables in C, would you use them?

Essenzialmente, "statica" (in serie C) utilizzato in una funzione consente una variabile non essere spazzato via come farebbe normalmente una volta le estremità funzionali (cioè, mantiene il suo vecchio valore ogni volta che viene chiamata la funzione). "Extern" espande l'ambito di una variabile in modo che possa essere utilizzata in altri file (cioè, lo rende una variabile globale).

2

risposta breve. Statico è persistente quindi se lo si dichiara in una funzione, quando si chiama di nuovo la funzione il valore è lo stesso dell'ultima volta. Se lo dichiari globalmente, è solo globale in quel file.

Extern significa che è stato dichiarato globalmente ma in un file diverso. (fondamentalmente significa che questa variabile esiste e questo è ciò che è definito come).

7

Risposta breve: non esistono. C99 6.7.1 dice "Al massimo, un identificatore di classe di memoria può essere fornito negli specificatori di dichiarazione in una dichiarazione". extern e static sono entrambi specificatori di classe di archiviazione.

+3

Questo sta rispondendo a un'interpretazione sorprendente della domanda.Mi aspetterei che la domanda significhi: quali sono gli usi dei puntatori statici e quali sono gli usi dei puntatori esterni (poiché so che entrambi esistono, ignorerei tale qualifica). –

2

Supponiamo di avere un puntatore che voglio rendere disponibile globalmente a più unità di traduzione. Voglio definire in un posto (foo.c), ma consentire più dichiarazioni per esso in altre unità di traduzione. La parola chiave "extern" dice al compilatore che questa non è la che definisce la dichiarazione per l'oggetto; la definizione attuale apparirà altrove. Rende solo il nome dell'oggetto disponibile al linker. Quando il codice è compilato e collegato, tutte le diverse unità di traduzione faranno riferimento allo stesso oggetto con quel nome.

Supponiamo di disporre anche di un puntatore che desidero rendere globalmente disponibile per le funzioni all'interno di un singolo file di origine, ma non di renderlo visibile ad altre unità di traduzione. Posso usare la parola chiave "statica" per indicare che il nome dell'oggetto non deve essere esportato nel linker.

Supponiamo di avere anche un puntatore che voglio usare solo all'interno di una singola funzione, ma che mantenga il valore di quel puntatore tra le chiamate di funzione. Posso ancora usare la parola chiave "statica" per indicare che l'oggetto ha estensione statica; la memoria per esso verrà allocata all'avvio del programma e non verrà rilasciata fino alla fine del programma, quindi il valore dell'oggetto verrà mantenuto tra le chiamate di funzione.

/** 
* 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; 
}