Преобразование расширения диапазона корпуса GNU в стандарт C - PullRequest
7 голосов
/ 29 марта 2012

Расширение диапазона регистра GNU допускает диапазоны регистра в операторах switch:

switch (value) {
    case 1 ... 8:
        printf("Hello, 1 to 8\n");
        break;
    default:
        printf("Hello, default\n");
        break;
}

Как бы вы конвертировали это в стандартный C (c99 или c89)? Добавить отдельные заявления случая?

Редактировать: Как бы вы обрабатывали очень большие операторы switch конкретно?

Ответы [ 4 ]

7 голосов
/ 29 марта 2012
switch(value) 
{
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
        printf("Hello, 1 to 8\n"); 
        break;     
    default:         
        printf("Hello, default\n");         
        break; 
} 

РЕДАКТИРОВАТЬ: Чтобы ответить на комментарий.
Если у вас слишком много вариантов, вы можете рассмотреть возможность замены switch-case на if-else конструкций. Это может быть намного чище, сжато и читабельно.

if (value >=1 && value <= 8) 
{    
    printf("Hello, 1 to 8\n"); 
} 
else 
{   
    printf("Hello, default\n"); 
}  
3 голосов
/ 29 марта 2012

Я бы использовал оператор if:

if (value >=1 && value <= 8) {
    printf("Hello, 1 to 8\n");
} else {
    printf("Hello, default\n");
} 

Затем вы можете добавить дополнительные операторы else if, если требуется больше диапазонов,

2 голосов
/ 29 марта 2012

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

typedef void(*func_t)(void);

#define CASES_N 9

void func0 (void)
{
  printf("Hello, 0\n");
}

void func1 (void)
{
  printf("Hello, 1 to 8\n");
}

static const func_t execute [CASES_N] =
{
  &func0,
  &func1,
  &func1,
  &func1,
  &func1,
  &func1,
  &func1,
  &func1,
  &func1
};

int main()
{
  if(what < CASES_N)
  {
    execute[what]();
  }
  else
  {
    printf("Hello, default\n");
  }
}

Этот код в основном такой же, как и оператор переключателя, оптимизированный для компилятора.

2 голосов
/ 29 марта 2012

Если на большом расстоянии вы могли бы сделать, немного грязно, но,

switch(what) {
case 1:
    /* do 1 */
    break;
case 2:
    /* do 2 */
    break;
default:
    if (what > 31 && what < 127) {
         /* do 32 to 126 */
    }
}

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

Будьте очень строги с вложенностью. Если по какой-то причине вам нужен переключатель, то лучше, чем выше:

if (value > 31 && value < 127) {
  /* Do something */
} else {
    switch (value) {
    case 1:
        ...
    }
}

Ах, простите за редактирование снова. Это будет чище.

if (value > 31 && value < 127) {
  /* Do something */
} else if (value > 127 && value < 178) {

} else if ( ...

}

switch (value) {
case 1:
    ...
}
...