在 if 语句中使用 switch case

Posted

技术标签:

【中文标题】在 if 语句中使用 switch case【英文标题】:Use switch cases in an if statement 【发布时间】:2020-11-24 15:33:56 【问题描述】:

我们可以在 switch 语句中使用条件来包含 case 吗?

我的代码:

switch(menu_option)

  if (g_logged_in)
  
     case 'L':
       cout << "Login Menu\n";
       break;
     case 'S':
       cout << "Signup Menu\n";
       break;
  
  case 'A':
    foo();
    break;
  case 'B':
    bar();
    break;

  default:
    cout << "Invalid Option!\n";

当我编译文件时,我得到一个错误

[pewpew@Sierra cpp-something]$ c++ src/main.cc -o main.out
src/main.cc: In function 'int main()':
src/main.cc:53:13: warning: statement will never be executed [-Wswitch-unreachable]
   53 |             if (g_logged_in)
      |             ^~

这不可能吗?

【问题讨论】:

正如警告所说:这些语句永远不会被执行。 @πάνταῥεῖ 因此这个问题,无论如何不可能?我应该只在案例中包含 if 语句吗? “无论如何不可能?” 那么,请定义可能。至少代码可以编译,但不会做你想做的事。 【参考方案1】:

目前,程序控制从未达到if (g_logged_in),因此从未评估过。您有用的编译器正在发出警告。

虽然switch 块实际上只不过是一组受控的goto 语句。你可以用

强制它
switch(menu_option)
    foo:
    if (g_logged_in)

在程序控制到达的地方使用goto foo;,尽管由于可读性和可维护性,这种想法是不明智的。以下 sn-p 是“Hello World!”的重新表述。程序:

#include <iostream>
int main()
    switch (1)
    foo:
    if (true)
        case 0:
            std::cout << " World!\n";
            break;
        case 1:
            std::cout << "Hello";
            goto foo;
        
       

有关switch 块内交错控制循环的真实用例,请参阅 Duff 的设备:https://en.wikipedia.org/wiki/Duff%27s_device

【讨论】:

啊,谢谢,这似乎回答了我的问题,我研究了 Duff 的设备,但我对 C++ 还很陌生,所以不太了解。 @RaahimFareed:在 Duff 的装置向我展示之前,我花了几天的时间精神恍惚。 @RaahimFareed 现代优化器在 Duff 的设备上窒息而死,因此它通常在设计时甚至没有用处。这也是神秘的代码。简而言之,您可以放心地忽略它。 请注意 if 并不能真正保护案例,因为将 true 更改为 false 仍会打印 "Hello" Demo。【参考方案2】:

您的代码上方没有“案例”。 你不能这样做。这种情况很可能被编译成一条 CPU 指令,它只适用于整数。 您必须使用这种情况并为这两种情况执行两次 if()。

【讨论】:

我目前正在使用这种方式,因为问题中的代码没有执行 The case is most likely compiled into a CPU instruction 不,大小写只是一个(特殊)标签,与指令无关,因为它们是完全不同的东西。案例标签可以通过多种方式跳转,但大多数时候它不是单个跳转指令【参考方案3】:

您不能有条件地指定case 语句。你将不得不做更多这样的事情:

switch (menu_option)

  case 'L':
    // in C++17 and later, you can uncomment the following
    // attribute to avoid a compiler warning...
    //
    // [[fallthrough]];
  case 'S':
    if (g_logged_in)
    
      if (menu_option == 'L')
        cout << "Login Menu\n";
      else
        cout << "Signup Menu\n";
    
    else
      cout << "Invalid Option!\n";
    break;

  case 'A':
    foo();
    break;

  case 'B':
    bar();
    break;

  default:
    cout << "Invalid Option!\n";
    break;

或者这个:

switch (menu_option)

  case 'A':
    foo();
    break;

  case 'B':
    bar();
    break;

  default:
    if (g_logged_in)
    
      if (menu_option == 'L')
      
        cout << "Login Menu\n";
        break;
      
      if (menu_option == 'S')
      
        cout << "Signup Menu\n";
        break;
      
    
    cout << "Invalid Option!\n";
    break;

【讨论】:

哦,哇,我从没想过要这样做,整洁

以上是关于在 if 语句中使用 switch case的主要内容,如果未能解决你的问题,请参考以下文章

switch case语句和if的区别

在Switch语句中使用.StartsWith?

JS入门基础(if else 与 switch case / node安装)

Switch case 语句怎么使用

我可以使用带有两个变量的case / switch语句吗?

c语言中switch可用啥语句替换