Переход от одного случая к случаю по умолчанию в операторе switch - PullRequest
18 голосов
/ 20 сентября 2011
switch(ch){
          case 'a':
                 //do something, condition does not match so go to default case
                 //don't break in here, and don't allow fall through to other cases.
          case 'b':
                 //..
          case 'c':
                 //..
          case '_':
                 //...
          default:
                 //
                 break;
}

В операторе switch, подобном указанному выше, я вхожу в регистр 'a', я нарушаю только, если условие внутри него возникает, в противном случае я хочу перейти к регистру по умолчанию.Есть ли другой способ сделать это, кроме ярлыков или gotos?

Ответы [ 9 ]

23 голосов
/ 20 сентября 2011

goto За победу

switch (ch) {
    case 'a':
        if (1) goto LINE96532;
        break;
    case 'b':
        if (1) goto LINE96532;
        break;
LINE96532:
    default:
        //
        break;
}
7 голосов
/ 20 сентября 2011

Просто измените порядок дел, чтобы этот случай был последним:

switch(ch){
          case 'b':
                 //..
          case 'c':
                 //..
          case '_':
                 //...
          case 'a':
                 //do something, condition does not match so go to default case
                 if (condition)
                     break;
                 //don't break in here, and don't allow fall through to other cases.
          default:
                 //
                 break;
}
5 голосов
/ 20 сентября 2011

Рефакторинг вашего кода:

int test_char(char ch)
{
  switch(ch) {
    case 'a': if (condition) return 0; break;
    case 'b': // ...
    default: return -1;
  }

  return 1;
}

... 
// defaults processing switch
switch(test_char(ch)) {
  case 0: break; // condition met
  case 1: // default processing
  default: // case not handled by test_char
}

Это также добавляет преимущество гибкости при тестировании нескольких классов обработки по умолчанию. Скажем, у вас есть группа символов [c, d, e, f], которые разделяют некоторую общую логику. Просто верните 2 из test_char () для этих случаев (возможно, после тестирования некоторых условий) и добавьте обработчик case 2: в оператор переключателя обработки по умолчанию.

5 голосов
/ 20 сентября 2011

Если условие не зависит от случаев, зачем помещать его внутрь?

if (!condition){
  // do default
}else{
  switch(ch){
    case 'a':
      // do a
      break;
    ...
  }
}
1 голос
/ 20 сентября 2011

Я не уверен, что это лучший ответ, но здесь он звучит так:

Если вы абсолютно не хотите использовать ярлыки и хотите сохранить дела в их текущем порядке, то выможет продолжаться после случая 'a', а затем проверить, чтобы увидеть, если (ch! = 'a') в начале каждого последующего случая, выполнить оператор, только если условие истинно:

switch(ch){
    case 'a':
        // do something
    case 'b':
    if(ch != 'a') {
        //do something
    }
    //repeat for each subsequent case
    default:
        //do something
    break;
}

Этовероятно, не самый эффективный способ решить вашу проблему, но он должен выполнить то, что вы хотите.

0 голосов
/ 23 октября 2016

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

typedef enum boolean
{
    FALSE = 0, TRUE = 1
} bool;

void pstuff(char input)
{
    bool _skip = FALSE; 
    switch(input)
    {
        case 'a':
            printf("Case a.");
            _skip = TRUE; 
        case 'b': 
            if(!_skip)
            {
                printf("Case b.");
                _skip = TRUE;
            }
        case 'c':       
            if(!_skip)
            {
                printf("Case c.");
                _skip = TRUE; 
            }
        //...
        default: 
            printf("Done!\n"); //Always gets printed.

    }   
}
0 голосов
/ 15 сентября 2015

прыжки по умолчанию

  • использовать пустой регистр букв чуть выше значения по умолчанию (с очевидным именем)
  • Используйте goto case "case-labelname", чтобы перейти к стандартному значению, а затем упасть до него.

пример

    switch (VAR)
{
    case "a":
        // dO STUFF !
    if(COND)
            goto case "DFLT";
        // dO STUFF !
        break;
    case "B":
        // dO STUFF !
        break;
    case "C":
        // dO STUFF !
    IF(COND)
            goto case "DFLT";
        break;
    case "DFLT":
    default:

       // dO DEFAULT
        break;
}
0 голосов
/ 08 августа 2014

Вот что я сделал:

char ucResult = 1;
switch(ch){
      case 'a':
          if(ucResult){
             // do something
             if(error) ucResult = 0;
          }
      case 'b':
          if(ucResult){
             // do something
             if(error) ucResult = 0;
          }
      case 'c':
          if(ucResult){
             // do something
             if(error) ucResult = 0;
          }
      case '_':
          if(ucResult){
             // do something
             if(error) ucResult = 0;
          }
      default:
             //
             break;
}

С этой структурой вы можете переключиться на случай по умолчанию из любых предыдущих случаев. Удобно и для разрыва внешних петель.

0 голосов
/ 20 сентября 2011

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

int default_true = 0;
switch (case_value)
{
    case 'a': /* if the condition is true, set the default_true flag */

    case 'b': /* if the condition is true, set the default_true flag */

    //...

    default: default_flag = 1; // set the default_true flag to true
}

if (default_flag)
{
    //place your "default" code here rather than inside the switch statement
    //this prevents code reduplication
}
...