C Programming

Courses

C 程序常见编译错误与排查方法

Resources

C 程序常见编译错误与排查方法

本页使用 GCC 的报错作为示例。不同版本的 GCC 报错文字可能略有差异。

error 通常会导致编译失败;warning 表示代码存在可疑之处,也应检查。

1. 找不到 gcc

报错:

gcc: command not found

或 PowerShell 提示:

gcc is not recognized

原因: GCC 未安装,或 GCC 所在目录没有加入 Path。

检查:

gcc --version

参见 VS Code 安装与配置 。

2. 缺少分号

报错:

expected ';'

错误:

int a = 10
printf("%d\n", a);

正确:

int a = 10;
printf("%d\n", a);

报错位置有时位于真正错误的下一行。

3. 使用中文标点

报错:

stray

或出现无法识别的字符。

错误:

printf(“hello\n”);

正确:

printf("hello\n");

代码中的括号、逗号、分号和引号应使用英文半角字符。

4. 圆括号不配对

报错:

expected ')'

错误:

printf("%d\n", x;

正确:

printf("%d\n", x);

5. 花括号不配对

报错:

expected '}'

或:

expected declaration or statement at end of input

错误:

int main(void)
{
    printf("Hello\n");

正确:

int main(void)
{
    printf("Hello\n");
}

6. 字符串缺少结束引号

报错:

missing terminating " character

错误:

printf("Hello);

正确:

printf("Hello");

7. 字符常量缺少引号

错误:

char ch = A;

编译器会把 A 当作名称。

正确:

char ch = 'A';

字符使用单引号,字符串使用双引号:

'A'
"ABC"

8. 变量未声明

报错:

undeclared

错误:

x = 10;

正确:

int x;
x = 10;

或:

int x = 10;

9. 变量名拼写错误

报错:

undeclared

错误:

int count = 10;

printf("%d\n", cout);

正确:

printf("%d\n", count);

C 区分大小写:

count
Count
COUNT

是三个不同的名称。

10. 重复定义变量

报错:

redefinition

错误:

int x = 10;
int x = 20;

正确:

int x = 10;
x = 20;

11. 使用了未声明的函数

报错或警告:

implicit declaration of function

错误:

int main(void)
{
    int x = add(1, 2);
    return 0;
}

int add(int a, int b)
{
    return a + b;
}

正确:

int add(int a, int b);

int main(void)
{
    int x = add(1, 2);
    return 0;
}

int add(int a, int b)
{
    return a + b;
}

12. 函数声明与定义不一致

报错:

conflicting types

错误:

int add(int, int);

double add(int a, int b)
{
    return a + b;
}

正确:

int add(int, int);

int add(int a, int b)
{
    return a + b;
}

13. 函数参数数量错误

报错:

too few arguments to function

或:

too many arguments to function

定义:

int add(int a, int b);

错误:

add(1);
add(1, 2, 3);

正确:

add(1, 2);

14. 函数参数类型不匹配

警告或报错:

incompatible type for argument

定义:

void print_number(int x);

错误:

print_number("10");

正确:

print_number(10);

15. 函数重复定义

报错:

redefinition of

错误:

int add(int a, int b)
{
    return a + b;
}

int add(int a, int b)
{
    return a + b;
}

一个函数只能有一个定义。

16. printf / scanf 未声明

报错或警告:

implicit declaration of function 'printf'

原因: 未包含 <stdio.h>。

错误:

int main(void)
{
    printf("Hello\n");
}

正确:

#include <stdio.h>

int main(void)
{
    printf("Hello\n");
}

17. 头文件名称错误

报错:

fatal error: xxx.h: No such file or directory

错误:

#include <studio.h>

正确:

#include <stdio.h>

18. #include 写法错误

错误:

include <stdio.h>

正确:

#include <stdio.h>

预处理指令以 # 开头。

19. #include 文件名缺少括号或引号

错误:

#include stdio.h

正确:

#include <stdio.h>

自定义头文件通常写为:

#include "myheader.h"

20. scanf 缺少 &

警告:

format '%d' expects argument of type 'int *'

错误:

int n;
scanf("%d", n);

正确:

int n;
scanf("%d", &n);

21. scanf 格式说明符错误

错误:

double x;
scanf("%f", &x);

正确:

double x;
scanf("%lf", &x);

常用格式:

类型scanf
int%d
float%f
double%lf
char%c

22. printf 格式说明符与参数不匹配

警告:

format specifies type ... but the argument has type ...

错误:

double x = 3.14;
printf("%d\n", x);

正确:

printf("%f\n", x);

常用格式:

类型printf
int%d
char%c
double%f
字符串%s

23. % 后的格式说明符不存在

警告:

unknown conversion type character

错误:

printf("%q\n", x);

应使用与数据类型对应的有效格式说明符。

24. 数组下标中缺少右方括号

报错:

expected ']'

错误:

int a[10;

正确:

int a[10];

25. 数组初始化元素过多

警告:

excess elements in array initializer

错误:

int a[3] = {1, 2, 3, 4};

正确:

int a[3] = {1, 2, 3};

或:

int a[] = {1, 2, 3, 4};

26. 数组长度不是合法的常量

在需要常量表达式的场合,数组长度必须满足对应 C 标准和编译环境的要求。

错误示例:

const int N = 10;
int a[N];

在某些编译模式或使用场景下可能无法作为编译期数组长度使用。

初学阶段可使用:

#define N 10

int a[N];

或直接写:

int a[10];

27. switch 中重复 case

报错:

duplicate case value

错误:

switch (x)
{
case 1:
    break;

case 1:
    break;
}

每个 case 值必须唯一。

28. case 写在 switch 外

报错:

case label not within a switch statement

错误:

case 1:
    printf("1\n");

case 必须位于 switch 语句中。

29. break 使用位置错误

报错:

break statement not within loop or switch

错误:

int main(void)
{
    break;
}

break 只能用于循环或 switch。

30. continue 使用位置错误

报错:

continue statement not within a loop

错误:

int main(void)
{
    continue;
}

continue 只能用于循环。

31. else 没有对应的 if

报错:

else without a previous if

错误:

if (x > 0)
{
    printf("positive\n");
}

printf("test\n");

else
{
    printf("other\n");
}

else 必须与对应的 if 构成完整结构。

32. else if 写法错误

错误:

else (x == 0)
{
    printf("zero\n");
}

正确:

else if (x == 0)
{
    printf("zero\n");
}

33. for 语句缺少分号

报错:

expected ';'

错误:

for (int i = 0, i < 10, i++)

正确:

for (int i = 0; i < 10; i++)

for 的三个部分使用分号分隔。

34. 把赋值表达式写在需要比较的位置

示例:

if (x = 10)
{
    ...
}

这通常不会产生编译错误,但编译器可能给出警告。

如果要比较:

if (x == 10)
{
    ...
}

35. 不合法的赋值对象

报错:

lvalue required as left operand of assignment

错误:

10 = x;

或:

x + 1 = 5;

赋值运算符左侧必须是可以被修改的对象:

x = 10;

36. 修改只读对象

报错:

assignment of read-only variable

错误:

const int x = 10;
x = 20;

使用 const 定义的对象不能再次赋值。

37. 类型名写错

报错:

unknown type name

错误:

integer x;

正确:

int x;

常见基本类型包括:

char
int
float
double

38. 声明语法错误

错误:

int = x;

正确:

int x;

变量声明的基本形式是:

类型 名称;

39. 使用了 C++ 语法

C 与 C++ 是不同的语言。

例如,在 C 源文件中:

cout << x;

通常无法直接编译。

C 中可使用:

printf("%d\n", x);

同样,.c 文件通常使用 gcc 编译;.cpp 文件通常使用 g++ 编译。

40. 使用了当前 C 标准不支持的语法

例如:

for (int i = 0; i < 10; i++)
{
    ...
}

需要 C99 或更新的 C 标准。

如果编译环境使用较旧标准,可能出现:

'for' loop initial declarations are only allowed in C99 or C11 mode

可以使用相应标准编译:

gcc main.c -std=c11 -o main.exe

41. return 返回值类型不匹配

示例:

int f(void)
{
    return "hello";
}

函数声明返回 int,却返回了字符串。

正确:

int f(void)
{
    return 10;
}

42. 非 void 函数没有返回值

警告:

control reaches end of non-void function

错误:

int add(int a, int b)
{
    int c = a + b;
}

正确:

int add(int a, int b)
{
    int c = a + b;
    return c;
}

43. void 函数返回一个值

错误或警告:

void print_number(int x)
{
    return x;
}

void 表示函数不返回值。

可以写:

void print_number(int x)
{
    printf("%d\n", x);
    return;
}

44. 指针类型不匹配

警告:

incompatible pointer type

错误:

int x = 10;
double *p = &x;

正确:

int x = 10;
int *p = &x;

45. 把整数直接赋给指针

警告:

makes pointer from integer without a cast

错误:

int *p = 10;

指针保存的是地址,而不是普通整数值。

46. 把指针赋给普通整数

警告:

makes integer from pointer without a cast

错误:

int x;
int *p = &x;

int y = p;

如果需要取得 x 的值:

int y = *p;

47. 结构体成员不存在

报错:

has no member named

定义:

struct Student
{
    int age;
};

错误:

struct Student s;
s.name = 10;

结构体中并不存在 name 成员。

48. . 和 -> 使用错误

普通结构体变量使用 .:

struct Student s;
s.age = 18;

结构体指针使用 ->:

struct Student *p = &s;
p->age = 18;

混用时可能出现类型相关的编译错误。

49. 枚举、变量或其他名称重复

报错:

redeclaration

或:

redefinition

例如同一作用域中:

int value;
double value;

同一个名称不能同时作为两个不同变量的定义。

50. 链接时找不到函数

报错:

undefined reference to

例如:

undefined reference to `add'

常见原因:

  • 函数只有声明,没有定义;
  • 函数名拼写不一致;
  • 定义函数的 .c 文件没有参与链接。

例如:

gcc main.c math_utils.c -o main.exe

可以同时编译并链接多个源文件。

51. 找不到 main

报错可能包含:

undefined reference to `main'

程序需要入口函数:

int main(void)
{
    return 0;
}

初学阶段建议统一使用这种标准形式。

52. 同一函数被多个源文件重复定义

链接错误:

multiple definition of

例如两个 .c 文件中都定义了:

int add(int a, int b)
{
    return a + b;
}

链接时会发生重复定义。

53. 数学函数链接失败

代码:

#include <math.h>

double x = sqrt(4.0);

某些 GCC 环境中可能出现:

undefined reference to `sqrt'

需要链接数学库:

gcc main.c -lm -o main

Windows 使用的 GCC 发行版可能不需要显式添加 -lm。

54. 源文件不存在

报错:

fatal error: main.c: No such file or directory

例如:

gcc main.c -o main.exe

但当前目录中没有 main.c。

应确认文件名和当前工作目录。

55. 输出文件无法写入

Windows 下有时会出现:

Permission denied

例如:

cannot open output file main.exe: Permission denied

常见原因是旧的 main.exe 仍在运行,导致编译器无法覆盖它。

结束正在运行的程序后重新编译。

56. 文件扩展名错误

例如代码文件实际保存为:

main.c.txt

而不是:

main.c

可能导致编译命令找不到文件或编辑器无法按 C 源文件处理。

在 Windows 中建议显示文件扩展名后检查实际文件名。

运行后才出现的结果错误、死循环、数组越界、异常退出等问题,不属于编译错误,参见常见运行错误 。