обмен управления между функциями на языке Си - PullRequest
1 голос
/ 28 марта 2011

Учитывая следующий сценарий:

fn (1) вызывает fn (2), затем fn (2) вызывает fn (3), и теперь fn (3) должна передать управление fn (1)вместо fn (2) управление не должно возвращаться снова.

В связи с этим я пытался с goto, но goto не работает между функциями, это только локальный переход.

Я хотел проверить, есть ли какой-либо другой метод, который я мог бы использовать, чтобы отправить элемент управления другой функции

ПРИМЕЧАНИЕ: НИКАКАЯ глобальная переменная, указатель на функции в этом случае не будет работать, согласно моемуразведка

Ответы [ 6 ]

4 голосов
/ 28 марта 2011

Ну, типичный способ сделать это будет:

int fn3() {
  return 1;
}

void fn2() {
  if (fn3())
    return;
  ...
}

Не уверен, если вы ищете что-то более эзотерическое, такое как setjmp / longjmp

2 голосов
/ 28 марта 2011

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

1 голос
/ 28 марта 2011

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

Саймон Тэтхэм написал отличную статью о сопрограммах в C : http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html

1 голос
/ 28 марта 2011

Вы можете использовать setjmp и longjmp для этого - но почти наверняка это действительно плохая идея сделать это на самом деле.У бывших программистов на Фортране (среди прочих) иногда возникают кошмары о том, какой беспорядок вы, похоже, намереваетесь создать.Учитывая время, когда мэйнфрейм, который обслуживал более 300 одновременно работающих пользователей, работал на частоте 20 МГц или около того, в то время было какое-то оправдание, даже если отслеживание событий было беспорядочным.Учитывая нынешние компьютеры, я подвергаю сомнению не только полезность, но и саму разумность наличия вызова функции, который не возвращается (особенно потому, что процессоры теперь оптимизированы для этого случая, поэтому то, что вы запрашиваете, будет медленнее, чем обычные результаты).

1 голос
/ 28 марта 2011
int fn1(void) {
    printf("in fn1 before calling fn2\n");
    fn2();
    printf("in fn1 after calling fn2\n");
    return 0;
}
int fn2(void) {
    printf("in fn2 before calling fn3\n");
    if (1) {
      return fn3();
    }
    printf("in fn2 after calling fn3\n");
    return 0;
}
int fn3(void) {
    printf("in fn3\n");
    return 0;
}
0 голосов
/ 28 марта 2011

Я думаю, вы должны использовать setjmp () и longjmp (). Человек доступен здесь .

В следующем примере показано, как его использовать (из http://en.wikipedia.org/wiki/Setjmp.h#Example_usage):

#include <stdio.h>
#include <setjmp.h>

static jmp_buf buf;

void second(void) {
    printf("second\n");         // prints
    longjmp(buf,1);             // jumps back to where setjmp was called - making setjmp now return 1
}

void first(void) {
    second();
    printf("first\n");          // does not print
}

int main() {   
    if ( ! setjmp(buf) ) {
        first();                // when executed, setjmp returns 0
    } else {                    // when longjmp jumps back, setjmp returns 1
        printf("main\n");       // prints
    }

    return 0;
}

Выход:

second
main
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...