Как сохранить маркировки goto в массиве и затем перейти им?

Вы также можете использовать StringUtils.isNoneEmpty("") для проверки, является нулевым или пустым.

18
задан Ciro Santilli 新疆改造中心法轮功六四事件 24 June 2015 в 10:24
поделиться

10 ответов

Это возможно с функцией GCC, известной как « метки как значения ».

void *s[3] = {&&s0, &&s1, &&s2};

if (n >= 0 && n <=2)
    goto *s[n];

s0:
...
s1:
...
s2:
...

Работает только с GCC!

40
ответ дан 30 November 2019 в 05:38
поделиться

Нет прямого способа сохранить кодовые адреса для перехода в C. Как насчет использования switch.

#define jump(x)  do{ label=x; goto jump_target; }while(0)
int label=START;
jump_target:
switch(label)
{
    case START:
        /* ... */
    case LABEL_A:
        /* ... */
}

Вы можете найти аналогичный код, созданный каждым бессековым парсером / генератором конечного автомата. Такому коду нелегко следовать, поэтому, если он не сгенерирован, или ваша проблема не является наиболее серьезной. легко описывается конечным автоматом, я бы не рекомендовал этого делать.

12
ответ дан 30 November 2019 в 05:38
поделиться

goto требуется метка времени компиляции.

Из этого примера кажется, что вы реализуете какой-то конечный автомат. Чаще всего они реализуются как конструкция switch-case:

while (!finished) switch (state) {
  case s0:
  /* ... */
  state = newstate;
  break;

  /* ... */
}

Если вам нужно, чтобы она была более динамичной, используйте массив указателей на функции.

17
ответ дан 30 November 2019 в 05:38
поделиться

В обычном стандарте C это невозможно, насколько мне известно. Однако есть расширение в компиляторе GCC, , описанное здесь , которое делает это возможным.

Расширение вводит новый оператор && , который принимает адрес метки, которая затем можно использовать с оператором goto .

6
ответ дан 30 November 2019 в 05:38
поделиться

Это то, для чего нужны операторы switch .

switch (var)
{
case 0:
    /* ... */
    break;
case 1:
    /* ... */
    break;
default:
    /* ... */
    break;  /* not necessary here */
}

Обратите внимание, что они не обязательно транслируются компилятором в таблицу переходов.

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

5
ответ дан 30 November 2019 в 05:38
поделиться

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

2
ответ дан 30 November 2019 в 05:38
поделиться

не могли бы вы использовать указатели на функции вместо goto?

Таким образом вы можете создать массив функций для вызова и вызова соответствующей.

8
ответ дан 30 November 2019 в 05:38
поделиться

Для простого ответа, вместо того, чтобы заставлять компиляторы делать настоящие глупости, изучите хорошие методы программирования.

2
ответ дан 30 November 2019 в 05:38
поделиться

Вы можете посмотреть setjmp / longjmp.

3
ответ дан 30 November 2019 в 05:38
поделиться

Токенизатор? Похоже, для чего был создан gperf. Нет, правда, взгляни.

1
ответ дан 30 November 2019 в 05:38
поделиться