我found维基百科上的这段代码。
#include <stdio.h>
int main(void)
{
int c;
while (c = getchar(), c != EOF && c != 'x')
{
switch (c)
{
case '\n':
case '\r':
printf ("Newline\n");
break;
default:
printf ("%c",c);
}
}
return 0;
}
我很好奇将表达式用作while循环的条件:
while (c = getchar(), c != EOF && c != 'x')
它的作用非常明显,但我以前从未见过这种结构。这是否特定于而循环?如果没有,解析器/编译器如何确定逗号分隔表达式的哪一侧为而循环返回布尔值?
答案 0 :(得分:17)
comma operator是一个二元运算符,它计算第一个操作数并丢弃结果,然后计算第二个操作数并返回该值。
它也是"sequence point",这意味着所有副作用都将在下一部分代码执行之前计算出来。
答案 1 :(得分:10)
逗号运算符是一个奇怪的野兽,直到你理解它,并不是while
特有的。
表达式:
exp1, exp2
评估exp1
,然后评估exp2
并返回exp2
。
你经常看到它,虽然你可能没有意识到:
for (i = j = 0; i < 100; i++, j += 2)
你实际上并没有使用来自"i++, j += 2"
的返回值,但它仍然存在。逗号运算符计算两个位以修改i
和j
。
你可以在任何可以使用普通表达式的地方使用它(例如你的函数调用中的逗号是而不是一个逗号运算符),它在编写压缩源代码时非常有用,如果这就是你喜欢的。通过这种方式,它是家庭的一部分,允许这样的事情:
while ((c= getchar()) != EOF) {...}
i = j = k = 0;
等等。
对于您的具体示例:
while (c = getchar(), c != EOF && c != 'x')
发生以下情况:
c = getchar()
(逗号运算符是序列点)。c != EOF && c != 'x'
已执行。while
使用该返回值来控制循环。答案 2 :(得分:4)
在许多语言中,逗号是一个运算符,它总是产生第二个操作数的值。操作数从左到右依次进行评估。
的伪代码:
a = 10
print a = 7 + 8, a * 2
注意:print
被认为是不带参数的语句,因此后面的内容被认为是单个表达式a = 7 + 8, a * 2
。
执行如下:
10
放入a
7 + 8
(15
)15
)放入a
a * 2
(30
),
和15
评估30
运算符:
30
)30
)答案 3 :(得分:2)
要在其他答案上进一步扩展,请使用以下代码:
EXPRESSION_1 , EXPRESSION_2
首先评估EXPRESSION_1,然后有一个序列点,然后评估EXPRESSION_2,整个事物的值是EXPRESSION_2的值。
操作保证顺序和序列点对您引用的代码都很重要。它们一起意味着我们可以确定在测试c的值之前调用getchar()函数并且完全更新变量c的值。
答案 4 :(得分:1)
逗号是一名运营商。它默认返回右手表达式的值。保证评估顺序先行,然后保持正确。
就像大多数操作符一样,它可以为用户定义的类型重载:
#include <iostream>
#include <string>
using namespace std;
enum EntryType { Home, Cell, Address };
class AddressBookEntryReference {
public:
AddressBookEntryReference(const string& name, const EntryType &entry)
: Name(name), Entry(entry) { }
string Name;
EntryType Entry;
};
AddressBookEntryReference operator,(const string& name, const EntryType &type) {
return AddressBookEntryReference(name, type);
}
class AddressBook {
string test;
public:
string& operator[](const AddressBookEntryReference item) {
// return something based on item.Name and item.Entry.
// just to test:
test = item.Name;
return test;
}
};
int main() {
// demo:
AddressBook book;
cout << book["Name", Cell] // cool syntax!
<< endl;
}