2013-08-25 4 views
0

Недавно в одном из интервью я столкнулся с этим вопросом: «Как статическая переменная сохраняет свое предыдущее значение при вызове функции». Подумал какое-то время, но на самом деле не мог найти никаких убедительных ответов. Может ли кто-нибудь объяснить это? Пробовал делать Google, не мог найти свою информацию.Как статическое сохранение значения по вызову функции

+7

Как глобальная переменная сохраняет свою ценность? –

ответ

0

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

1

Статические переменные (внутри функции или нет) находятся в глобальном пространстве памяти. Они инициализируются при запуске программы и сохраняются для продолжительности программы.


C11 5.1.2 «Все объекты со статической продолжительностью хранения должны быть инициализированы (устанавливаются их начальных значений) перед запуском программы.»

6.2.4.3 «... Срок его службы - это полное выполнение программы, и его сохраненное значение инициализируется только один раз, до запуска программы».

1

Think функции области видимости статические переменные как глобальные переменные, видимыми только в области видимости функции они определены в.

5

Статические переменные хранятся в .data области, где хранятся все глобальные переменные. И эти глобальные и статические переменные распределяются как часть операции exec (т. Е. Создавая новый процесс/разветвляя новый процесс).

  ----------------------- 
     | Command Line Arg | 
     |---------------------| 
     |  Stack   | 
     |  \/    | < Grow downward 
     |---------------------| 
     |  /\    | 
     |  Heap   | < Grows Upward 
     |---------------------| 
     |  .bss   | (Uninitialized global variables) 
     |---------------------| 
     |  .data   | (initialized global/static variables) 
     |---------------------| 
     |  .text   | 
     ----------------------- 

В приведенном выше рисунке .data является областью, где все статические переменные, которые объявляются внутри функции или объявленные как глобальные переменные хранятся. Надеюсь, это поможет.

0

Я даю вам ссылку, которая может помочь вам предположить.

Description on 'static keyword'

+0

Эта ссылка не является ссылкой; Я думаю, вы пропустили 'http: //'. –

+0

Извините за это! –

1

Цитирование стандарта ISO C, пункт 6.2.4 раздела 2:

срок службы объекта представляет собой часть выполнения программы во время хранения, которое гарантированно будет зарезервирован для этого. Объект существует, имеет постоянный адрес и сохраняет его последнее сохраненное значение в течение его времени жизни.

Пункт 3:

Объект, идентификатор объявлен [СНиП] с хранения класса спецификатора статическая, имеет статический срок хранения. Его время жизни - это полное выполнение программы, и ее сохраненное значение инициализируется только один раз, до запуска программы.

Это объясняет, почему это требуется сохранить свое прежнее значение, но не как она делает это (это не работа стандарта сказать реализации, как делать вещи, только то, что они должны делать).

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

Но в основном он хранится в некоторой области памяти, выделенной непосредственно перед запуском функции main, и это не освобождается до тех пор, пока программа запущена и содержимое которой не изменяется, если сама программа не делает этого.

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

4

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

Таким образом, это законно, чтобы сделать это:

int *test_static() 
{ 
    static int func_var = 1234; 
    printf("%d", func_var); 

    return &func_var; // return pointer to int 
} 

int main() 
{ 
    int *i = test_static(); // will print '1234' and point i to func_var 

    // we can't do "func_var = 99;" here, but... 

    *i = 99; 
    test_static(); // will print '99' 

    return 0; 
} 

Я не утверждаю, что мы должны практике это, хотя! ;)

Смежные вопросы