c中switch语句中的多个变量
Posted
技术标签:
【中文标题】c中switch语句中的多个变量【英文标题】:Multiple variables in switch statement in c 【发布时间】:2011-02-01 14:32:03 【问题描述】:如何使用c中的switch语句在c中编写以下语句
int i = 10;
int j = 20;
if (i == 10 && j == 20)
Mymethod();
else if (i == 100 && j == 200)
Yourmethod();
else if (i == 1000 || j == 2000) // OR
Anymethod();
编辑:
我稍后将最后一个大小写从“and”更改为“or”。因此,我向在此编辑之前回答我问题的人表示歉意。
例如,这种情况,我只是想知道这是否可能。我在谷歌上搜索了一下,发现这是不可能的,但我更相信 *** 上的专家。
谢谢
【问题讨论】:
@Muhammad:您实际上需要所有 C、C++ 和 C# 的答案吗?如果没有,最好指定您真正关心的语言。 @Jon,感谢您的建议。我会处理好这个。 【参考方案1】:您迫切需要的答案会不自然地将此代码强制转换为switch
- 对于您所描述的问题,这不是 C、C++ 或 C# 中的正确方法。使用if
语句,因为在这种情况下使用switch
会导致代码可读性降低,并且可能会出现错误。
有些语言会评估类似于if
语句序列的switch
语句语法,但C、C++ 和C# 不在其中。
在 Jon Skeet 评论说“尝试让它发挥作用很有趣”之后,我将违背我最初的判断并继续玩,因为确实可以通过以下方式学习尝试替代方案,看看他们在哪里工作,在哪里他们不工作。希望我最终不会把事情弄得比我应该做的还要多……
在所考虑的语言中,switch 语句的目标必须是常量——它们不是在运行时计算的表达式。但是,您可能会获得类似于您正在寻找的行为 if 您可以将想要作为切换目标的条件映射到哈希函数,该函数将产生匹配的完美哈希到条件。如果可以的话,你可以调用散列函数并打开它产生的值。
当您想要打开一个字符串值时,C# 编译器会自动为您执行类似的操作。在 C 语言中,当我想打开一个字符串时,我已经手动完成了类似的操作。我将目标字符串与用于识别字符串的枚举一起放在一个表中,然后打开枚举:
char* cmdString = "copystuff"; // a string with a command identifier,
// maybe obtained from console input
StrLookupValueStruct CmdStringTable[] =
"liststuff", CMD_LIST ,
"docalcs", CMD_CALC ,
"copystuff", CMD_COPY ,
"delete", CMD_DELETE ,
NULL, CMD_UNKNOWN ,
;
int cmdId = strLookupValue( cmdString, CmdStringTable); // transform the string
// into an enum
switch (cmdId)
case CMD_LIST:
doList();
break;
case CMD_CALC:
doCalc();
break;
case CMD_COPY:
doCopy();
break;
// etc...
不必使用一系列if
语句:
if (strcmp( cmdString, "liststuff") == 0)
doList();
else if (strcmp( cmdString, "docalcs") == 0)
doCalc();
else if (strcmp( cmdString, "copystuff") == 0)
doCopy();
// etc....
顺便说一句,对于此处的字符串到函数的映射,我个人认为表查找/switch 语句组合更具可读性,但我想有些人可能更喜欢if
序列的更直接方法.
您在问题中的表达式集看起来并不是特别简单地转换为哈希 - 您的哈希函数几乎肯定会最终成为 if
语句的序列 - 您基本上只是将构造移动到某个地方别的。 Jon Skeet 的原始答案本质上是将您的表达式转换为哈希,但是当 or
操作被放入其中一个测试的混合中时,哈希函数就崩溃了。
【讨论】:
@Michael:我不确定是否有人真的建议使用开关。当然,我的回答(在编辑之前和之后)鼓励使用 if/else 结构。 尝试让它发挥作用仍然很有趣,同时强烈反对它。 问题示例中没有嵌套 if :) @Jon:你是对的。所以我无视自己的建议,并给出了更深入的答案:) @Rune FS:你也是对的。现在没有提到嵌套的if
。【参考方案2】:
一般来说你不能。尽管您可能希望在末尾添加 else
子句以捕获意外输入,但您所做的已经很好。
在您的具体示例中,j 似乎通常是 i 值的两倍。如果这是一般规则,您可以尝试通过执行以下操作来利用它:
if (i * 2 == j) /* Watch out for overflow here if i could be large! */
switch (i)
case 10:
// ...
break;
case 100:
// ...
break;
// ...
【讨论】:
感谢您的回复,我可以使用这个嵌套开关来执行此功能吗? @Muhammad:这取决于你的真实代码是什么样的。我怀疑这实际上是你向我们展示的。老实说,if/else 最终可能会变得更具可读性,除非j
是双倍 i
的事实具有某些重要意义。你为什么这么渴望使用开关?
@Muhammad:您可以使用嵌套开关,但如果您有 m 个 i 值和 n 个 j 值,您将需要 m*n 个案例。阅读起来会非常混乱,并且您可能重复了代码。如果输入中有模式,请尝试利用这些模式来重用代码。如果在一个函数中执行代码太长,则将代码拆分为多个处理相关组合的函数。【参考方案3】:
(删除原始答案:我错过了条件是“OR”而不是“AND”的事实。编辑:啊,因为显然它不是开始的。)
您可以理论上仍然可以使用类似于我的原始代码的代码(将两个 32 位整数组合成一个 64 位整数并打开它),尽管会有 2^33 个 case 语句涵盖最后一个条件。我怀疑任何编译器实际上都会通过这样的代码实现它:)
但基本上不可以:改用 if/else 结构。
【讨论】:
请注意,最后一种情况并不完全匹配,因为在原始问题中存在“或”操作,而不是“与”,因此这里不仅仅是可读性问题。 @Jon 请查看我的编辑。你有空来陪我真是太好了。 小心。long
不能保证比 C 中的 int
长。
@Mark:是的,我的回答是假设 C#。坦率地说,将问题标记为 C、C++ 和 C# 确实令人困惑,因为它们是完全不同的语言。 OP 的历史表明他实际上使用 C# - 方法名称也是如此。以上是关于c中switch语句中的多个变量的主要内容,如果未能解决你的问题,请参考以下文章