当编译器给我一个奇怪的错误时,我正在解决c中的leetcode问题。为什么我不能在longestCommonPrefix
函数的末尾声明void * p
?
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
char * longestCommonPrefix (char ** strs, int strsSize) {
int bufsize = 16;
int len = 0;
char * ans = malloc(bufsize);
char ch;
while (true) {
ch = (*strs)[len];
for (int i = 1; i < strsSize; i++) {
if ((strs[i])[len] != ch || (strs[i])[len] == 0) goto _while_end;
}
if (len == bufsize) {
bufsize += 16;
void * p = realloc (ans, bufsize);
if (!p) return NULL;
ans = p;
}
ans[len++] = ch;
}
_while_end:
void * p = realloc (ans, len+1);
if (!p) return 0;
ans = p;
ans[len] = 0;
return ans;
}
int main () {
char ** s = {"asdf", "asdw", "asdfe"};
printf ("%sn", longestCommonPrefix (s, 3));
return 0;
}
main.c:27:2: error: expected expression
void * p = realloc (ans, len+1);
^
main.c:28:7: error: use of undeclared identifier 'p'
if (!p) return 0;
^
main.c:29:8: error: use of undeclared identifier 'p'
ans = p;
^
main.c:35:15: warning: incompatible pointer types initializing 'char **' with an expression of type 'char [5]' [-Wincompatible-pointer-types]
char ** s = {"asdf", "asdw", "asdfe"};
^~~~~~
main.c:35:23: warning: excess elements in scalar initializer [-Wexcess-initializers]
char ** s = {"asdf", "asdw", "asdfe"};
^~~~~~
2 warnings and 3 errors generated.
在C中,只能标记语句,不能标记声明。声明和声明是两个独立的类别。(在C++中,声明被包含在语句中,而不是单独的,并且可以被标记。(我不认为这有技术原因(例如语言的形式语法中的一些冲突(;它只是C语言发展的遗留问题。
一个简单的解决方法是简单地使用一个带有标签的null语句;
:
_while_end:
;
void * p = realloc (ans, len+1);
不确定为什么@mykola的答案被接受,但真正的原因是因为goto
标签不能在声明之前,它们只能在语句之前。
有几种解决方案,其中一种在评论中概述,但如果你真的想在标签后面声明,你可以在标签后面强制声明,如下所示:
_while_end:; //<-- note semicolon
void *p = realloc (ans, len+1);