为什么C使用语句作为for循环的条件?

时间:2018-03-10 19:13:02

标签: c grammar

就像标题所说的那样。如果我没记错,语句不应该返回任何值,那么C如何从语句中检索值? (是的,我知道编译器可以做到这一点,但这需要一点点黑客,而不是很漂亮。)

for循环的增量部分是一个表达式,这也非常令人困惑,因为你永远不需要增量操作的返回值。

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

事实上,我正在编写一个试图遵循C语法的DSL,但是在实现for循环时它感觉非常错误,特别是我决定使赋值语不是表达式。

3 个答案:

答案 0 :(得分:3)

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

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

在您的链接中,有人显然试图使用expression_statement替代expression,后跟;。这可能在语法上有效,但它并不反映这种语言结构的语义。在语义上,语言没有看到任何“陈述”。语言看到并使用表达式。

  

for循环的增量部分是一个表达式,这也非常令人困惑,因为你永远不需要增量操作的返回值。

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

printf("Hello World");

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

a = b + c;

你丢弃整个表达的结果。

答案 1 :(得分:1)

您误读了您的参考资料 - 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已经发展了。没有根本,但肯定会改变。

答案 2 :(得分:0)

有趣的是:然而,这种说法:

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.