You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 14:36:19