关于goto
(下面一段来源《征服C指针》)
75: ReadLineStatus read_line(FILE *fp, char **line) 76: { 77: int ch; 78: ReadLineStatus status = READ_LINE_SUCCESS; 79: 80: st_current_used_size = 0; 81: while ((ch = getc(fp)) != EOF) { 82: if (ch == '\n') { 83: status = add_character('\0'); 84: if (status != READ_LINE_SUCCESS) 85: goto FUNC_END; 86: break; 87: } 88: status = add_character(ch); 89: if (status != READ_LINE_SUCCESS) 90: goto FUNC_END; 91: } 92: if (ch == EOF) { 93: if (st_current_used_size > 0) { 94: /*如果最终行后面没有换行*/ 95: status=add_character('\0'); 96: if (status != READ_LINE_SUCCESS){ 97: goto FUNC_END; 98: } else { 99: status = READ_LINE_EOF; 100: goto FUNC_END; 101: } 102: } 103: 104: line = malloc(sizeof(char) st_current_used_size); 105: if (*line == NULL) { 106: status = READ_LINE_OUT_OF_MEMORY; 107: goto FUNC_END; 108: } 109: strcpy(*line, st_line_buffer); 110: 111: FUNC_END: 112: if (status != READ_LINE_SUCCESS && status !=READ_LINE_EOF) { 113: free_buffer(); 114: } 115: return status; 116: }
goto常见的几个场合:
1.异常处理(如上)
2.跳出多重循环:
int i,j,k; for(i=0;i<n;i++){ for(j=0;j<n;j++){ for(k=0;k<n;k++){ if(a[i][j][k]==0)goto label; } } } label: printf("%d %d %d",i,j,k);
如果不用goto,结果将会变成:
int i,j,k; for(i=0;i<n;i++){ for(j=0;j<n;j++){ for(k=0;k<n;k++){ if(a[i][j][k]==0)break; } if(a[i][j][k]==0)break; } if(a[i][j][k]==0)break; } printf("%d %d %d",i,j,k);
总体说,goto不是不能用,而是要分清场合使用。如果写出这段代码:
a: if(flag)goto b; else goto c; func1(); b: if(flag2)goto a; else goto c; c: func2();func3(); flag2=0;goto d;
这样一段乱七八糟的代码,估计没有人想看吧。这就是乱用goto的例子。
不能乱用goto,不代表不能使用goto。在适当的场合使用goto,往往会达到事半功倍的效果。