对逗号在 C/C++ 中的工作方式有些困惑
Some confusion with how commas work in C/C++
我使用 SO 作为参考已经有一段时间了,但之前从未问过问题。我目前在大学学习 C++ class 并且还在阅读 Bjarne Stroutstrup 的 Programming: Principles and Practice 只是为了我自己的利益,因为我在这里看到了一个问题的答案真的很推荐。
我们目前在我的 class 中介绍运算符,但我似乎无法理解逗号运算符在语句中的工作原理。一个例子是 class 的在线部分的示例问题,即使我编写了 C 程序并使用 GDB 来获取结果,我仍然会出错。问题是:
Assuming x==16 before the following expression, what is the value of the following expression (not necessarily the value of x)?
x++, ++x, x+=x
我对正确答案不感兴趣,我对如何得到正确答案不感兴趣。我已经通读了几个类似问题的答案,例如这个 here,但似乎我不知道在实际上没有赋值运算符时如何应用它。这和说
一样吗
int y = (x++, ++x, x+=x);
或
int y = x++, ++x, x+=x;
或者两者都不是?有人可以解释一下逗号运算符是如何工作的,特别是与没有赋值的语句有关吗?
逗号运算符很简单——简单到很难。它在所有运算符中具有最低的优先级;它的优先级甚至低于赋值运算符。请注意,函数的参数不是由逗号运算符分隔的。
逗号运算符计算其左侧操作数,生成序列点并丢弃结果,然后计算右侧操作数。
在上下文中:
x++, ++x, x += x;
相当于:
x++;
++x;
x += x;
除了总值是x += x;
的结果。
鉴于 x 从 16 开始,它递增到 17,然后是 18,然后加倍到 36。因此总值为 36。
请注意,由于序列点的原因,它不会运行违反关于在序列点之间不将同一变量递增一次以上的规则。
使用逗号运算符的唯一原因实际上是在某些情况下您不能使用单独的语句但可以使用逗号运算符。例如:
for (i = 0, j = n; i < j; ++i, --j)
不能用分号代替逗号。
题中有两个样例:
int y = (x++, ++x, x+=x);
int y = x++, ++x, x+=x;
第一个是合法的(尽管不必要地扭曲了),并将 y
初始化为 36(并将 x
设置为 36)。
第二个不合法,无法编译;逗号不是逗号运算符,应该分隔不同的声明符,但 ++x
和 x += x
不是声明符。但是,如果改为:
y = x++, ++x, x+=x;
那就合法了。第一项是:
y = x++
将 16 分配给 y
并将 x
递增到 17。第二项将 x
递增到 18;第三项将 x
更改为 36.
逗号运算符计算第一个操作数,丢弃它,然后计算 到 第二个操作数,计算之间有一个序列点。
在你的例子中,这意味着你已经评估了这个表达式序列
x++ // evaluates to 16, increments x to 17
++x // increments x to 18, evaluates to 18
x+=x // increments x by x, i.e. by 18, evaluates to 36.
完整表达式的计算结果为第三个子表达式。第一个表达式的计算结果为 16,但将 x
递增至 17。第二个表达式将 x
递增至 18 并计算为该数字。第三个将 x
的值 18 递增,计算结果为 x
,即计算结果为 36。
我使用 SO 作为参考已经有一段时间了,但之前从未问过问题。我目前在大学学习 C++ class 并且还在阅读 Bjarne Stroutstrup 的 Programming: Principles and Practice 只是为了我自己的利益,因为我在这里看到了一个问题的答案真的很推荐。
我们目前在我的 class 中介绍运算符,但我似乎无法理解逗号运算符在语句中的工作原理。一个例子是 class 的在线部分的示例问题,即使我编写了 C 程序并使用 GDB 来获取结果,我仍然会出错。问题是:
Assuming x==16 before the following expression, what is the value of the following expression (not necessarily the value of x)?
x++, ++x, x+=x
我对正确答案不感兴趣,我对如何得到正确答案不感兴趣。我已经通读了几个类似问题的答案,例如这个 here,但似乎我不知道在实际上没有赋值运算符时如何应用它。这和说
一样吗int y = (x++, ++x, x+=x);
或
int y = x++, ++x, x+=x;
或者两者都不是?有人可以解释一下逗号运算符是如何工作的,特别是与没有赋值的语句有关吗?
逗号运算符很简单——简单到很难。它在所有运算符中具有最低的优先级;它的优先级甚至低于赋值运算符。请注意,函数的参数不是由逗号运算符分隔的。
逗号运算符计算其左侧操作数,生成序列点并丢弃结果,然后计算右侧操作数。
在上下文中:
x++, ++x, x += x;
相当于:
x++;
++x;
x += x;
除了总值是x += x;
的结果。
鉴于 x 从 16 开始,它递增到 17,然后是 18,然后加倍到 36。因此总值为 36。
请注意,由于序列点的原因,它不会运行违反关于在序列点之间不将同一变量递增一次以上的规则。
使用逗号运算符的唯一原因实际上是在某些情况下您不能使用单独的语句但可以使用逗号运算符。例如:
for (i = 0, j = n; i < j; ++i, --j)
不能用分号代替逗号。
题中有两个样例:
int y = (x++, ++x, x+=x);
int y = x++, ++x, x+=x;
第一个是合法的(尽管不必要地扭曲了),并将 y
初始化为 36(并将 x
设置为 36)。
第二个不合法,无法编译;逗号不是逗号运算符,应该分隔不同的声明符,但 ++x
和 x += x
不是声明符。但是,如果改为:
y = x++, ++x, x+=x;
那就合法了。第一项是:
y = x++
将 16 分配给 y
并将 x
递增到 17。第二项将 x
递增到 18;第三项将 x
更改为 36.
逗号运算符计算第一个操作数,丢弃它,然后计算 到 第二个操作数,计算之间有一个序列点。
在你的例子中,这意味着你已经评估了这个表达式序列
x++ // evaluates to 16, increments x to 17
++x // increments x to 18, evaluates to 18
x+=x // increments x by x, i.e. by 18, evaluates to 36.
完整表达式的计算结果为第三个子表达式。第一个表达式的计算结果为 16,但将 x
递增至 17。第二个表达式将 x
递增至 18 并计算为该数字。第三个将 x
的值 18 递增,计算结果为 x
,即计算结果为 36。