C中的语义错误和逻辑错误有什么区别?

时间:2018-02-02 16:42:26

标签: c

1

localhost/dist

2

   int a=6, b=5, c;
        a + b = c;
        printf("%d", c);
        return 0;

哪个是syme​​ntic错误,哪个是逻辑错误?

我的另一个问题 - 在编译期间始终检测到语义错误是否正确?请举一些例子。

3 个答案:

答案 0 :(得分:1)

首先是语法错误,其次是逻辑。

想一个像句子一样的程序。让句子为“我去河边睡觉”。这里“go”是语法(语法)错误,你马上就会看到它。而你的老师(编译器)给出了错误。但“在河中睡觉”是逻辑错误。一个人可以在河里睡觉,但这将毫无意义。

所以,你的函数承诺返回一个矩形区域,但做其他事情。这就是逻辑错误。

答案 1 :(得分:1)

语法错误,您将其称为语义错误(symentic? - 它与逻辑相同,所以我猜你的意思是语法)只是一个直接的错字(就像写mether而不是的母亲)。编程语言是一种严格的语言,必须由编译器理解。语法错误是以错误的方式编写语言(程序):

C

是错误的,因为在width*height 语言中不存在这样的语法。编译器将确认这一点。

逻辑错误是最糟糕的一种 - 程序中的大错误。一个逻辑错误是当你正确编写整个程序时,编译器根本不会抱怨,并且程序似乎运行并给出结果,但结果是错误的!如您所知,矩形区域为

return (height + width);

但你有

{{1}}

这是一个逻辑(语义)错误 - 你的函数将运行并输出一个数字,但它将远离正确的数字。

答案 2 :(得分:0)

语法(或语法)描述程序的结构 - 应该是什么函数,语句和表达式。例如,for循环 1 的语法是

for ( expressionopt ; expressionopt ; expressionopt ) statement

因此,语法错误是程序结构中的一个错误 - 你缺少一个分号,或者花括号或括号不匹配,你拼错了一个关键字,就像这样。编译器 required 发出诊断 2 以解决语法错误。

但是,单独的语法不能指定诸如“必须在使用前声明变量”之类的规则,或者“赋值的目标必须是可修改的左值”,或者“赋值的源和目标必须是兼容类型”, 语义规则(C标准称它们为约束)描述哪些程序结构有意义 - 只是因为语句在语法上是有效的意味着它具有语义意义。例如,这是声明语法的一部分:

declaration:
    declaration-specifiers init-declarator-listopt ;
    static_assert-declaration

declaration-specifiers:
    storage-class-specifier declaration-specifiersopt
    type-specifier declaration-specifiersopt
    type-qualifier declaration-specifiersopt
    function-specifier declaration-specifiersopt
    alignment-specifier declaration-specifiersopt

现在,仅基于语法,我们可以提出类型说明符,类型限定符等的任意组合。语法允许类似

的内容
int char long short unsigned double float foo;

但还有其他约束指定哪些类型说明符组合有意义。 long longlong double以及unsigned short int是有意义的。 double charfloat long int不是。

因此,语义错误(或约束违规)是程序的含义中的错误 - 您错过了声明在某个地方,或者你正试图分配给不应该写的东西,这样的东西。与语法错误一样,编译器 required 为违反约束发出诊断。

那么,a + b = c;是语法错误还是语义错误?这是赋值的语法:

assignment-expression:
    conditional-expression
    unary-expression assignment-operator assignment-expression

assignment-operator: one of
    = *= /= %= += -= >= &= ^= |=

a + b是否会缩减为一元表达式?基于我对语法的阅读,它确实:

additive-expression:
    multiplicative-expression
    additive-expression + multiplicative-expression
    additive-expression - multiplicative-expression

multiplicative-expression:
    cast-expression
    multiplicative-expression * cast-expression
    multiplicative-expression / cast-expression
    multiplicative-expression % cast-expression

cast-expression:
    unary-expression
    ( type-name ) cast-expression

以下是我看到它减少的方式:

a + b =>
    additive-expression + multiplicative-expression =>
    additive-expression =>
    multiplicative-expression =>
    cast-expression =>
    unary-expression

所以,乍一看,这似乎不是语法错误。如果不是,它肯定是一个语义错误(违规约束违规),这就是gcc报告它的方式:

error: invalid lvalue in assignment

lvalues 只能在语义级别而不是语法级别上进行。 a + b的结果不是左值 - 它与您可以写入新值的位置不对应,因此它不能作为赋值的目标。

逻辑错误(a.k.a. bug)是程序的实现中的错误。例如,计算矩形区域的函数实现不正确。 有时,逻辑错误会触发约束违规,但并非总是如此。这就是你测试的原因。

<小时/>

  1. C 2011 Online Draft
  2. C语言标准不区分“警告”和“错误”;它只强制要求对语法错误和约束违规发出某种诊断。