C语言中的Switch语句

6

我有以下的if语句:

    if (strcmp(registerName, "zero"))
            return 00000;
    else if (strcmp(registerName, "at"))
        return 00001;
    else if (strcmp(registerName, "v0"))
        return 00010;
    else if (strcmp(registerName, "v1"))
        return 00011;

这段代码实际上很长——大约有20个if语句。因此,我想使用switch语句。当每个语句都有不同的条件时,我该如何将其转换为switch语句?

我尝试了下面的代码,但它不起作用:

int registerAddress;

switch(registerAddress) {

case 1 (strcmp(registerName, "zero")):
        regsiterAddress = 00000;
        break;
case 2 (strcmp(registerName, "at")):
        registerAddress = 00001;
        break;
}

1
顺便说一下,当a等于b时,strcmp(a, b)返回零(在布尔上下文中评估为false)。 - rczajka
哦,是的 - 必须添加 '== 0' - darksky
5个回答

7
您不能在 C 语言中使用 switch 语句来匹配字符串,因为它只能用于原始类型。您可以使用哈希表或搜索树来优化匹配,但对于仅有 20 个选项而言,这可能不值得麻烦。

如果要简化代码,您可以设置一个映射表:

struct str2Num {
    char *str;
    int num;
};

const struct str2Num registerMap[] = {
    { "zero", 00000 },
    { "at", 00001 },
    { "v0", 00010 },
    { "v1", 00011 },
    { NULL, 0 }  /* end marker */
};

并像这样进行匹配:

int i;
for (i = 0; registerMap[i].str != NULL; i++) {
    if (strcmp(registerName, registerMap[i].str) == 0) {
        return registerMap[i].num;
    }
}
/* handle no-match case here */

事实上,如果您按字母顺序排序表格,甚至可以使用bsearch()进行快速匹配。


7

你只能使用整数进行切换,所以这样做是行不通的。

如果你只是将字符串转换为整数,请将信息存储在数组中并查找它。

struct {
   const char *name;
   int value;
} fooMapping[] = {
     {"zero",0},
     {"at",1}
      ....
};

int foo2value(const char *name)
{
     size_t i;
     for(i = 0; i < sizeof fooMapping/sizeof fooMapping[0]; i++) {
          if(strcmp(name, fooMapping[i].name) == 0) 
             return fooMapping[i].value;

     }
    return -1;
}

这样做比我现在有的20个if语句更有效吗? - darksky
@Nayefc 虽然可能差不多,但要确定就必须进行测试。不过它占用的空间确实要少得多。 - ughoavgfhw
如果这些值增加到很多,将它们按排序顺序存储,并使用二分查找而不是线性查找来查找匹配项。 - nos
if语句应该是:if(strcmp(name, fooMapping[i].name) == 0) ——使用i而不是0,对吗? - darksky
它不会增长 - 它的常数为n = 20。我应该坚持使用二进制吗?我已经在类似的事情上使用了二分查找。 - darksky

1
为什么不使用 ? 操作符,像这样:

return
    strcmp(registerName, "zero")? 00000:
    strcmp(registerName, "at")  ? 00001:
    strcmp(registerName, "v0")  ? 00010:
    strcmp(registerName, "v1")  ? 00011:
    ...

1
在编程中,"switch"是一种语句。
switch(number) {

case 1;
case 2;
case 7;
}

你的意思是,如果数字等于1,则执行case 1。如果数字等于7,则执行case 7。因此,你需要为每个文本值分配一个变量,在你的情况下是“zero”、“at”、“v0”和“v1”,你需要将它们放入一个数组中,在switch语句中,不是switch(number),而是switch一个整数,该整数对应于你所拥有的任何文本的索引号。因此,如果array [3] =“v0”,则会为索引号(3)分配一个整数,然后进行switch(integer)。希望这可以帮助到你。


0

由于 switch-case 只适用于数字或单个字符,我建议使用类似 GNU's gperf 的工具来创建一个完美哈希表,并在该值上进行切换(然后跟随 strcmp() 以确保精确匹配)。这应该可以为您提供所需的性能改进。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接