在C中为什么你需要一个goto标签后的声明?
我正在编写一些C代码,在我的代码中我有两个嵌套循环。 在特定条件下,我想要break
内循环并continue
外循环。 我尝试使用外部循环代码末尾的标签来实现这一点,并在条件下goto
该标签。 但是gcc
给出的错误是我在复合语句的末尾没有标签。 为什么不?
注1:这不是一个switch
语句, 这个问题已在其他地方得到解答。
注2:这不是关于样式的问题,而是我应该或不应该使用goto
语句或条件变量。
编辑:人们已经要求一个例子,我可以给出一个轻微的例子,检查一个数组是否是另一个数组的子数组
int superArray[SUPER_SIZE] = {...}, subArray[SUB_SIZE] = {...}; int superIndex, subIndex; for (superIndex=0; superIndex<SUPER_SIZE-SUB_SIZE; superIndex+=1) { for (subIndex=0; subIndex<SUB_SIZE; subIndex+=1) if (superArray[superIndex+subIndex] != subArray[subIndex]) goto break_then_continue; // code that executes if subArray is a sub array break_then_continue: }
在标准中,它明确表示标签属于一个语句,因此标签之后的一个简单的分号( ;
)可以规避您运行的问题,因为它被视为一个语句。
在6.8.3 / 6中甚至有一个使用“ 空 ” 1语句的例子。
示例3 null语句也可用于在复合语句的结束之前携带标签
while (loop1) { /* ... */ while (loop2) { /* ... */ if (want_out) goto end_loop1; /* ... */ } /* ... */ end_loop1: ; }
1 在标准中,这被称为null statement
。
6.8.1标记语句
Syntax 1 labeled-statement: identifier : statement case constant-expression : statement default : statement
请注意,上述报价中的statement
不是可选的。
- open-std.org:n1124.pdf
你只需要写:
label: ;
分号是一个空的陈述。 你需要它,因为语言是这样定义的; 你需要去发表声明,即使声明是空的。
for (int i = 0; i < N; i++) { for (int j = 0; i < M; j++) { ... if (some_condition) goto continue_loop1; ... } continue_loop1: ; }
你可以争论标签上的缩进。
标签应指向一个声明。
C强制要求:
(C99,6.8.1标记语句p4)“任何语句前面都可以有一个前缀,用于将标识符声明为标签名称。”
在您的情况下,您可以使用null语句:
void foo(void) { goto bla; bla: ; }
空语句不执行任何操作。
或者,如果您有声明,也可以使用复合语句(块):
void foo(void) { goto bla; bla: { int x = 42; printf("%d\n", x); } }