Вопрос: Как этот условный анализ?


Для некоторого контекста условное значение используется в обычном типе алгоритма для нахождения циклов связанных списков:

От ссылки: http://vijayinterviewquestions.blogspot.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.

Что делает линия:

q=(q->next)?(q->next->next):q->next;

разобрать, как будто? Я немного запутался в приоритете оператора в этом условном - делает ли q значение левой стороны? или всего условного?


4


источник


Ответы:


который может быть расширен до:

if (q->next) {
  q = q->next->next;
} else {
  q = q->next;
}

5



Его называют троичный  оператора, и это означает

if(q->next)
  q->next->next;
else
  q->next;

2



Вы видите пример тернарного оператора.

q=(q->next)?(q->next->next):q->next;

также можно читать как:

if(q->next)
{
    q = (q->next->next)
}
else
{
    q = q->next;
}

Тернарный оператор имеет приоритет ниже, чем большинство других операторов (кроме оператора запятой, «throw» и всех операторов присваивания).

http://en.cppreference.com/w/cpp/language/operator_precedence


1



Если вы посмотрите на таблица приоритетов оператора  вы увидите, что тернарный оператор ?: находится в нижней части списка. Это означает, что подвыражения внутри него будут оцениваться первыми. Скобки в этой группировке только усиливают этот факт; они, вероятно, были добавлены для удобства чтения.

Начало выражения (q->next) оценивается, если оно истинно или нет, сравнивая с нулем; в случае указателя указатель NULL равен нулю или false, а любое другое значение - true.

Результатом тернарного оператора будет первое выражение после ? если часть слева от ? истинно, в противном случае это будет выражение после :,


1



Он принимает значение всего условного выражения, поскольку оператор присваивания имеет очень низкий приоритет  (второй раз throw а также ,). Выражение в вашем вопросе эквивалентно выражению:

q = q->next ? q->next->next : q->next;

Для того, чтобы присвоение получило приоритет, вам нужно написать что-то вроде:

(q = q->next) ? q->next->next : q->next;

Что, конечно, всегда присваивает q->next в q, затем переходит к оценке одного из оставшихся условных операндов в тонком воздухе.


1