For some context, the conditional is used in the normal type of algorithm for finding linked list cycles:
From link: http://vijayinterviewquestions.blog开发者_如何学JAVAspot.com/2007/05/how-would-you-detect-loop-in-linked.html
p=head;
q=head->next;
while(p!=NULL && q!=NULL) {
if(p==q) { //Loop detected! exit(0); }
p=p->next;
q=(q->next)?(q->next->next):q->next;
}
// No loop.
What does the line:
q=(q->next)?(q->next->next):q->next;
get parsed as though? I'm a little confused about operator precedence in this conditional - does q take the value of the left hand side of the ? or of the whole conditional?
that can be expanded to:
if (q->next) {
q = q->next->next;
} else {
q = q->next;
}
Its called the ternary operator and it means
if(q->next)
q->next->next;
else
q->next;
You're seeing an example of the ternary operator.
q=(q->next)?(q->next->next):q->next;
can also be read as:
if(q->next)
{
q = (q->next->next)
}
else
{
q = q->next;
}
The ternary operator has precedence lower than most other operators (excepting the comma operator, "throw" and all assignment operators).
http://en.cppreference.com/w/cpp/language/operator_precedence
If you have a look at an operator precedence table you'll see that the ternary operator ?:
is near the bottom of the list. This means that the subexpressions within it will be evaluated first. The parenthesis within this grouping just reinforce the fact; they were probably added for readability.
The beginning of the expression (q->next)
is evaluated to see if it is true or not by comparing to zero; in the case of a pointer, a NULL pointer is zero or false and any other value is true.
The result of a ternary operator will be the first expression after the ?
if the part to the left of the ?
is true, otherwise it will be the expression after the :
.
It takes the value of the whole conditional expression, since the assignment operator has very low precedence (second only to throw
and ,
). The expression in your question is equivalent to:
q = q->next ? q->next->next : q->next;
In order for the assignment to take priority, you would have to write something like:
(q = q->next) ? q->next->next : q->next;
Which, of course, always assigns q->next
to q
, then proceeds to evaluate one of the remaining conditional operands into thin air.
精彩评论