2009-08-17 20 views

Respuesta

10

Para responder a su pregunta sobre cuándo podrían ser utilizados, un par de ejemplos simples:

Un puntero estática podría ser usado para implementar una función que devuelve siempre el mismo tampón para el programa, la asignación de la primera vez se llama:

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

Un extern (es decir, mundial) puntero podría utilizarse para permitir a otras unidades de compilación para acceder a los parámetros del principal:

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

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

¿por qué buff es char? ¿No podría ser int? – tetris

+2

Es char porque es un ejemplo. Podría ser int, double, yada yada. –

2

Ver How to correctly use the extern keyword in C

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

En esencia, "estática" (en C estándar) cuando se utiliza en una función permite que una variable no ha de ser absorbido como normalmente lo haría una vez que los extremos de funciones (es decir, conserva su valor anterior cada vez que se llama a la función). "Extern" amplía el alcance de una variable para que pueda usarse en otros archivos (es decir, la convierte en una variable global).

2

respuesta corta. La estática es persistente, por lo que si la declara en una función, cuando vuelve a llamar a la función, el valor es el mismo que el de la última vez. Si lo declaras globalmente, solo es global en ese archivo.

Externo significa declarado globalmente pero en un archivo diferente. (Básicamente significa que esta variable existe y esto es lo que se define como).

7

Respuesta corta: no existen. C99 6.7.1 dice "Como máximo, se puede dar un especificador de clase de almacenamiento en los especificadores de declaración en una declaración". extern y static son ambos especificadores de clase de almacenamiento.

+3

Eso es responder a una sorprendente interpretación de la pregunta.Esperaría que la pregunta significara: ¿cuáles son los usos de los punteros estáticos y cuáles son los usos de los punteros externos? (Ya que sé que ambos existen, ignoraría esa calificación). –

2

Supongamos que tengo un puntero que quiero que esté disponible globalmente para varias unidades de traducción. Quiero definir en un solo lugar (foo.c), pero permitir múltiples declaraciones en otras unidades de traducción. La palabra clave "extern" le dice al compilador que esta no es la que define la declaración para el objeto; la definición real aparecerá en otro lugar. Simplemente pone el nombre del objeto a disposición del vinculador. Cuando el código se compila y vincula, todas las diferentes unidades de traducción harán referencia al mismo objeto por ese nombre.

Supongamos que también tengo un puntero que quiero que esté disponible globalmente para funciones dentro de un único archivo fuente, pero que no lo tenga visible para otras unidades de traducción. Puedo usar la palabra clave "estática" para indicar que el nombre del objeto no se debe exportar al enlazador.

Supongamos que también tengo un puntero que quiero usar solo dentro de una sola función, pero que conserva el valor de ese puntero conservado entre las llamadas a funciones. Puedo volver a utilizar la palabra clave "estática" para indicar que el objeto tiene extensión estática; la memoria se asignará al inicio del programa y no se lanzará hasta que finalice el programa, por lo que el valor del objeto se conservará entre las llamadas a funciones.

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