为什么 C 使用语句作为 for-loop 的条件?

Why does C use statement as for-loop's condition?

如标题所说。如果我没记错的话,语句不应该 return 任何值,那么 C 如何从语句中检索值? (是的,我知道编译器可以做到这一点,但这需要一些技巧,而且并不漂亮。)

而且for循环的自增部分是一个表达式,这也很容易混淆,因为你永远不需要自增操作的return值。

我所有的C语法知识都来自here

事实上,我正在编写一个试图遵循 C 语法的 DSL,但在实现 for-loop 时感觉很不对劲,尤其是我决定将赋值作为语句而不是表达式。

在C中for循环有两种语法形式,它们都没有使用语句作为条件

for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
for ( declaration expression[opt] ; expression[opt] ) statement

在您的 link 显然有人试图使用 expression_statement 来替代 expression,然后是 ;。这在语法上可能有效,但它并不反映这种语言结构的语义。从语义上讲,该语言在那里看不到任何 "statements"。语言看到并使用表达式。

And the increment part of for loop is a expression, which is very confusing too, because you would never need the increment operation's return value.

但是 [几乎] C 语言中的每个表达式语句都是如此。表达式语句中完整表达式的结果总是被丢弃。每次你说

printf("Hello World");

您丢弃 printf 的结果。每次你做

a = b + c;

您丢弃了整个表达式的结果。

您误读了参考资料 material — Lysator 的 ANSI C Yacc Grammar。它说:

iteration_statement
    : WHILE '(' expression ')' statement
    | DO statement WHILE '(' expression ')' ';'
    | FOR '(' expression_statement expression_statement ')' statement
    | FOR '(' expression_statement expression_statement expression ')' statement
    ;

它们是 expression_statements,而不是 statements。在循环的条件部分使用表达式是有意义的。

expression_statement
    : ';'
    | expression ';'
    ;

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

看一下,这是 C90 的语法,而不是 C99 或 C11——你可以从日期和内容上看出来。请注意,自编写以来,C 已经发展。没有彻底改变,但确实改变了。

有趣:然而,这种说法:

FOR '(' expression_statement expression_statement ')' statement 

不编译。这是一个例子:

#include <stdio.h>

int main()
{
    int a;
    //FOR '(' expression_statement expression_statement ')' statement
    for( a=0; a<10 ) printf( "a=%d\n", a );
    return 0;
}

这导致编译器输出:

  gcc -ggdb  -Wall -Wextra  -Wconversion -std=gnu11 -pedantic -Wmissing-prototypes  -c "untitled2.c"  -I.   (in directory: /home/rkwill/Documents/forum)
untitled2.c: In function ‘main’:
untitled2.c:7:20: error: expected ‘;’ before ‘)’ token
    for( a=0; a<10 ) printf( "a=%d\n", a );
                ^
Compilation failed.