C ;运算符用法



当我编写代码时,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语句的规则没有规定省略控制表达式。 最重要的是,这只是规则。

最新更新