表达与声明

我问的问候C#,但我认为它在大多数其他语言相同。

有没有人对表达和声明有很好的定义,并且有什么不同?


表达式:评估为某个值的东西。 例如:1 + 2 / x
声明:执行某些操作的代码行。 例如:GOTO 100

在最早的通用编程语言,如FORTRAN中,这种区分非常清晰。 在FORTRAN,一个声明是一个执行单位,这是你所做的一件事。 没有被称为“线路”的唯一原因是因为有时它跨越了多条线路。 一个表达本身无法做任何事......你必须将它分配给一个变量。

1 + 2 / X

是FORTRAN中的错误,因为它什么都不做。 你必须用这种表达方式做点什么:

X = 1 + 2 / X

FORTRAN没有我们今天所知的语法 - 这个想法是与Backus-Naur Form(BNF)一起发明的,作为Algol-60定义的一部分。 在这一点上,语义上的差异(“有价值”与“做某事”)被赋予了语法:一种短语是表达式,另一种是语句,分析者可以将它们区分开来。

后来语言的设计者模糊了这种区别:它们允许语法表达式做事,并且它们允许具有值的语法语句。 最早流行的语言例子仍然存在.C的设计者意识到,如果允许您评估表达式并丢弃结果,则不会造成任何伤害。 在C语言中,每个句法表达式都可以通过在末尾添加分号来形成语句:

1 + 2 / x;

尽管绝对没有任何事情会发生,但这是完全合法的声明 同样,在C语言中,表达式可能有副作用 - 它可以改变某些东西。

1 + 2 / callfunc(12);

因为callfunc可能只是做一些有用的事情。

一旦你允许任何表达式成为一个语句,你也可以在表达式中允许赋值操作符(=)。 这就是为什么C可以让你做类似的事情

callfunc(x = 2);

这将计算表达式x = 2(将值2分配给x),然后将该值(2)传递给函数callfunc

表达式和语句模糊化发生在所有C语言衍生物(C,C ++,C#和Java)中,它们仍然有一些语句(如while ),但几乎允许任何表达式作为语句使用(仅在C#中赋值,调用,递增和递减表达式可以用作语句;参见Scott Wisniewski的答案)。

有两个“语法类别”(这是某种事物语句和表达的技术名称)会导致重复工作。 例如,C有两种形式的条件语句形式

if (E) S1; else S2;

和表达形式

E ? E1 : E2

有时候人们希望重复不在那里:例如,在标准C中,只有一个语句可以声明一个新的局部变量 - 但是这个功能足够有用,GNU C编译器提供了一个GNU扩展,使得表达式能够声明一个局部变量也是如此。

其他语言的设计者不喜欢这种重复,他们很早就看到,如果表达式可能有副作用和值,那么语句和表达式之间的语法区别并不是那么有用 - 所以他们摆脱了它。 Haskell,Icon,Lisp和ML都是没有语法语句的语言 - 它们只有表达式。 即使是类结构化的循环和条件形式也被视为表达式,并且它们具有值 - 但不是非常有趣的。


我想对乔尔的回答做一个小的更正。

C#不允许将所有表达式用作语句。 特别是,只能使用赋值,调用,增量和减量表达式作为语句。

例如,C#编译器会将以下代码标记为语法错误:

1 + 2;


  • 表达式是产生值的任何东西:2 + 2
  • 声明是程序执行的基本“块”之一。
  • 请注意,在C中,“=”实际上是一个运算符,它有两个作用:

  • 返回右边子表达式的值。
  • 将右侧子表达式的值复制到左侧的变量中。
  • 这里是ANSI C语法的摘录。 您可以看到C没有多种不同的语句......程序中的大多数语句都是表达式语句,即末尾带有分号的表达式。

    statement
        : labeled_statement
        | compound_statement
        | expression_statement
        | selection_statement
        | iteration_statement
        | jump_statement
        ;
    
    expression_statement
        : ';'
        | expression ';'
        ;
    

    http://www.lysator.liu.se/c/ANSI-C-grammar-y.html

    链接地址: http://www.djcxy.com/p/51679.html

    上一篇: Expression Versus Statement

    下一篇: Restricting eval() to a narrow scope