c中switch语句中的多个变量

时间:2010-03-27 19:34:26

标签: c# c++ c

如何使用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();
    }

编辑:

我已将最后一个案例从'和'更改为'或'以后。所以我在编辑之前回答了我的问题。

例如,这种情况,我只是想知道它是否可能。我有谷歌这个,发现它是不可能的,但我更信任stackoverflow上的大师。

由于

3 个答案:

答案 0 :(得分:6)

您正在寻找不自然地将此代码强制转换为switch的答案 - 对于您所描述的问题,这不是C,C ++或C#中的正确方法。与if语句一起使用,因为在这种情况下使用switch导致代码可读性降低,并且可能导致错误引发错误。

有些语言会评估类似于switch语句序列的if语句语法,但C,C ++和C#不在其中。


在Jon Skeet发表评论之后,尝试让其发挥作用感兴趣“之后,我将违背我的初步判断并继续发挥作用,因为人们可以通过以下方式学习尝试替代方案,看看他们在哪里工作以及他们不工作的地方。希望我不会最终混淆事情......

所考虑语言中switch语句的目标必须是常量 - 它们不是在运行时计算的表达式。但是,您可能会获得类似于您正在寻找的行为如果您可以将您想要拥有的条件作为切换目标映射到将产生匹配的完美哈希的哈希函数在条件。如果可以这样做,你可以调用哈希函数并打开它产生的值。

当您想要打开字符串值时,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语句组合更具可读性,但我想有些人可能更喜欢{{1}的更直接的方法。 }序列。

你在问题​​中使用的表达式集看起来并不是特别简单 - 你的哈希函数几乎肯定会成为if语句的序列 - 你基本上只是移动了在其他地方建造。 Jon Skeet的原始答案主要是将表达式转换为哈希值,但当if操作被混入其中一个测试时,哈希函数就会崩溃。

答案 1 :(得分: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;
        // ...
    }
}

答案 2 :(得分:2)

(删除了原来的回答:我错过了这个条件是“OR”而不是“AND”的事实。编辑:啊,因为显然它不是一开始。)

可以理论上仍然使用类似我的原始代码(将两个32位整数组合成一个64位整数并接通它),尽管会有2 ^ 33个案例语句覆盖最后的条件。我怀疑任何编译器实际上都会通过这样的代码:)

但基本上没有:改为使用if / else结构。