Внешние и статические указатели в языке C


Привет что может быть использование статического и внешнего указателя ?? если они имеются

5 7

5 ответов:

Чтобы ответить на ваш вопрос о том, когда они могут быть использованы, приведу несколько простых примеров:

Статический указатель можно использовать для реализации функции, которая всегда возвращает один и тот же буфер программе, выделяя его при первом вызове:

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

Указатель extern (т. е. глобальный) может использоваться для предоставления другим блокам компиляции доступа к параметрам main:

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

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

Короткий ответ: они не существуют. C99 6.7.1 гласит: "В описателях объявлений в объявлении может быть указан не более одного спецификатора класса хранения". extern и static являются спецификаторами классов хранения.

Смотрите Как правильно использовать ключевое слово extern в C

И внутренние статические переменные в C, вы бы их использовали?

По существу, "static" (в стандарте C) при использовании в функции позволяет переменной не быть стертой, как это обычно происходит после завершения функции (т. е. она сохраняет свое старое значение каждый раз, когда функция вызывается). "Extern" расширяет область действия переменной, чтобы ее можно было использовать в других файлах (т. е. она становится глобальной переменной).

Предположим, у меня есть указатель, который я хочу сделать глобально доступным для нескольких единиц перевода. Я хочу определить его в одном месте (foo.c), но допускает несколько объявлений для него в других единицах перевода. Ключевое слово "extern" сообщает компилятору, что это не объявление defining для объекта; фактическое определение появится в другом месте. Это просто делает имя объекта доступным для компоновщика. Когда код компилируется и связывается, все разные единицы перевода будут ссылаться на один и тот же объект под этим именем.

Предположим, что у меня также есть указатель, который я хочу сделать глобально доступным для функций в одном исходном файле, но не иметь его видимым для других единиц перевода. Я могу использовать ключевое слово "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;
}

Короткий ответ. Статика является постоянной, поэтому, если вы объявите ее в функции, при повторном вызове функции значение будет таким же, как и в прошлый раз. Если вы объявите его глобально, он будет только глобальным в этом файле.

Extern означает, что он объявлен глобально, но в другом файле. (это в основном означает, что эта переменная действительно существует, и это то, что ее определяют как).