Статическая переменная внутри функции в C

Что будет напечатано? 6 6 или 6 7? И почему?

void foo()
{
    static int x = 5;
    x++;
    printf("%d", x);
}

int main()
{
    foo();
    foo();
    return 0;
}
+89
источник поделиться
13 ответов

Здесь есть два вопроса: время жизни и область действия.

В области переменной отображается имя переменной. Здесь x виден только внутри функции foo().

Время жизни переменной - это период, в течение которого она существует. Если x определено без ключевого слова static, время жизни будет от входа в foo() до возврата от foo(); поэтому он будет повторно инициализирован до 5 при каждом вызове.

Ключевое слово static действует, чтобы продлить время жизни переменной на время жизни программы; например инициализация происходит только один раз, а затем переменная сохраняет свое значение - независимо от того, что это произошло - над всеми будущими вызовами foo().

+140
источник

Выход: 6 7

Причина: статическая переменная инициализируется только один раз (в отличие от автоматической переменной), и дальнейшее определение статической переменной будет обойдено во время выполнения. И если он не инициализируется вручную, он инициализируется значением 0 автоматически. Так,

void foo() {
    static int x = 5; // assigns value of 5 only once
    x++;
    printf("%d", x);
}

int main() {
    foo(); // x = 6
    foo(); // x = 7
    return 0;
}
+32
источник
другие ответы

Связанные вопросы


Похожие вопросы

То же самое, что и следующая программа:

static int x = 5;

void foo()
{
    x++;
    printf("%d", x);
}

int main()
{
     foo();
     foo();
     return 0;
}

Все, что статическое ключевое слово делает в этой программе, это указание компилятору (по существу): "Привет, у меня есть переменная здесь, что я не хочу, чтобы кто-либо еще обращался к ней, не говорите никому другому, что она существует".

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

Я надеюсь, что это поможет

+9
источник

6 7

компилятор устанавливает, что статическая инициализация переменных не происходит при каждом вводе функции

+8
источник

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

+5
источник

Выход будет 6 7. Статическая переменная (независимо от того, внутри или нет) инициализируется ровно один раз, прежде чем выполняется какая-либо функция в этом блоке перевода. После этого он сохраняет свое значение до изменения.

+2
источник

Vadiklk,

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

main()
{
   static int var = 5;
   printf("%d ",var--);
   if(var)
      main();
} 

и ответ 5 4 3 2 1, а не 5 5 5 5 5 5.... (бесконечный цикл), как вы ожидаете. снова, причина статическая переменная инициализируется один раз, когда в следующий раз вызывается main() он не будет инициализирован до 5, поскольку он уже инициализирован в программе. Таким образом, мы можем изменить значение, но не можем повторно инициализировать. То, как работает статическая переменная.

или вы можете рассматривать как хранилище: статические переменные хранятся в разделе данных программы, а переменные, которые хранятся в разделе данных, инициализируются один раз. и до инициализации они сохраняются в разделе BSS.

В свою очередь, автоматические (локальные) переменные хранятся в Stack, и все переменные в стеке повторно инициализируются все время, когда функция вызывается, поскольку для нее создается новая FAR (запись активации функции).

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

Спасибо Джавед

+2
источник

Давайте просто прочитаем статью Википедии о статических переменных...

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

+1
источник

Вы получите 6 7 напечатанных как, как легко проверить, и здесь причина: Когда сначала вызывается foo, статическая переменная x инициализируется до 5. Затем она увеличивается до 6 и печатается.

Теперь для следующего вызова foo. Программа пропускает инициализацию статической переменной и вместо этого использует значение 6, которое было присвоено x в последний раз. Выполнение выполняется как обычно, давая вам значение 7.

+1
источник
6 7

x - глобальная переменная, которая видна только из foo(). 5 - его начальное значение, которое хранится в разделе .data кода. Любая последующая модификация перезаписывает предыдущее значение. В корпусе функции отсутствует код назначения.

+1
источник

6 и 7 Поскольку статическая переменная intialise только один раз, Таким образом, 5 ++ становится 6 при первом вызове     6 ++ становится 7 при 2-м вызове    Примечание. Когда происходит 2-й вызов, значение x равно 6 вместо 5, потому что x является статической переменной.

+1
источник

Выход: 6,7

причина

Объявление x находится внутри foo но инициализация x=5 происходит вне foo !

Нам нужно понять, что

static int x = 5;

это не то же самое, что

static int x;
x = 5;

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

Таким образом, static int x (сфера) часть заявления фактически применяется, когда вы читаете это, где - то внутри функции, и только оттуда вперед, а не над ним внутри функции.

Однако x = 5 (время жизни) часть инструкции является инициализацией переменной и происходит OUTSIDE функции как часть загрузки программы. При загрузке программы изменяется переменная x со значением 5.

Я прочитал это в одном из комментариев: "Кроме того, это не относится к действительно запутанной части, которая заключается в том, что инициализатор пропускается при последующих вызовах". Он пропускается при всех вызовах. Инициализация переменной вне собственного кода функции.

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

Внутри foo утверждение static int x = 5; вряд ли будет генерировать какой-либо код вообще.

Я нашел, что адрес x использует, когда я помещаю функцию foo в мою программу, а затем (правильно) догадался, что это же место будет использоваться, если я снова запустил программу. Частичный снимок экрана ниже показывает, что x имеет значение 5 еще до первого вызова foo.

Break Point before first call to foo

+1
источник

По крайней мере, в С++ 11, когда выражение, используемое для инициализации локальной статической переменной, не является "constexpr" (не может быть оценено компилятором), тогда инициализация должна произойти во время первого вызова функции. Простейший пример - непосредственное использование параметра для инициализации локальной статической переменной. Таким образом, компилятор должен выдать код, чтобы угадать, является ли вызов первым или нет, что, в свою очередь, требует локальной логической переменной. Я скомпилировал такой пример и проверил это, увидев код сборки. Пример может быть таким:

void f( int p )
{
  static const int first_p = p ;
  cout << "first p == " << p << endl ;
}

void main()
{
   f(1); f(2); f(3);
}

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

0
источник

Посмотрите другие вопросы по меткам или Задайте вопрос