我问的是关于 c# 的问题,但我认为它在大多数其他语言中都是一样的。
有没有人对表达式和语句有一个很好的定义,它们有什么区别?
最佳答案
表达式:计算出一个值的东西。示例:1+2/x
语句: 执行某项操作的一行代码。示例:GOTO 100
在最早的通用编程语言(如 FORTRAN)中,区别非常明显。在 FORTRAN 中,语句是一个执行单元,是您所做的事情。它不被称为“线”的唯一原因是因为有时它跨越多条线。表达式本身不能做任何事情……您必须将它分配给一个变量。
1 + 2 / X
在 FORTRAN 中是一个错误,因为它什么都不做。你必须用那个表达式做一些事情:
X = 1 + 2 / X
FORTRAN 并没有我们今天所知道的文法——这个想法与 Backus-Naur 形式 (BNF) 一起被发明,作为 Algol-60 定义的一部分。那时,语义的区别(“有一个值”与“做某事”)在句法中得到体现:一种短语是表达式,另一种是语句, 解析器可以区分它们。
后来的语言设计者模糊了这种区别:他们允许句法表达式来做事,他们允许句法语句具有值。 仍然存在的最早的流行语言示例是 C。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's answer)。
有两个“句法类别”(这是语句和表达式的技术名称)会导致重复工作。比如C有条件的两种形式,语句形式
if (E) S1; else S2;
和表达形式
E ? E1 : E2
有时人们想要不存在的重复:例如,在标准 C 中,只有一条语句可以声明一个新的局部变量——但这种能力非常有用,以至于 GNU C 编译器提供了一个 GNU 扩展,使表达式也可以声明局部变量。
其他语言的设计者不喜欢这种重复,他们很早就看到如果表达式可以有副作用和值,那么语句和表达式之间的句法区别就不是所有有用的东西——所以他们把它扔掉了。 Haskell、Icon、Lisp 和 ML 都是没有句法语句的语言——它们只有表达式。甚至类结构化循环和条件形式也被视为表达式,并且它们具有值——但不是很有趣。
关于language-agnostic - 表达与陈述,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19132/