我问的是关于c#的问题,但我认为它在大多数其他语言中都是一样的。

有人对表达式和语句有很好的定义吗?它们的区别是什么?


当前回答

我更喜欢“陈述”这个词的形式逻辑意义。它改变了计算中一个或多个变量的状态,从而能够对它们的值做出真或假的声明。

我想,当新的术语或词汇被引入,现有的词汇被“重新定义”,或者用户对他们所描述的现有的、已建立的或“适当的”术语一无所知时,在计算世界和科学中总会出现困惑

其他回答

你可以在维基百科上找到这个,但是表达式被求值为某个值,而语句没有求值。

因此,表达式可以用在语句中,但不能用在语句中。

请注意,一些语言(如Lisp,我相信Ruby,以及许多其他语言)并不区分语句和表达式……在这样的语言中,所有东西都是一个表达式,并且可以与其他表达式连接。

我对这里的答案都不太满意。我查看了c++ (ISO 2008)的语法。然而,出于教学和编程的考虑,答案可能足以区分这两个元素(尽管现实看起来更复杂)。

语句由零个或多个表达式组成,但也可以是其他语言概念。这是语法的扩展巴克斯诺尔形式(语句节选):

statement:
        labeled-statement
        expression-statement <-- can be zero or more expressions
        compound-statement
        selection-statement
        iteration-statement
        jump-statement
        declaration-statement
        try-block

我们可以看到c++中被认为是语句的其他概念。

表达式-语句是自解释的(一个语句可以由0个或多个表达式组成,仔细阅读语法,这很棘手) 例如,Case是一个带标签的语句 选择语句是if if/else, case 迭代语句是while, do…然而,对于(……) 跳转语句有break, continue, return(可以返回表达式),goto Declaration-statement是声明的集合 try-block是表示try/catch块的语句 在语法中可能还有更多

以下是表达部分的节选:

expression:
        assignment-expression
        expression "," assignment-expression
assignment-expression:
        conditional-expression
        logical-or-expression assignment-operator initializer-clause
        throw-expression

表达式通常是或包含赋值 条件表达式(听起来容易误导人)指的是使用运算符(+,-,*,/,&,|,&&,||,…) 抛出表情——呃?throw子句也是一个表达式

语句是表达式的一种特殊情况,具有void类型。语言区别对待语句的倾向经常会导致问题,如果恰当地概括它们会更好。

例如,在c#中,我们有非常有用的Func<T1, T2, T3, TResult>重载泛型委托集。但是我们也必须有相应的Action<T1, T2, T3>集合,并且通用的高阶编程必须不断重复来处理这种不幸的分叉。

简单的例子——在调用另一个函数之前检查引用是否为空的函数:

TResult IfNotNull<TValue, TResult>(TValue value, Func<TValue, TResult> func)
                  where TValue : class
{
    return (value == null) ? default(TValue) : func(value);
}

编译器能处理TResult为空的可能性吗?是的。它所要做的就是要求return后面跟着一个void类型的表达式。default(void)的结果将是void类型,传递的func将需要是func <TValue, void>(这将等效于Action<TValue>)的形式。

其他一些答案暗示你不能像连接表达式那样连接语句,但我不确定这个想法是从哪里来的。我们可以想到;它作为二进制中缀运算符出现在语句之后,取void类型的两个表达式并将它们组合成一个void类型的表达式。

表达式可以求值得到一个值,而语句不返回值(它们是void类型)。

当然,函数调用表达式也可以被视为语句,但除非执行环境有一个特殊的内置变量来保存返回值,否则无法检索它。

面向语句的语言要求所有过程都是语句列表。面向表达式的语言,可能是所有的函数式语言,都是表达式的列表,或者在LISP的情况下,是一个表示表达式列表的长s表达式。

尽管这两种类型都可以组合,但只要类型匹配,大多数表达式都可以任意组合。每种类型的语句都有自己的方式来组合其他语句,如果它们可以做到这一切的话。Foreach和if语句要么要求单个语句,要么要求所有子语句一个接一个地放入语句块中,除非子语句允许它们自己的子语句。

语句还可以包括表达式,而表达式实际上不包括任何语句。不过,lambda表达式是一个例外,它表示一个函数,因此可以包括函数可以包含的任何东西,除非语言只允许有限的lambdas,比如Python的单表达式lambdas。

在基于表达式的语言中,你所需要的只是一个函数的单个表达式,因为所有的控制结构都返回一个值(其中很多返回NIL)。不需要return语句,因为函数中最后求值的表达式就是返回值。

表达式是产生一个值的任何东西: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