Как реализовать: сделать что-нибудь, если функция еще не была вызвана? - PullRequest
3 голосов
/ 01 мая 2019

Есть ли способ в C, который вы можете сделать: если функция не была вызвана ранее в предыдущей части кода, затем вызвать ее, в противном случае, если она была вызвана раньше, не вызывать ее?

Вот какой-то код:

while (function hasn't been called)
{
    // do some code
}
else (call the function)
{
    // do something else
}

Что-то в этом роде?

Ответы [ 2 ]

6 голосов
/ 01 мая 2019

Ну, это довольно просто. Просто используйте статическую переменную.

void foo() {
    static int hasBeenCalled = 0;
    if(!hasBeenCalled) {
        /* Do stuff */
        hasBeenCalled = 1;
    }
}

Вам не нужно выполнять инициализацию для глобалов и статики, так как они имеют значение по умолчанию 0, а локальные переменные - нет. Но имхо это выглядит намного лучше. Глобалы и статика используются так редко, что я не вижу смысла в использовании этой «функции».

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

int hasBeenCalled = 0;

void foo() {
    while(!hasBeenCalled) {
        /* Do stuff that eventually calls bar() */
    }
}

void bar() {
    hasBeenCalled=1;
    /* Do stuff */
}

int main() {
    foo();
}
0 голосов
/ 02 мая 2019

К сожалению, код, который вы используете для иллюстрации своих намерений, не очень ясен. Но вы спросили это:

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

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

static void foo_first_time(void);
static void foo_after_first_time(void);

void (*foo)(void) = foo_first_time;

static void foo_first_time(void) {
    foo = foo_after_first_time;
    // do some code
    // ...
}

static void foo_after_first_time(void) {
    // do something else
    // ...
}

Теперь вызывающая сторона просто вызывает foo() в обычном режиме. Первый раз вызовет foo_first_time, но последующие вызовы вызовут foo_after_first_time.

int main () {
    foo(); // calls foo_first_time
    foo(); // calls foo_after_first_time
    foo(); // calls foo_after_first_time again
}
...