在C中,被丢弃的语句的逗号和分号有什么区别

In C, what is the difference between comma and semicolon for statements that are discarded

我问是因为当我细读 grep 的源代码时,我注意到它使用了 C 语法的一个元素,逗号,这是我不习惯看到的,例如:

r = links[depth], l = r->llink, t = l->rlink;
rl = t->rlink, lr = t->llink;
t->llink = l, l->rlink = lr, t->rlink = r, r->llink = rl;

我研究了用法,发现:

When used as an operator, the comma operator uses the following syntax:

expr1, expr2

The left operand expr1 is evaluated as a void expression (i.e. it is ignored if not contain side effects), then expr2 is evaluated to give the result and type of the comma expression. So, the result is just expr2.

(来源:http://tigcc.ticalc.org/doc/opers.html#comma

因此,如果逗号运算符确实是 "the same" 作为分号(当然,假设我们不需要使用表达式的 return 值),那么写作

f(2); g(3);

在功能上等同于写作

f(2), g(3);

甚至

f(2), g(2),

为什么要用分号代替?为什么 grep 作者不遵循惯例并使用分号而不是逗号,因为 C 忽略空格所以换行符无关紧要?

很费解。

在显示的代码中,逗号可以替换为分号,并且代码的工作方式没有区别。这可能只是强调这三个操作之间的密切关系的一种方式。

但有时差异很重要。例如:

if (links[depth] != 0)
    r = links[depth], l = r->llink, t = l->rlink;

对比:

if (links[depth] != 0)
    r = links[depth]; l = r->llink; t = l->rlink;

尽管它是这样写的,但编译器会看到:

if (links[depth] != 0)
    r = links[depth];
l = r->llink;
t = l->rlink;

这根本不是一回事。它在 for 循环的循环初始化和重新初始化部分也很重要:

int i, j;
…
for (i = 0, j = max; i < j; i++, j--)

您不能用分号替换那些逗号。