当前位置: 首页 > 工具软件 > goto > 使用案例 >

c++关键字goto

韦俊英
2023-12-01

1、goto

  • c++最强大的关键字之一,它可以使程序跳转到指定位置继续运行。
  • 还记得上c++的课老师说不要随意使用goto,原则上尽量避免使用goto。
  • 理论上可以证明,用顺序,条件,循环可以解决所有问题,所以尽量不要用goto语句!
  • 大量使用goto使程序结构混乱,大型程序后期维护性较差。
  • 要是使用goto带来的好处远大于坏处,可以使用。
  • 剑?无好坏,关键在人。

2、goto只能在函数内实现跳转,不能跨函数跳转

  • 因为标号label是局部有效的。
#include <iostream>
#include <vector>
using namespace std;

void fun(){
    loop:
    for (int i = 0; i < 2; ++i) {
        cout<<"loop"<<endl;
    }
    goto loop;
};
int main() {
    fun();

    return 0;
}

这样会一直打印loop,正常。

#include <iostream>
#include <vector>
using namespace std;

void fun(){
    loop:
    for (int i = 0; i < 2; ++i) {
        cout<<"loop"<<endl;
    }
    goto loop;
};
int main() {
    goto loop;
    return 0;
}

会报错,说loop标号未定义,说明识别不到别的函数内的标号,也就没法跳转。
那把标号标到别的函数前面会怎样?

#include <iostream>
#include <vector>
using namespace std;

label:void fun(){
    loop:
    for (int i = 0; i < 2; ++i) {
        cout<<"loop"<<endl;
    }
    goto loop;
};
int main() {
    goto label;
    return 0;
}

结果也是一样,识别不出来label这个标号。说明goto能识别的标号也必须在它所在的函数内。

  • 那怎么实现跨函数的跳转呢?longjump,setjump。不怎么懂也没用过。。。。

3、基本功能跳转

#include <iostream>
using namespace std;

int main()
{
   int x;
	cin>>x;
   if(x<2)
   {
	   goto ld;
   }
	ls:
	cout<<x<<endl;
	ld:
	cout<<x<<endl;
   return 0;
}

输入1,输出1
输入2,if语句不执行,顺序执行代码,输出1,1

4、跳出本次循环,功能类似continue

  • 先尝试,直接像continue那样使用。
#include <iostream>
#include <vector>
using namespace std;
int main() {

    label:
    for (int i =0; i < 3; ++i) {
        if(i == 1)
            goto label;
        cout<<i<<endl;
    }
    return 0;
}

最后一直循环打印0;
解释:i一开始是0,然后++i,i为1;这时候goto label,跳转去的for循环,i重新被初始化为0,就这样重复这个循环。。。

  • 考虑到上面是因为被重新初始化,达不到效果,将初始化放外面
#include <iostream>
#include <vector>
using namespace std;
int main() {
    int i =0;
    label:
    for (; i < 3; ++i) {
        if(i == 1)
            goto label;
        cout<<i<<endl;
    }
    return 0;
}

这时候只打印一个0出来
解释i一开始为0,打印出来,++i后i为1,if条件成立,goto label,这时候++i没有执行,i仍然为1,这样就会一直循环下去,所以这个也是死循环,只不过不打印。。。

  • 由于上面是因为++i不执行造成的死循环,我们将++i放在里面。
#include <iostream>
#include <vector>
using namespace std;
int main() {
    int i =0;
    label:
    for (; i < 3; ) {
        if(i == 1)
        {
            ++i;
            goto label;
        }
        else
        {
            cout<<i<<endl;
            ++i;
        }

    }
    return 0;
}

打印出0,2,程序也正常退出,达到预期效果。
但是这个for循环被大改,失去了for循环使用的简单性。有点像do。。while了有没有?所以。。。

  • 使用do…while,while版本达到continue效果。
#include <iostream>
#include <vector>
using namespace std;
int main() {
    int i =0;
    loop:
    do{
        if(i==1)
        {
            ++i;
            goto loop;
        }

        cout<<i<<endl;
        ++i;
    }while(i<3);
    return 0;
}

输出0,2,达到预期效果。

#include <iostream>
#include <vector>
using namespace std;
int main() {
    int i =0;
    loop:
    while(i<3){
        if(i == 1)
        {
            ++i;
            goto loop;
        }
        cout<<i<<endl;
        ++i;
    }
    return 0;
}

输出0,2。达到预期效果。

5、goto往后跳,跳转到循环外的下一条语句,效果同break,用于多重循环跳出。

#include <iostream>
#include <vector>
using namespace std;
int main() {
    for (int i = 0; i < 3; ++i)
        for (int j = 0; j < 4; ++j)
            for (int k = 0; k < 5; ++k)
                if(k == 1)
                    goto label;

    label:
    cout<<"break for"<<endl;
    return 0;
}

打印出break for,程序也正常结束。

6、goto往前跳,可以形成循环

#include <iostream>
#include <vector>
using namespace std;
int main() {
    label:
    cout<<"front"<<endl;
    goto label;
    return 0;
}

循环打印front,而且还是死循环。
解释:goto跳到哪条语句就从哪条语句继续往下执行,直到程序块结束。

7、goto跳转到goto语句

#include <iostream>
#include <vector>
using namespace std;
int main() {

    goto label2;
    label1:
    cout<<"label1"<<endl;
    label2:
    {
        cout<<"label2"<<endl;
        goto label1;
    }
    return 0;
}

goto的标号中又有goto语句,也是可以的。

8、总结

  • goto在函数内可以随意跳转,可以向前也可以向后。
  • goto可达到多重效果,goto跳转的语句也可以是goto语句。
  • goto可能会造成死循环,注意!
  • goto确实很强大,但是也很混乱。
 类似资料: