在C语言longestCommonPrefix函数末尾声明void * p为何编译报错?
为什么无法在C语言的goto标签后声明变量?
我在用C语言解决LeetCode题目时,编译器出现了异常错误,不知道为什么没法在longestCommonPrefix函数的_while_end标签后声明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 ("%s\n", 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.
问题原因及解决方法
1. 标签后不能直接声明变量的原因
C语言语法规则明确:标签必须紧跟可执行语句或另一个标签,不能直接跟变量声明。哪怕是支持C99及以后标准的编译器(允许在代码块中间声明变量),标签后直接放变量声明也是不合法的——因为标签属于语句范畴,而变量声明不属于可执行语句,编译器会期望在标签后看到可执行代码。
2. 修复标签后的变量声明问题
有两种简单的修复方式:
- 方式一:给标签后的代码套代码块
在_while_end:后添加{},把变量声明和后续逻辑放在块内,让变量声明处于代码块的合法位置:
_while_end:
{
void * p = realloc (ans, len+1);
if (!p) return 0;
ans = p;
ans[len] = 0;
return ans;
}
- **方式二:提前声明变量** 在函数开头就声明`void *p;`,后续在标签后直接赋值使用: ```c char * longestCommonPrefix (char ** strs, int strsSize) { int bufsize = 16; int len = 0; char * ans = malloc(bufsize); void *p; // 提前声明变量 char ch; // ... 中间代码不变 _while_end: p = realloc (ans, len+1); if (!p) return 0; ans = p; ans[len] = 0; return ans; }
3. 顺便修复main函数的警告
main函数里的char ** s = {"asdf", "asdw", "asdfe"};类型不匹配,char**是指向指针的指针,不能直接用字符串字面量初始化。正确写法是定义字符串数组,数组名会自动退化为char*的指针:
int main () { char *s[] = {"asdf", "asdw", "asdfe"}; printf ("%s\n", longestCommonPrefix (s, 3)); return 0; }
内容的提问来源于stack exchange,提问作者George Potoshin
相关产品推荐
相关产品推荐

