为什么 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.
如标题所说。如果我没记错的话,语句不应该 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.