Как изменить значение локальной статической переменной из внешней функции

#include <stdio.h>

void func() {
   static int x = 0;  // x is initialized only once across three calls of
                      //     func()
   printf("%d\n", x); // outputs the value of x
   x = x + 1;
}

int main(int argc, char * const argv[]) {
   func(); // prints 0
   func(); // prints 1
   func(); // prints 2

   // Here I want to reinitialize x value to 0, how to do that ? <-- this line
   return 0;
}

В приведенном выше коде после трехкратного вызова func() я хочу повторно инициализировать x до нуля. Есть ли способ переинициализировать его до 0?


person Anand    schedule 29.10.2012    source источник
comment
Вы можете объявить func(), чтобы он принимал аргумент, который сообщает ему, следует ли выполнять повторную инициализацию. Например. void func(const bool reset=false) { ... }.   -  person jogojapan    schedule 29.10.2012
comment
@jogojapan ну, технически вы можете объявить глобальный указатель int и установить для него значение x .. но это звучит нежелательно   -  person Ancurio    schedule 29.10.2012
comment
@Ancurio Да, конечно, есть разные способы сделать это. Причина, по которой я предложил параметр функции, заключается в том, что он сохраняет высшую власть над значением x с func, что уместно, учитывая, что это локальная статическая переменная.   -  person jogojapan    schedule 29.10.2012


Ответы (3)


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

Если это первое, вы можете сделать это следующим образом:

void func() {
  static int x = 0;
  printf("%d\n", x);
  x = (x + 1) % 3;
}

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

class Func
{
  int x;
  // disable copying

public:
  Func() : x(0) {}

  void operator() {
    printf("%d\n", x);
    x = x + 1;
  }

  void reset() {
    x = 0;
  }
};

Func func;

Вы должны сделать его либо некопируемым, чтобы два объекта не увеличивали два разных счетчика (или сделать его одноэлементным), либо сделать счетчик статическим членом, чтобы каждый объект увеличивал один и тот же счетчик. Теперь вы используете его так:

int main(int argc, char * const argv[]) {
  func(); // prints 0
  func(); // prints 1
  func(); // prints 2

  func.reset();
  return 0;
}
person Andrzej    schedule 29.10.2012

Вы можете присвоить func() адрес переменной указателю, который виден извне func().

Или у вас может быть специальный параметр, который вы можете передать func(), чтобы указать ему сбросить переменную.

Но на самом деле весь смысл объявления x внутри func() состоит в том, чтобы сделать его видимым только внутри тела func(). Если вы хотите иметь возможность изменять x, определите его в другом месте. Поскольку вы пишете на C++, вероятно, x имеет смысл быть статическим членом некоторого класса.

person Keith Thompson    schedule 29.10.2012

Вы не можете. Это локальная статическая переменная, невидимая за пределами func().

Вы можете использовать:

  1. Global static (обычно не рекомендуется).
  2. Передайте его через параметр ссылки/указателя или верните по ссылке.
person Eric Z    schedule 29.10.2012