多个If-Else语句VS.

Multiple If-Else Statements VS. Switch Statements within While Loop for C Language

这是我在这里的第一个帖子。第一次学习C建造机器人!:)

switch语句是否是表达下面多个if-else语句的更好选择?我是说这段代码很好用。但我只是对switch语句很好奇,想了解它们。

如果是的话,我不知道怎么做。我在网上搜索了很多次,但我对那些复杂的程序感到越来越害怕。:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
while(1)
{
    signed float A;

    A = get_angle();    

    if (A > 540 && A <= 700)
    {
        put_speed(200, 600);       //function to specify duty cycle and speed
    }
    else if (A > 1 && A <= 180)
    {
        put_speed (600, 200);
    }  
    else if (A > 180 && A <= 360)
    {
        put_speed(600, 100);
    }  
    else if (A > 360 && A <= 540)
    {
        put_speed(100, 600);
    }  
    else
    {
        put_speed(600, 600);
    }
}   // End of While


不,该代码不能用switch编写。

case的值必须是常量和整数。您可以使用case 4611:,但不能使用"case a>360"。

因此,除非您需要数百条case语句(您不需要),否则代码不容易翻译为使用switch

更新一种使其(在我看来)更优雅的方法是订购范围,并通过依赖已在所有else if中检查过的下限来减少重复:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
while(1)
{
    const float A = get_angle();

    if (A > 1 && A <= 180)
    {
        put_speed (600, 200);
    }  
    else if (A <= 360)
    {
        put_speed(600, 100);
    }  
    else if (A <= 540)
    {
        put_speed(100, 600);
    }  
    else if (A <= 700)
    {
        put_speed(200, 600);
    }
    else
    {
        put_speed(600, 600);
    }
}

这个新版本假设get_angle()从不返回负值,如果出现这种情况,它会选择错误的选项。您可以通过首先添加一个额外的if来解决这个问题,以捕获负值。


首先,您的范围没有排序,这使得您可能想做的有点混乱。重新排列代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if      (A >   1 && A <= 180)
{
    put_speed (600, 200);
}  
else if (A > 180 && A <= 360)
{
    put_speed(600, 100);
}  
else if (A > 360 && A <= 540)
{
    put_speed(100, 600);
}  
else if (A > 540 && A <= 700)
{
    put_speed(200, 600);       //function to specify duty cycle and speed
}
else
{
    put_speed(600, 600);
}

您可以看到范围或多或少是180的倍数。然而,范围的终点并不是我想象中的那样(我本以为是720,而不是700)。

正如您的代码一样,将其作为一个开关来编写是很困难的/适得其反的,但是您可以在上使用一个除法,特别是如果700是一个打字错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
switch ((int)(floor((a - 1) / 180)))
{
   case 0: //1 to 180
       put_speed(600, 200);
       break;

   case 1: //181 to 360
       put_speed(600, 100);
       break;

   case 2: //361 to 540
       put_speed(100, 600);
       break;

   case 3: //541 to 720
       if (a <= 700) //Odd
       {
           put_speed(200, 600);
           break;
       }
       //fallthrough for 701 to 720 (v. strange)

   default:
       put_speed(600, 600);
}


如果你想避免使用if-else,你可以使用一组坐标,还要注意,你必须在所有这些文字后面加上f

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>

int main(void)
{
    const float a[][4] = {
        {540.f,700.f,200.f,600.f},
        {1.f,180.f,600.f,200.f},
        {180.f,360.f,600.f,10.f},
        {360.f,540.f,100.f,600.f},
        {0.f,0.f,600.f,600.f}
    };
    size_t i, count = sizeof(a) / sizeof(a[0]);
    float A = 200.f;

    for (i = 0; i < count; i++) {
        if ((A > a[i][0] && A <= a[i][1]) || (i == count - 1)) {
            printf("%.0f %.0f
"
, a[i][2], a[i][3]);
            break;      
        }
    }
    return 0;
}

你可以用开关盒。只需将角度除以180(保持整数)。前任:如果(a>=1&a<180),则除以180将返回0。如果(a>=180&a<360),则除以180将返回1。

或者如果你有这样的条件

如果(a>1&a<=180),则除以181。它仍然会导致0,然后您可以使用开关盒。

注意:在这种情况下,如果不是这样会更有效率,但你想学习,所以这是我的建议。