2.goto分析:

  1).goto是干啥的?

  c语言提供了可随意滥用的goto语句以及标记跳转位置的标号.但是理论上goto是没有必要的.

  标记跳转位置的标号: 如上例中的 _failed: , _failed_fd:, 标号可以在该函数的任意地方,在标号后边,写处理逻辑。

  调用goto语句语法: “goto 标号;"

  2)测试代码:

  

复制代码

#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
    int a = atoi(argv[1]);

    if (a == 1)
    {
        goto failed1;
    }
    else if(a == 2)
    {
        goto failed2;
    }
    else
    {
        goto failed3;
    }
    
failed1:
    printf("get failed1\n");
failed2:
    printf("get failed2\n");
failed3:
    printf("get failed3\n");

    printf("a + b = 3\n"); (随便输出的)
    return 0;
}

复制代码 代码从控制台输入a的值,下面分别是 a = 1, 2, 3时的结果,编译:gcc -g -o test test.c

控制台输入: ./test 1

结果:

get failed1

get failed2

get failed3

a + b = 3

控制台输入: ./test 2

结果:

get failed2

get failed3

a + b = 3

控制台输入: ./test 3

结果:

get failed3

a + b = 3

可以看到,运行到对应的标号后,程序是继续向下运行的。

修改代码:

将 _failed1:的代码搬到 if(a == 1) 上边,同时修改a的值:

复制代码

#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
    int a = atoi(argv[1]);

failed1:
    printf("get failed1\n");
    a = 3;
    
    if (a == 1)
    {
     printf("a = 1\n");
        goto failed1;
    }
    else if(a == 2)
    {
        goto failed2;
    }
    else
    {
        goto failed3;
    }

failed2:
    printf("get failed2\n");
failed3:
    printf("get failed3\n");

    printf("a + b = 3\n");
    return 0;
}

复制代码 当再次编译代码,并运行:

./test 1

输出结果:

get failed1

get failed3

a + b = 3

可以看出,标号仅仅起到一个标识作用,程序顺序执行时,标号仿佛不存在,首先输出get failed1, 然后修改 a = 3,.并不是只有调用了goto标号,然后程序调到标号处,从而触发标号下边的代码开始运行。而是可以看作在完整的代码中插入标号,从而单纯地引导goto到达的位置。

  3)为什么不推荐使用goto:

  一般认为goto的使用会造成代码难以理解和维护,ps:因为我用的较少,对此理解还不是很深刻。

  4)什么情况下用到goto:

  当程序有多层嵌套,当处在嵌套内的逻辑判断为真或为假时,需要彻底或者连续跳出几层循环时,一般考虑使用goto,因为break一次只能跳出一层,并且需要跳出多层循环时需要假如更多的判断逻辑,

  这种情况下,会考虑使用goto,还有就是在大型程序中处理复杂逻辑时,一般也会考虑使用goto。

  例如判断两个数组中是否有相同元素时: