C 程序常见编译错误与排查方法
ResourcesC 程序常见编译错误与排查方法
本页使用 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 中建议显示文件扩展名后检查实际文件名。
运行后才出现的结果错误、死循环、数组越界、异常退出等问题,不属于编译错误,参见常见运行错误 。