C++ 关于使用switch语句的问题

C++ 关于使用switch语句的问题,c++,C++,首先,我意识到从性能的角度来看,这个switch语句的设计很慢,因为在某些情况下cout会被多次调用。除此之外,这种编写switch语句的方式是否不是好的编码实践。换言之,是单独处理每一个案例并打破僵局更好,还是失败更好 int main(void) { int number; cout << "Enter a number between 1 and 10 and I will display its Roman numeral equivalent." <&

首先,我意识到从性能的角度来看,这个switch语句的设计很慢,因为在某些情况下cout会被多次调用。除此之外,这种编写switch语句的方式是否不是好的编码实践。换言之,是单独处理每一个案例并打破僵局更好,还是失败更好

int main(void)
{
    int number;
    cout << "Enter a number between 1 and 10 and I will display its Roman numeral equivalent." << endl
         << "> ";
    cin >> number;

    cout << "Roman numeral: ";
    switch (number)
    {
        case 3:
            cout << "I";
        case 2:
            cout << "I";
        case 1:
            cout << "I";
            break;
        case 4:
            cout << "I";
        case 5:
            cout << "V";
            break;
        case 6:
            cout << "VI";
            break;
        case 7:
            cout << "VII";
            break;
        case 8:
            cout << "VIII";
            break;
        case 9:
            cout << "I";
        case 10:
            cout << "X";
            break;
        default:
            cout << "Error!\nYou did not enter a number between 1 and 10";
    }

    cout << endl;

    return 0;
}
int main(无效)
{
整数;
库特数;

coutSwitch语句并不慢,编译器通常会对它们进行优化,以跳转表。如果您确信Switch语句按预期工作,那么这很好,是一种非常酷的方式

也就是说,如果你单独处理每一个案例,你会有相同数量的案例。如果你只是这样做,我可能会将其更改为单独处理每一个案例,而不是失败。这样更容易理解和维护:

switch (number)
{
    case 1:
        cout << "I";
        break;
    case 2:
        cout << "II";
        break;
    case 3:
        cout << "III";
        break;
    case 4:
        cout << "IV";
        break;
    case 5:
        cout << "V";
        break;
    case 6:
        cout << "VI";
        break;
    case 7:
        cout << "VII";
        break;
    case 8:
        cout << "VIII";
        break;
    case 9:
        cout << "IX";
        break;
    case 10:
        cout << "X";
        break;
    default:
        cout << "Error!\nYou did not enter a number between 1 and 10";
}

对每种情况使用中断应该是最好的选择。使用“故障排除”将继续处理下一种情况的代码,这可能会导致错误并影响性能。

调用“是正确的,这非常聪明,而且速度非常快。但是如果您想提高性能

  • 在每个switch语句中,将您要
    cout
    ing的字符串添加到正在运行的字符串缓冲区。然后,在switch语句之后,
    cout
    缓冲区
  • 阅读/理解起来有点混乱。单独处理10个案例中的每一个都会更简单,性能也会更好(尽管使用的内存量很少)

这是一个如此简单的案例,很难说它真的“糟糕”。我听到过关于出租案例会变成其他案例的不同意见。我确信在某个时候,我们都做到了这一点。(我通常会用类似于/*fall-through*/的东西非常清楚地记录它,所以下一个阅读代码的人知道我是有意这么做的。)

我认为一个更复杂的例子会证明这不是一个好主意。但这并不是因为失败本身就是一件坏事。而是因为更好的设计不能保证这一点。在面向对象设计中,一个case语句可能表明你有“代码气味”--您不允许对象基于类型而不是基于其他信息执行它需要的操作

现在,如果有人真的想挑剔你公认的简单示例,可以说你把控制器、模型和视图混合在一起的方式很糟糕。你的控制器应该只获取输入。你的模型应该有更好的方式来获取输入的替代表示(映射,或者说,我不知道,一个case语句),并且您的视图逻辑不会分散在控制器逻辑中或其周围。通过实际遵循其他一些设计概念,switch语句可能会完全消失。其他示例也可能会出现这种情况


简言之,我认为如果你的设计是合理的,你可能会发现,如果一个switch语句事实上是必要的,那么对fall-through case语句的关注就没有什么大不了的。

我倾向于不使用这种风格,因为通常很难一眼看出控制流。这就是为什么
goto
是gen通常认为这是一个坏主意(尽管有些人认为这是福音,但并不理解为什么——在某些情况下,如果它不会使代码变得不可读,它实际上非常方便)

换句话说,我希望每个
案例都是独立的。如果它们有共性,我会倾向于将其分解成单独的函数,并从每个案例中调用这些函数

这不包括代码在不同情况下相同的情况,我只是使用了类似(显然是伪代码):

对于您的特定用例,我可能只使用如下表查找:

char *roman[] = {"I", "II", "III", "IV", ... "X"};
if ((n < 1) || (n > 10))
    cout << "Urk! I only have ten fingers!";
else
    cout << roman[n-1];
char*roman[]={“I”、“II”、“III”、“IV”、…“X”};
如果((n<1)|(n>10))

coutSwitch语句可以由编译器优化为跳转表,因此它们并不总是很慢。而且它们肯定比编写一堆
if
-
else if
语句要好。我个人喜欢fall-through,因为它允许您在某些情况下做一些很酷的事情,而不必重复代码;但一般来说,人们不赞成他们,因为他们比单独处理每一个案件更难理解

对于您的示例,如果您担心对
cout
的多次调用,则始终可以将中间字符串存储在
stringstream
中并打印最终字符串。但是,对
cout
的输出是缓冲的,因此我不知道这是否会有任何显著的性能改进

#include <iostream>
#include <ios>
#include <sstream>

int main(void)
{
    using namespace std;

    int number = -1;
    cout << "Enter a number between 1 and 10 and I will display its Roman numeral equivalent." << endl
         << "> ";
    cin >> number;

    ostringstream oss( "Roman numeral: ", ios_base::ate );
    switch (number)
    {
        case 3:
            oss << "I";
        case 2:
            oss << "I";
        case 1:
            oss << "I";
            break;
        case 4:
            oss << "I";
        case 5:
            oss << "V";
            break;
        case 6:
            oss << "VI";
            break;
        case 7:
            oss << "VII";
            break;
        case 8:
            oss << "VIII";
            break;
        case 9:
            oss << "I";
        case 10:
            oss << "X";
            break;
        default:
            cout << "Error!\nYou did not enter a number between 1 and 10";
            return -1;
    }

    cout << oss.str() << endl;

    return 0;
}
#包括
#包括
#包括
内部主(空)
{
使用名称空间std;
整数=-1;
库特数;
ostringstream oss(“罗马数字:”,ios_base::ate);
开关(编号)
{
案例3:

oss
cout
已经被缓冲。为什么你认为添加另一层缓冲会使它更快?对于像这样的简单情况,我将把case、cout和break放在一行,并将它们排列成三列(默认情况除外)-我讨厌看大量的代码来解决问题:-这不会使你的答案无效,谢谢。这只是一种编码风格。谢谢塞思。总是感谢你的输入!)你的例子非常干净。我真的很喜欢别人怎么做,因为它让我的眼睛看不到的方法。但是,C++我想让我们使用Switter语句。所以当我写这篇文章时,我意识到失败会对一些条目起作用。(@:FHADAD78):如果是为了一个类,我怀疑你的教育者可能会皱眉,因为他们会认为可读性比“聪明”更重要。编码练习。记住这一点。如果讲师失败或对任何工具进行计数
char *roman[] = {"I", "II", "III", "IV", ... "X"};
if ((n < 1) || (n > 10))
    cout << "Urk! I only have ten fingers!";
else
    cout << roman[n-1];
#include <iostream>
#include <ios>
#include <sstream>

int main(void)
{
    using namespace std;

    int number = -1;
    cout << "Enter a number between 1 and 10 and I will display its Roman numeral equivalent." << endl
         << "> ";
    cin >> number;

    ostringstream oss( "Roman numeral: ", ios_base::ate );
    switch (number)
    {
        case 3:
            oss << "I";
        case 2:
            oss << "I";
        case 1:
            oss << "I";
            break;
        case 4:
            oss << "I";
        case 5:
            oss << "V";
            break;
        case 6:
            oss << "VI";
            break;
        case 7:
            oss << "VII";
            break;
        case 8:
            oss << "VIII";
            break;
        case 9:
            oss << "I";
        case 10:
            oss << "X";
            break;
        default:
            cout << "Error!\nYou did not enter a number between 1 and 10";
            return -1;
    }

    cout << oss.str() << endl;

    return 0;
}