2010-07-01 4 views
4

Каковы различия между статическими и внешними переменными? Каковы преимущества создания статической переменной? Почему мы предпочитаем делать внешние переменные в многофункциональных программах? В книге говорится, что еще она очень поздно инициализируется. Я не понимаю.статические и внешние переменные

+3

C# и C++ - очень разные языки. Так как понятие «внешние» переменные не существует в C#, я предполагаю, что это о C++. –

+2

В какой книге вы тоже обращаетесь? Было бы удобно узнать имя/ISBN, чтобы выяснить ваш вопрос (страница также будет полезна). – XIII

+0

let us c by yashwant kanetkar и turbo c by robert lafore –

ответ

24

Проблема в том, что в статическом состоянии C могут быть разные значения. Я попытаюсь дать обзор различных ситуаций в следующих параграфах.

Если переменная определена вне функции, ее можно использовать всеми функциями в файле. Иногда также называется «глобальная переменная». Это означает, что для всего файла есть только один экземпляр этой переменной. Также имя переменной сохраняется в результирующем файле .OBJ. Последнее важно, поскольку, если другой файл также определяет переменную с тем же именем вне функции, компоновщик предполагает, что в обоих случаях она является одной и той же переменной и объединяет их. Чтобы сделать это более ясным, лучше добавить ключевое слово «extern» к одной из переменных. В этом случае мы говорим, что объявляем переменную, а не определяем ее. Это дополнительный сигнал для компилятора/компоновщика, чтобы указать, что мы действительно хотим ссылаться на глобальную переменную, определенную где-то в другом месте.

Если вы хотите определить глобальную переменную, но не хотите, чтобы она была доступна другим файлам, добавьте ключевое слово static раньше. Ключевое слово static сообщает компилятору, что имя переменной не должно храниться в файле .OBJ. Это означает, что два файла .C по следующей строке:

static long MyGlobalVariable; 

каждый будет иметь свою собственную переменную. Обе переменные будут называться MyGlobalVariable.

Если вы определяете переменную внутри функции, она становится локальной переменной. Он возникает, если функция вызывается и снова исчезает после завершения функции. В некоторых ситуациях вы хотите сохранить значение переменной между вызовами функций. Вы можете сделать это, используя глобальную переменную (вместо локальной переменной), но затем эта переменная становится доступной для всех функций в файле, которые вам не обязательно нужны. В этом случае вы можете поставить статический ключевое слово перед переменной, например:

void MyFunction() 
{ 
static long MyLocalVariable = 0; 
++MyLocalVariable; 
} 

Первый раз, когда функция вызывается, MyLocalVariable будет «создан» и инициализируется значением 0. В конце функции , переменная не уничтожается, а сохраняется. Поэтому в следующий раз, когда вы вызовете эту функцию, значение переменной будет равно 1, а не нулю.

В C действительно неважно, поставите ли вы переменную вне функции (как глобальную переменную) или определите ее как статическую внутри функции. Единственная разница в том, где можно получить доступ к переменной.

В C++ все совсем по-другому. Если вы пишете это (вне функции):

MyClass MyGlobalVariable; 

MyGlobalVariable будет построен (это: конструктор будет выполняться) в начале приложения, прежде чем даже основной называется. Однако у вас нет реального контроля над порядком, в котором построены все глобальные переменные. Так что, если другой файл содержит следующее:

MyOtherClass MySecondGlobalVariable; 

Вы не можете знать наверняка, будет ли построен MyGlobalVariable или MySecondGlobalVariable первым. Это может вызвать проблемы, если конструктор одного из них полагается на наличие (построение) другого.

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

void MyFunction() 
{ 
static MyClass MyStaticVariable; 
} 

Тогда MyStaticVariable будет построен первый раз, когда вызывается функция. При такой конструкции, вы можете написать что-то вроде этого:

MyClass &getMyClass() 
{ 
static MyClass MySelf; 
return MySelf; 
} 

И мы реализовали одиночки, где мы имеем контроль над когда он построен. В первый раз, когда нам это нужно, он построен.

Честно говоря, этот подход является довольно упрощенным, поскольку это может привести к проблемам в многопоточных приложениях. В этом случае есть и другие трюки.

+0

Вопрос только с тегом C сейчас. –

+0

О примере, который вы указали, если я перезапускаю программу, первая строка статическая long MyLocalVariable = 0; , который делает свое значение 0. Когда было его значение 1, то? –

+0

После строки ++ MyLocalVariable ее значение будет равно 1. Если мы снова запустим функцию позже, значение будет равно 1, а после строки ++ MyLocalVariable значение будет равно 2. И так далее. Важно убедиться, что инициализация нуля выполняется только при первом вводе функции (точнее, в момент создания переменной). – Patrick

-3

«Статический» более или менее означает, что «это всегда будет существовать». В зависимости от контекста, вы получите разные результаты:

static int global_variable; 
void function() 
{ 
     static int global_function_variable; 
} 

class foo 
{ 
     static void function() 
     { 
      static int foo_function_variable; 
      //... 
     } 
     static int foo_variable; 
} 

global_variable - только когда-либо видимые в «ЕП». (Поскольку заголовки более или менее скопированы, это означает статический глобальный заголовок существует в виде отдельной переменных для всех CPP файлов, он включен в?)

global_function_variable создаются в первый раз function называется, и будет продолжать существуют на протяжении всей жизни программы. Значение сохраняется, поэтому, если вы измените его на один вызов функции, следующий вызов функции будет использовать измененную переменную.

foo::function() - это функция, которую можно назвать глобальной функцией; вам не нужно иметь экземпляр foo, чтобы позвонить ему. Это означает, что у него нет действительного указателя this. Аналогично, foo_variable существует, даже если нет никаких foo объектов. Все объекты foo имеют одинаковые foo_variable - если вы меняете его на один объект, все остальные объекты «видят» изменение.

foo_function_variable ведет себя, я думаю, точно так же, как global_function_variable.

Основная идея заключается в extern контролировать связь переменной: От MSDN:

// specifying_linkage1.cpp 
int i = 1; 
void other(); 

int main() { 
    // Reference to i, defined above: 
    extern int i; 
} 

void other() { 
    // Address of global i assigned to pointer variable: 
    static int *external_i = &i; 

    // i will be redefined; global i no longer visible: 
    // int i = 16; 
} 

extern int global_variable; 

extern может также использоваться, чтобы связать переменную с использованием другого языка, наиболее часто, C.

global_variable - наиболее распространенное использование extern; он говорит, что в другом месте есть переменная, называемая global_variable, и мы будем использовать эту переменную. Где-то вам нужно объявить переменную без ключевое слово extern, или оно никогда не создается.

+1

Могут ли те, кто downvote, прокомментировать, почему? – Narfanator