TCC编译器第26行报“lvalue expected”错误原因咨询
嘿,很高兴能帮到你——重新捡回C语言确实会遇到一些容易忘的细节,别担心,咱们一步步来拆解问题!
首先说你最关心的第26行"lvalue expected"错误:
你写的inp = input();里,inp是一个数组名。在C语言中,数组名是一个不可修改的左值——它本质上是指向数组第一个元素的常量指针,你不能直接用赋值运算符=给它赋值。编译器期望这里是一个可以被修改的左值,但数组名不符合要求,所以报了这个错。
接下来咱们顺便把其他问题也一起理清楚,因为你的代码还有几个会导致运行问题或警告的点:
1. input函数的严重隐患
你的input()函数返回的是局部数组inp的指针,而局部变量在函数执行完毕后就会被销毁,这块内存会被系统回收或重新使用。返回这个指针会导致未定义行为——后续使用这个指针时,读取的内容是不确定的,可能会崩溃或出现奇怪的结果。
修复方法有两种:
- 让调用者传入数组作为参数,比如修改
input为void input(char* inp, int size),然后在函数里用安全的方式读取输入; - 在
input里用malloc动态分配内存,比如char* inp = malloc(256);,记得之后要调用free释放内存,避免内存泄漏。
2. 第15行的警告原因
void output(outp)这个函数的参数outp没有声明类型,在旧版C标准中会默认当作int类型,但你传入的是char*,所以编译器会警告“赋值把整数转成指针没加类型转换”。你需要明确参数类型:void output(char* outp)。
3. 字符串比较的错误
if (inp == "END")这种写法是错的,==比较的是两个指针的地址,而不是字符串的内容。要比较字符串内容,应该用strcmp函数,记得要包含<string.h>头文件,改成if (strcmp(inp, "END") == 0)。
4. gets函数不安全
gets函数不会检查输入的长度,很容易导致缓冲区溢出,现在已经被C标准废弃了,建议用fgets代替,比如fgets(inp, sizeof(inp), stdin)。注意fgets会把换行符也读进去,如果不需要的话,可以手动去掉:
char* newline = strchr(inp, '\n'); if (newline != NULL) { *newline = '\0'; }
修改后的示例代码
这里给你一个修复后的版本参考(调用者传入数组的方式):
#include <stdio.h> #include <string.h> // 调用者传入数组,避免局部变量指针问题 void input(char* inp, int size) { fgets(inp, size, stdin); // 去掉换行符 char* newline = strchr(inp, '\n'); if (newline != NULL) { *newline = '\0'; } } void output(char* outp) { puts(outp); } int main() { int exe = 1; char inp[256]; char exit_msg[] = "END OF PROGRAM. THANK YOU!"; // 字符串字面量会自动加\0,无需手动添加 while(exe) { input(inp, sizeof(inp)); // 传入数组和大小 output(inp); if (strcmp(inp, "END") == 0){ exe = 0; } } puts(exit_msg); return 0; }
内容的提问来源于stack exchange,提问作者Lee David O'Dea

