Хрестоматия по программированию на Си в Unix


компьютерная помощь в красногорске | купить диплом вуза |

Системные вызовы и взаимодействие с UNIX. Хрестоматия по программированию на Си в Unix - стр. 7


#include <setjmp.h>

jmp_buf jmp; /* контрольная точка */

/* прыгнуть в контрольную точку */ void onintr(nsig){ longjmp(jmp, nsig); }

main(){ int n; n = setjmp(jmp); /* установить контрольную точку */ if( n ) printf( "Рестарт после сигнала %d\n", n); signal (SIGINT, onintr); /* реакция на сигнал */ printf("Начали\n"); ... }

setjmp возвращает 0 при запоминании контрольной точки. При прыжке в контрольную точку при помощи longjmp, мы оказываемся снова в функции setjmp, и эта функция возвращает нам значение второго аргумента longjmp, в этом примере - nsig.

Прыжок в контрольную точку очень удобно использовать в алгоритмах перебора с возвратом (backtracking): либо - если ответ найден - прыжок на печать ответа, либо если ветвь перебора зашла в тупик - прыжок в точку ветвления и выбор другой альтернативы. При этом можно делать прыжки и в рекурсивных вызовах одной и той же функции: с более высокого уровня рекурсии в вызов более низкого уровня (в этом случае jmp_buf

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

6.7.1. Перепишите следующий алгоритм при помощи longjmp.

#define FOUND 1 /* ответ найден */ #define NOTFOUND 0 /* ответ не найден */ int value; /* результат */ main(){ int i; for(i=2; i < 10; i++){ printf( "пробуем i=%d\n", i); if( test1(i) == FOUND ){ printf("ответ %d\n", value); break; } } } test1(i){ int j; for(j=1; j < 10 ; j++ ){ printf( "пробуем j=%d\n", j); if( test2(i,j) == FOUND ) return FOUND; /* "сквозной" return */ } return NOTFOUND; } test2(i, j){ printf( "пробуем(%d,%d)\n", i, j); if( i * j == 21 ){ printf( " Годятся (%d,%d)\n", i,j); value = j; return FOUND; } return NOTFOUND; }

Вот ответ, использующий нелокальный переход вместо цепочки return-ов:

#include <setjmp.h>

jmp_buf jmp; main(){ int i; if( i = setjmp(jmp)) /* после прыжка */ printf("Ответ %d\n", --i); else /* установка точки */ for(i=2; i < 10; i++) printf( "пробуем i=%d\n", i), test1(i); } test1(i){ int j; for(j=1; j < 10 ; j++ ) printf( "пробуем j=%d\n", j), test2(i,j); } test2(i, j){ printf( "пробуем(%d,%d)\n", i, j); if( i * j == 21 ){ printf( " Годятся (%d,%d)\n", i,j); longjmp(jmp, j + 1); } }




Содержание  Назад  Вперед