使用if语句而不是默认的switch case

时间:2016-02-05 19:32:57

标签: c if-statement optimization switch-statement

在打开switch case之前使用if语句并避免使用default关键字是否正确? 例如,我想要一个程序,它将一个月的数量作为输入,并告诉你它的名字。这是使用switch case语句的代码:

#include <stdio.h>
#include <stdlib.h>

main() {
    int month;
    printf("Insert the number of the month and the program will return its name");
    scanf("%i", &month);
    switch (month) {
      case (1):
        printf("The month is January");
        break;
      case (2):
        printf("The month is February");
        break;
      case (3):
        printf("The month is March");
        break;
      case (4):
        printf("The month is April");
        break;
      case (5):
        printf("The month is May");
        break;
      case (6):
        printf("The month is June");
        break;
      case (7):
        printf("The month is July");
        break;
      case (8):
        printf("The month is August");
        break;
      case (9):
        printf("The month is September");
        break;
      case (10):
        printf("The month is October");
        break;
      case (11):
        printf("The month is November");
        break;
      case (12):
        printf("The month is December");
        break;
      default:
        printf("not valid");
    }
    system("pause");
    return 0;
}

然后,我想知道我是否可以将非有效性条件放在if语句而不是default关键字中。对我而言似乎是正确的,因为我想在程序执行switch case语句之前验证该值。你怎么想,这是对的吗?如果我不要求太多,请你告诉我为什么?

包含if语句的代码:

#include <stdio.h>
#include <stdlib.h>

main() {
    int month;
    printf("Insert the number of the month and the program will return its name");
    scanf("%i", &month);
    if (month >= 1 && month <= 12) {
        switch (month) {
          case (1):
            printf("The month is January");
            break;
          case (2):
            printf("The month is February");
            break;
          case (3):
            printf("The month is March");
            break;
          case (4):
            printf("The month is April");
            break;
          case (5):
            printf("The month is May");
            break;
          case (6):
            printf("The month is June");
            break;
          case (7):
            printf("The month is July");
            break;
          case (8):
            printf("The month is August");
            break;
          case (9):
            printf("The month is September");
            break;
          case (10):
            printf("The month is October");
            break;
          case (11):
            printf("The month is November");
            break;
          case (12):
            printf("The month is December");
            break;
          default:;
        }
    } else {
        printf("not valid");
    }
    system("pause");
    return 0;
}

谢谢你,对不起我的英语,但这不是我的母语。如果我没有清楚地解释自己,请告诉我。

6 个答案:

答案 0 :(得分:2)

为什么不正确?它是。 default更安全:如果您更改了cases,但未能更改if,则会遇到麻烦。

答案 1 :(得分:2)

这两种方法都是有效且等效的,除了一些细节:

  • 您定义main的方式已完全过时。它不会在严格模式下使用C99编译器进行编译。使用int main(void)int main(int argc, char *argv[])
  • 测试scanf()的返回值。如果您键入的内容无法解析为数字,scanf()将返回0甚至EOF如果您关闭输入流,其余代码将使用未初始化的值month
  • case子句中的值括起来既不有用也不惯用。删除它们。
  • 始终在break;语句switch语句的最后一个句子末尾添加default语句更安全。如果您添加了另一个条款,则不会遗漏它。
  • 从第二个代码中删除default:;子句,这是无用且令人惊讶的。

如果输入超出范围(例如重新启动输入操作),则可能需要更多地指示第二种方法的原因。 if语句将允许您正确分离这些情况,而仅使用default子句可能不太合适:

for (;;) {
    int n, month;
    printf("Enter a number between 1 and 12: ");
    n = scanf("%d", &month);
    if (n == EOF) {
        printf("Unexpected end of file\n");
        exit(1);
    }
    if (n != 1) {
        printf("Invalid input\n");
        scanf("%*[^\n]%*c"); /* flush the pending input */
        continue;
    }
    if (month >= 1 && month <= 12) {
        switch (month) {
          case 1: 
            printf("The month is January\n");
            break;
          ...
          case 12: 
            printf("The month is December\n");
            break;
        }
        handle_month(month);  // perform other tasks
        break;
    } else {
        printf("Invalid month number\n");
    }
}

答案 2 :(得分:0)

是的,您可以在描述时使用if语句。但是,我没有看到这样做有什么好处。

答案 3 :(得分:0)

原件更好。编译器将完成相同的工作,尽管由于分支预测,第二个会慢一点。

但主要原因是代码的可维护性。添加或删除一个值时,您需要使用if语句修改两个位置,而只需使用switch修改一个。

答案 4 :(得分:0)

我的个人观点,可能并不完美。

优先考虑default案例,因为它会捕获任何未解决的案例。人们似乎依赖它,因此,-Wswitch-default中的警告标志gcc因此,有时您可能会在没有default案例的情况下收到编译器警告。

在您的特定情况下,它很好但good practice使用default的情况。

答案 5 :(得分:0)

实际上,我会说您的代码违反了何时使用switch语句的最佳做法。相反,试试这个:

if (month >= 1 && month <= 12) {
    char const*const names[] = {
        "January",
        "February",
        ...
        "November",
        "December",
    };
    printf("The month is %s\n", names[month -1]);
} else {
    printf("not valid\n");
}

那就是说,回到你的ininital问题,将if / elseswitch / case等流量控制结构混合在相同的数据通常很糟糕。这样做的原因是它不必要地复杂,所以坚持使用单个switch语句,就像在初始尝试中一样,或者使用我在上面概述的方法。