C++ 关于使用switch语句的问题
首先,我意识到从性能的角度来看,这个switch语句的设计很慢,因为在某些情况下cout会被多次调用。除此之外,这种编写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." <&
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:
osscout
已经被缓冲。为什么你认为添加另一层缓冲会使它更快?对于像这样的简单情况,我将把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;
}