当我编写代码时,C 编译器(在我的情况下为 GCC)在使用时不会给出错误或警告;运算符反复喜欢
int main()
{
;
;
;
;
return 0;
}
很明显,for循环可以在不给出任何输入的情况下实现
for(;;)
{ /* Some implementations */
}
但是当涉及到 while 循环时,编译器会抛出错误。
while()
{
}
那么是否有可能解释实际 ; 运算符在 C 中做什么,以及为什么当它没有放在前面时它不会给出错误;
;
不是运算符,它是出现在语言语法中不同位置的标点符号。它可能不会出现任意,而仅在正式语法指定的某些位置:
-
作为字符串文本或字符常量内的标点符号。示例:
";"
. -
在声明或结构声明的末尾。示例:
int a;
. -
在表达式语句的末尾。示例
a=b;
.
这包括 (6.8.3)null 语句(仅由分号组成)不执行任何操作。
-
在
Static_assert
结束时.示例_Static_assert(foo==bar, "foobar");
。 -
在做边语句的末尾。示例
do(x) while(y) ;
。 -
分隔
for
语句的三个子句。示例:for(int i=0; i<n; i++)
. -
在跳转语句之后。示例
return 0;
.
for
循环有点像雪花,因为它允许以下两种形式语法(6.8.5):
for (
表达式 opt;
表达式 opt;
表达式 opt
)
语句for (
声明表达式 opt;
表达式opt)
语句
其中opt表示可选。请注意,声明表达式末尾将包含一个;
,因此无论您选择哪个版本,它最终都会包含其中的 2 个。
此外,6.8.5.3 指出,第一个和第 3 个表达式是完全可选的,可以随时省略。如果省略第二个表达式,则会将其替换为非零常量,从而创建一个永恒("永远")循环。
通常这样的循环写成for(;;) {}
。
你的例子是:
4 个空语句表达式。
永恒的
for(;;)
循环。
语法错误,因为
while
的语法是:while
(
表达式)
语句。其中表达式不是可选的。
具有三个"空"表达式(技术上讲,第一个是子句)的for
循环由两个分号分隔,因为允许省略每个/任何这些表达式。从这个C11标准草案:
6.8.5.3语句 1 语句 语句
for (
语句 1;
表达式 2;
表达式 3)
语句的行为如下...
2条款-1和表达式-3都可以省略。省略的表达式-2是 替换为非零常量。
但是,while
语句不允许省略控制表达式(在括号内)。来自同一标准草案(请注意没有"第2款"):
6.8.5.1 while 语句
1 控制表达式的计算在每次循环执行之前进行 身体
关于在第一个代码片段中重复使用"孤独"分号:每个分号都分隔一个空语句。同样,来自同一标准草案:
6.8.3 表达式和空语句
...
3空语句(仅由分号组成)不执行任何操作。
Null 语句可用于定义"空"循环体;例如,以下代码推进i
变量,直到找到数组中的特定元素,但循环本身在主体中没有任何内容:
int i;
char array[] = "abcdefghijklmnopqrstuvwxyz";
for (i = 0; array[i] != 'q'; ++i)
; // The ";" forms a null statement as the loop's body
// After the loop, "i" will be the index of the letter q
那么是否可以解释实际 ; 运算符在 C 和 为什么当它没有放在前面时它没有给出错误;?
;
不是运算符。它是一个语句终止符,另外,它是for
语句语法的一部分。
作为语句终止符,;
可以终止空语句。 C 允许此类语句,并指定它们无效。 在循环控制子句中完成重要工作的情况下,这在为循环语句提供空主体方面用途有限,但不限于该上下文。
同样,在for
语句中,允许省略控制条款中三个表达式中的任何一个或全部,但在这种情况下,;
仍然需要显示哪些是这些表达式。 如果省略控制表达式,则根据规则,它被视为非零常量表达式(即,它是无条件的真)。 这应被视为一种特例。 如果省略其他表达式,则在循环执行中的相应点根本不计算表达式。
另一方面,while
语句的规则没有规定省略控制表达式。 最重要的是,这只是规则。