4

我有这样的和 switch 语句:

switch(x){
    case a:
         executeSth();
         executeA();
    break;
    case b:
         executeSth();
         executeB();
    break;
    ...
}

所以executeSth(); 除非在默认情况下,否则应始终执行,但之后调用某些特定情况的代码(executeA();或executeB()等)。(所以简单地把它放在开关前面是行不通的)。

有没有一种有效的方法来减少“executeSth();”的数量?不牺牲性能?

我只能想象将它分成两个开关(一个执行 executeSth() in 和一个执行特定代码),但这会牺牲性能。也许你有更好的想法?

我基本上对 c/c++ 或 php 的代码很感兴趣。我的目标是最小化代码大小,如果是 c/c++,则最小化生成的可执行文件的大小。

编辑:是的,功能的顺序很重要。Edit2:我无法在 php 或 c++ 之间进行选择,我需要它尽可能好。

4

6 回答 6

9

嵌套switch是一种选择...

这使用了两个开关,但在这种default情况下不会触发第二个开关,因此其性能配置文件比仅使用两个串联开关略好。

switch($x) {
    case a: case b: case c:
        executeSth();
        switch($x) {
            case a:
                executeA();
                break;
            case b:
                executeB();
                break;
            case c:
                executeC();
                break;
        }
        break;
    default:
        ...
}

或者,变量函数可以完成这项工作......

这是一个可能有效的 PHP 选项,尽管很多人不喜欢变量函数。如果您想完全消除嵌套和重复,这可能是最好的选择。

switch($x) {
    case a:
        $function = "executeA";
        break;
    case b:
        $function = "executeB";
        break;
    case c:
        $function = "executeC";
        break;
    default:
        ...
}

if(isset($function)) {
    executeSth();
    $function();
}

如果有人想在发布之前测试他们的 PHP 解决方案是否有效(应该和、应该和应该),我还在这里做了一个小现场测试平台。case 10executeSth()executeA()case 20executeSth()executeB()defaultexecuteDefault()

在 C++ 中,可以使用函数指针来实现与上述相同的功能

当我写这篇文章时,我脑子里放了个屁,幸好 idipous 提醒我,我们可以用一个简单的函数指针来做到这一点。

// Declare function pointer
int (*functionCall)() = NULL;

// In switch statement, assign something to it
functionCall = &execute;

// After the switch statement, call it
int result = (*functionCall)();

注意:我出去了,所以没有检查这些语法。我使用的语法是 C 语法,可能需要一些小的改动才能在 C++ 中工作。

于 2013-09-02T15:06:06.607 回答
3

你可以做什么(虽然它可能不是最易读的解决方案),如果你使用的是 PHP 5.3 及更高版本,你可以创建如下所示的方法:

function mymethod($funcToCall){
   executeSth();
   $funcToCall();
 }

并具有如下所示的开关:

switch(x){
case a:
     mymethod('executeA');
break;
case b:
     mymethod('executeB');
break;
...
}
于 2013-09-02T15:12:00.463 回答
1

除非真的有大量这类事情,否则我会保持原样。

一种解决方案当然是将调用移动executeSthexecuteA定义和executeB定义中——这当然只有在有多个具有相似代码的地方才有意义——如果不超过一个地方,你已经从一个地方移动了两行代码地方到另一个地方。

另一种解决方案可能是将函数executeAexecuteB作为executeSth参数传递。但这只会使阅读变得更加复杂。

一般来说,我会说“更小的代码”不一定是“更好的代码”。关键是使代码尽可能清晰(当然,同时仍要达到合理的性能和代码大小)。

在 C++ 中,我还期望如果executeSth它很小,它会被内联到案例代码中。因此,有一个或两个函数调用之间没有开销差异。

于 2013-09-02T15:14:05.383 回答
0

为什么不在你的默认情况下设置一个标志,然后在switch语句之后,如果没有设置标志,则执行通用函数(意味着它不是默认情况)?这听起来像是一个合理的解决方案。

$flag = false;
switch(x){
    case a:
         executeA();
    break;
    case b:
         executeB();
    break;
    default:
         ... // other stuff
         $flag = true;
    break;
}

if ( !$flag )
    executeSth();

编辑

我误解了这个问题。对于相反的顺序,您可以将可能的情况放在一个变量中,然后使用 PHP 中的 in_array 或 C++ 中的 strstr 之类的东西(不确定是否有更好的本机函数):

if ( !in_array(x, cases) {
    executeSth();
}
switch(x){
    case a:
         executeA();
    break;
    case b:
         executeB();
    break;
    ...
}
于 2013-09-02T16:05:18.847 回答
-1

就代码大小而言:没关系。可读性 > 代码大小。

也许您可以为您的 executeSth() 编写类似的内容:

if(!notDefault){
  executeSth();
}
于 2013-09-02T15:04:17.230 回答
-1

(C++) 让预处理器为你复制代码?(Dᴏɴ'ᴛ Uꜱᴇ Tʜɪꜱ ɪɴ Mᴀɪɴᴛᴀɪɴᴇᴅ Cᴏᴅᴇʙᴀꜱᴇ。它可能会损害可读性。我认为双开关解决方案很好。)

#define CASE(n) case n: printf("non-default\n"); _unused_label_##n

switch (x) {
CASE(1):
    printf("case 1\n");
    break;
CASE(2):
    printf("case 2\n");
    break;
default:
    printf("case else\n");
    break;
}

#undef CASE
于 2013-09-02T15:13:24.807 回答