语法错误与语义错误(所有语言通用版)

目录:

        导言:

        语法错误:

        语义错误:

        区分语法错误与语义错误:

        语义错误很可怕:

导言:

在我们日常写代码的日子里,难免会写出然我们意想不到的Bug(错误)但你也不需要担心,我们每一次写完Bug之后在此基础上修改时,其实都是在提升自己,避免以后再次遇到这种情况。无论你到底写出了什么样的Bug,这些Bug多半会分为两大类:语法Bug和语义Bug,但在技术领域中我们统称它们为:语法错误和语义错误。可能有些读者不明白这两个错误,所以为了帮助这类读者才有了这一篇文章。下面,我将逐一介绍这两个错误。

语法错误:

何为语法错误?你只需要知道导致编译器不可以正常执行程序的语句,这时语句的错误叫作语法错误。譬如在某个语言当中一个语句的结尾处忘了加上”;“,函数名写错等等,这都会导致编译器不可以执行我们所写的程序。但为了使读者更好理解作者所说的意思,所以在下文中我们会用一个例子来更好地说明”语法错误“这个概念:

假设小明开发了一个编程语言,这个编程语言中有一个函数叫作“print”,这个函数我们用于输出字符串,它可以把后面的字符串输出到控制台,之后要以一个“;”代表一条语句的结束,所以我们使用小明所开发的编程语言想要在控制台输出“Hello World”,我们应在他的编译器上这样输入:

print "Hello World";

但是小东在使用小明的编程语言输出“Hello World”时,不小心将表示语句结束的“;”给忘了

print "Hello World"

所以导致小东的代码执行不起来。在上文我们也说了,导致编译器不可以正常执行程序的语句,这时语句的错误叫作语法错误,所以小东写的这一条语句的错误是语法错误。

相信上文的例子可以让更多的读者理解“语法错误”这个概念。既然语法错误我们已经讲解完了,我们是时候该讲讲语义错误了。

语义错误:

还是小明这个编程语言开发者,也还是小东这个“编程语言”爱好者, 小明想要让小东输出一个字符串来证明此语言没有bug,因此小东要在这个编程语言中输出一个字符串,这个字符串叫做“string”,但小东这个“粗心大意”又误把“string”这个字符串的中“g”写成了与“g”相邻的“h”,所以小东在编译器输入的代码是这样的:

print"strinh";

这个代码运行的结果似乎不是小东理想的结果,小东理想的结果是“string”,但编译器给出的结果是“strinnh”。下一秒,小东看向自己在编译器输入的代码时,才发现自己写错了代码。虽然代码是一个bug,但编译器还是像若无其事样“跑”了起来。由此我们可以推断出:代码虽然执行了起来,但执行的效果不符合程序员理想的语句叫作“语义错误”。

区分语法错误与语义错误:

小明的编程语言在经历了几个月的风风雨雨后,终于可以在这个语言使用变量和运算符了。小东想要使用这个编程语言的新特性来干点有意义的事(这个编程语言的变量与操作符与大多数编程语言无异,所以读者不必担心学习到没有用的知识),他想要写个小程序如下(看不懂以下代码的读者请不必担心,我们会在代码旁做注释,注释以“#”开头):

​
​
num1 = 10;  #我们创建了一个变量叫"num1",我们使用"="(赋值操作符)来给"num1"赋值,它的值是10
num2 = num1 * num1; #再创建一个变量"num2",将"num1"乘"num1"的值赋给这个变量
num3 = num2 * num2; #在创建一个变量"num3",重复一遍上面的操作

print "num1这个变量的值是{nun},它的二次方是{num2},其次它的三次方是{num3}";
#使用"print"这个函数,"{}"是字符串插值,它可以把"{}"内的变量输出一遍

​

​

输出结果:num1这个变量的值是10,它的二次方是100,其次它的三次方是10000

我们来看看这个输出结果,很明显是不对的,”num1“这个变量的值是10,但它的三次方和我们预想中的结果不一致。10的三次方明明就是1000,这说明小东又写出了一个bug,我们在上文中已经讲过了语法错误与语义错误,想必大家已经知道是什么错误了吧。如果我们来帮助小东来修改应如何修改呢?下面是小东的代码修改之后的样子:

​


num1 = 10;  #我们创建了一个变量叫"num1",我们使用"="(赋值操作符)来给"num1"赋值,它的值是10
num2 = num1 * num1; #再创建一个变量"num2",将"num1"乘"num1"的值赋给这个变量
num3 = num1 * num1 * num1 #在创建一个变量"num3",它是"num1"的三次方

print "num1这个变量的值是{nun},它的二次方是{num2},其次它的三次方是{num3}";
#使用"print"这个函数,"{}"是字符串插值,它可以把"{}"内的变量输出一遍

​

可惜这次的效果更糟,没有输出结果,取而代之的是编译器上冷冰冰的错误提示,它提示小东检查每一条语句是否加上";"这个语句结束符,如果是这一类型的错误又是什么错误呢?我们不难发现小东的第六行代码没有加上语句结束符";".。只要加上";",整个程序就可以正常运行了。

加上";"后输出的结果:

输出结果:num1这个变量的值是10,它的二次方是100,其次它的三次方是1000

语义错误很可怕:

大多数读者会不会认为语义错误会比语法错误亲切许多,因为语法错误不会帮你运行,语义错误虽然可以运行,但输出的结果与自己理想中的效果不一样。但在亲切的背后还有一具可怕的面具。为什么这么说呢?因为只要你写了一个语法错误,大多数编译器会带有错误提示,它可以毫不费劲地找到你所写错的部分,并让你在此基础上进行修改,你也可以毫不费劲地修改。但如果一个错误的类型是语义错误,那你可得小心,编译器的错误提示不会帮助你找到此错误,你需要化身为“人工编译器”自己慢慢去找,这也就是大多数程序员改一个小bug改到深夜的重大原因,他们不是长时间去修改一个bug,而是花长时间在找错误的路上。这也足以证明语义错误比语法错误更可怕。

希望这一篇文章可以帮助不理解语句错误和语义错误与不可以区分语法错误与语义错误的”小朋友“。

猜你喜欢

转载自blog.csdn.net/m0_68824353/article/details/125963631
今日推荐