问题描述
为了使用 goto
语句,我在更汇编风格的循环中重写了 while
循环:
// while
int i=0;
while (i++<10)
printf("%d...",i);
// asm-ish
loop:
i++;
printf("%d...",i);
if (i<10)
goto loop;
loop_exit:
return 0;
除了某种学术练习之外,是否有任何实际/有用的示例说明如何使用 goto
语句?或者这基本上是未使用的 c 的残余部分。
以下是一个广泛使用它的代码文件示例:https://github.com/postgres/postgres/blob/ca3b37487be333a1d241dab1bbdd17a211a88f43/src/port/snprintf.c。
我想我能想到的一件事是在不必使用一堆 continue
/break
的情况下摆脱深层嵌套,但仅此而已。
解决方法
虽然您可以以这种方式使用 goto
,但它通常被认为是不好的风格,因为该语言具有其他结构,例如 while
,它们在“清洁器”中执行相同的操作时尚。
曾经使用 goto
的地方是为了错误处理情况而向前跳。例如,这个:
void foo()
{
char *p1 = NULL,*p2 = NULL,*p3 = NULL,*p4 = NULL;
p1 = malloc(1000);
if (!p1) {
perror("malloc failed");
return;
}
p2 = malloc(1000);
if (!p2) {
perror("malloc failed");
free(p1);
return;
}
p3 = malloc(1000);
if (!p3) {
perror("malloc failed");
free(p2);
free(p1);
return;
}
p4 = malloc(1000);
if (!p4) {
perror("malloc failed");
free(p3);
free(p2);
free(p1);
return;
}
// Do something with p1,p2,p3,p4
free(p4);
free(p3);
free(p2);
free(p1);
}
可以翻译成这样:
void foo()
{
char *p1 = NULL,*p4 = NULL;
p1 = malloc(1000);
if (!p1) {
perror("malloc failed");
goto err0;
}
p2 = malloc(1000);
if (!p2) {
perror("malloc failed");
goto err1;
}
p3 = malloc(1000);
if (!p3) {
perror("malloc failed");
goto err2;
}
p4 = malloc(1000);
if (!p4) {
perror("malloc failed");
goto err3;
}
// Do something with p1,p4
free(p4);
err3:
free(p3);
err2:
free(p2);
err1:
free(p1);
err0:
return;
}
这会将所有清理代码放在一个地方。