你写了一段循环,跑起来发现屏幕疯狂输出同一句话,出现错误像卡带的代码录音机。你盯着终端,出现错误心里冒出一个词——bug。代码对,出现错误就是代码它。但如果你只蹦出这一个词,出现错误旁边那个写C++的代码老哥可能就会纠正你:“这是运行时错误,不是出现错误语法问题。” 你看,代码同一个“错”,出现错误叫法能差出十万八千里。代码
我刚学编程那会儿,出现错误把分号漏了,代码编译器直接甩给我一行红字:expected ';' before '}' token。我拿去问人,对方扫了一眼:“语法错误。” 后来我又把数组越界了,程序没报错,但输出了乱码。这次没人说语法错误,他们管这叫段错误——Segmentation fault,名字听着就疼。
所以“错误”这个词太笼统了。就像你说“我身体不舒服”,医生得追问:是骨折、感冒、还是吃坏肚子?代码世界也一样,不同阶段、不同性质的问题,标签完全不同。
编译阶段出的错,通常叫编译错误或语法错误。编译器像个严格的语文老师,少个括号、类型对不上、变量没声明,它当场就拦下来,根本不让你生成可执行文件。这类错误最好对付——至少它告诉你哪儿错了,虽然有时候报错信息指向的位置和真正的问题隔了二十行。
但有些错误编译器管不着。程序跑起来之后才暴露的,叫运行时错误。除零、空指针解引用、数组越界,都属于这一类。它们不一定让程序崩溃,也可能悄悄算错结果。比如你写个除法,分母是用户输入,用户手滑输了个0——啪,程序挂了。这叫运行时错误,或者更具体点,叫算术异常。
还有一种更阴险的:逻辑错误。代码语法完美,跑起来也不崩,但结果就是不对。你写个排序,升序写成了降序;你算平均值,忘了除以个数。编译器不吭声,运行时也不报错,只有你盯着输出发呆:“为什么是42?” 这种错最难查,因为它不给你任何提示,全靠人脑去推。
我见过一个逻辑错误:有人用 if (x = 5) 代替了 if (x == 5)。赋值当比较,条件永远为真。程序跑得欢,就是行为诡异。这叫“赋值与相等混淆”,属于逻辑错误里的经典款。
再往深了说,还有异常(exception)和错误(error)的区分。在Java里,Exception和Error是两棵不同的继承树。前者你可以catch,后者通常意味着JVM自身出了问题,比如OutOfMemoryError。你抓不住它,只能让它崩。
Python那边又不一样。它把所有问题都叫异常,SyntaxError是异常,ZeroDivisionError也是异常。你写个try...except,能抓住一大半。但IndentationError这种,属于语法层面的,抓不抓得住得看版本。
所以回到标题那个问题:代码出现错误叫什么?答案取决于谁在什么阶段发现了什么性质的问题。编译器发现的叫编译错误,运行时炸的叫运行时错误,悄悄算错的叫逻辑错误。还有一堆别名:bug、defect、fault、failure……每个词背后都对应着不同的排查思路和修复成本。
我自己的习惯是:先看报错信息属于哪一类。如果是编译错误,直接读提示,改语法;如果是运行时错误,看堆栈,定位到具体行;如果是逻辑错误——那就泡杯茶,打开调试器,一行行跟。最怕的是那种不报错、不崩溃、但结果就是不对的代码。它像房间里的一只蚊子,你知道它在,但拍不到。
下次有人跟你说“我的代码出错了”,你可以多问一句:“是编译不过,还是跑起来崩了,还是结果不对?” 三个问题一抛,对方大概率会愣一下,然后你就能帮他省下半小时的瞎猜。代码错误的名字,本身就是一条排查线索。
```