C/C++/Java goto语句的使用
来源:互联网 发布:空气炮升级数据 编辑:程序博客网 时间:2024/06/08 17:13
goto语句:http://baike.baidu.com/link?url=2SPNcNbC4S-CP08jQV5ei2b9zqpXdfHrFRqstF5TCsVTnZeUcrpQ3THe0uvWkF95eyej52gBijSAwwXR_6ZeIq#6
《C Primer Plus》(第6版)中文版 7.8章 goto语句
《JAVA核心技术 卷I:基础知识》3.8.6章 中断控制流程语句
##############################################################
最近一段时间,经常需要在同一个函数中编写多个重复代码,出现问题后就需要一个个找出来进行修改,没有效率。在一个例子里发现一段goto语句的使用,发现能够高效的处理重复代码,之前对于goto语句并没有在意,觉得应该不用任何goto语句,但是现在看来,goto语句还是很有效的
知乎上有一个关于goto语句使用的讨论:
既然建议尽量避免使用goto语句为何C++还要支持goto呢?:https://www.zhihu.com/question/21981058
################################################################
首先介绍C/C++版本的goto语句
goto语句也称为无条件转移语句,最早应该出现在BASIC和FORTRAN中,C/C++也能够使用goto语句,但C/C++与前面两种语言不同的是,goto语句并不是必需的,没有goto语句程序也能运行良好。
goto语句的一般格式:
goto 标签名;
其中标签名遵循变量命名规则
介绍一下变量命名规则:
1).变量名只能是字母(A-Z,a-z)和数字(0-9)或者下划线(_)组成;
2).第一个字母必须是字母或者下划线开头;
3).不能使用C/C++关键字来命名变量,以免冲突;
4).变量名区分大小写。
参考:C/C++变量命名规则,个人习惯总结 - http://blog.sina.com.cn/s/blog_8a7012cf01017h9p.html
同时程序必须包含另一条语句,格式为:
标签名:即标签名后紧跟一个冒号
一个简单的C程序:
#include <stdio.h>int main(int argc, char* argv[]) { if (getchar() == 'a') { goto Hi; } else { goto Hello; }Hi: printf("Hi World\n"); return 0;Hello: printf("Hello World\n"); return 0;}
当你输入字符a时,输出Hi World;否则,输出Hello World
原则上,根本不用在C/C++程序中使用goto语句。但在以下场景中,使用goto语句可以高效的处理代码
1.从多重循环中直接跳出
当需要结束嵌套循环时,break语句只能跳出当前循环,使用goto语句可以直接跳出所有循环,这样就不需要在嵌套循环中再进行if判断了
例子:从一个二重循环中退出
使用break
#include <stdio.h>int main(int argc, char* argv[]) { bool flag = false; //设置标志位,用于判断是否退出 int sum = 0; // 累加i*j的值,大于10就结束 for (int i=0; i<10; i++) { for (int j=0; j<10; j++) { sum += i*j; if (sum > 10) { flag = true; break; } } if (flag) { break; } } printf("sum = %d\n", sum); return 0;}
使用goto
#include <stdio.h>int main(int argc, char* argv[]) { int sum = 0; // 累加i*j的值,大于10就结束 for (int i=0; i<10; i++) { for (int j=0; j<10; j++) { sum += i*j; if (sum > 10) { goto exit; } } } exit: printf("sum = %d\n", sum); return 0;}
很明显,goto语句能够方便的完成退出
2.为函数统一设置出口
这个就是我遇到的问题,不论退出函数时是好的结果还是坏的结果,都有可能会有一些必须执行的操作,比如释放资源,重设置标识符等。可能一个函数中会有多个出口,这样对于程序的可读性以及后续维护很不方便,使用goto可以很好的解决这个问题
不用goto
#include <iostream>#include <string.h>using namespace std;string func(const char* arg1, const char* arg2);int main(int argc, char* argv[]) { string res; res = func("arg1", "arg2"); cout <<"res = " <<res <<endl; return 0;}string func(const char* arg1, const char* arg2) { char* p1 = NULL; p1 = (char*)malloc(sizeof(char) * strlen(arg1)); memset(p1, 0, strlen(arg1)); memcpy(p1, arg1, strlen(arg1)); char* p2 = NULL; p2 =(char*)malloc(sizeof(char) * strlen(arg2)); memset(p2, 0, strlen(arg2)); memcpy(p2, arg2, strlen(arg2)); if (strcmp("arg1", p1) == 0) { cout <<"arg1 ok" <<endl; delete[] p1; delete[] p2; return arg1; } if (strcmp("arg2", p2) == 0) { cout <<"arg2 ok" <<endl; delete[] p1; delete[] p2; return arg2; } delete[] p1; delete[] p2; return "error";}
使用goto
#include <iostream>#include <string.h>using namespace std;string func(const char* arg1, const char* arg2);int main(int argc, char* argv[]) { string res; res = func("arg1", "arg2"); cout <<"res = " <<res <<endl; return 0;}string func(const char* arg1, const char* arg2) { char* p1 = NULL; p1 = (char*)malloc(sizeof(char) * strlen(arg1)); memset(p1, 0, strlen(arg1)); memcpy(p1, arg1, strlen(arg1)); char* p2 = NULL; p2 =(char*)malloc(sizeof(char) * strlen(arg2)); memset(p2, 0, strlen(arg2)); memcpy(p2, arg2, strlen(arg2)); string res = "error"; if (strcmp("arg1", p1) == 0) { cout <<"arg1 ok" <<endl; res = arg1; goto exit; } if (strcmp("arg2", p2) == 0) { cout <<"arg2 ok" <<endl; res = arg2; goto exit; } exit: delete[] p1; delete[] p2; return res;}
将同一个函数中的所有出口统一到一起,可读性提高,同时方便今后修改
#############################################################
Java中将goto作为关键字,但并没有给它赋予任何功能,但在Java中也有可替代goto功能的语句,就是带标签的break和带标签的continue语句
参考:Alternative to a goto statement in Java - http://stackoverflow.com/questions/2430782/alternative-to-a-goto-statement-in-java/2430829#2430829
带标签的break语句
语法:
break 标签名;
标签名:
注意:第二条语句必须放在希望跳出的语句块之前,并且必须紧跟一个分号,同时语句块中必须包含带标签的break语句,所以该语句仅能作为跳出语句块的操作。语句块可以使多重循环,也可以是if语句,for语句或者{}块语句。
一个简单的例子:输入数字,小于等于0则退出
package com.zj;import java.util.Scanner;public class Main { public static void main(String[] args) {// write your code here Scanner in = new Scanner(System.in); int n = 0; read_data: while (true) { while (true) { System.out.print("Enter a number >= 0:"); n = in.nextInt(); if (n <= 0) break read_data; } } if (n < 0) { System.out.println("n < 0"); } else if (n == 0) { System.out.println("n == 0"); } }}
还有一个continue加标签的用法,用于退出当前循环,继续上层循环,想要了解的可以查找相关资料
- C/C++/Java goto语句的使用
- c语言goto语句的使用
- c语言的goto语句
- Java里的goto语句与C语言goto语句对比
- C语言(17)-----goto语句使用
- C语言中使用goto语句
- c语言中使用goto语句
- c/c++ goto 语句
- C语言goto语句
- C语言goto语句
- c语言 goto语句
- C语言 goto语句
- C语言goto语句
- c语言 goto语句
- C语言goto语句
- 【C++】goto语句
- C语言goto 语句
- object-c语法--goto语句
- Ubuntu 16.04 用 MacBuntu 16.04 TP 打造 MAC 界面
- ACM——p2016数据的交换输出(选择排序,选择最小数与第一个交换)
- 数据结构——表与链表
- 多态,接口
- 构造继承
- C/C++/Java goto语句的使用
- vc6 远程调试
- gui
- 关系型数据库
- 接口,事件
- 带循环的行列计算
- super
- Java web bean
- 课堂笔记