Использование статических переменных внутри функций - PullRequest
3 голосов
/ 20 декабря 2010

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

Например:

int count(){
    static int n;
    n = n + 1;
    return n;
}

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

Надеюсь, это достаточно ясно, спасибо!

Ответы [ 4 ]

4 голосов
/ 20 декабря 2010
void first_call()
{
   static int n = 0;

   if(!n) {
     /* do stuff here only on first call */
     n++;
   }

   /* other stuff here */
}
2 голосов
/ 20 декабря 2010

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

0 голосов
/ 21 декабря 2010

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

static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&mut);
/* critical code comes here */
pthread_mutex_unlock(&mut);

Это не будет работать с переменной auto.

POSIX имеет такие static инициализаторы для мьютексов, условий и некогда переменных.

0 голосов
/ 20 декабря 2010

Я использовал статические переменные как способ управления выполнением другого потока.

Например, поток # 1 (основной поток) сначала объявляет и инициализирует управляющую переменную, такую ​​как:

/* on thread #1 */
static bool run_thread = true;
// then initialize the worker thread

и затем он запускает выполнение потока # 2, который будет выполнять некоторую работу, пока поток # 1 не решит остановить его:

/* thread #2 */
while (run_thread)
{
  // work until thread #1 stops me
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...