1

Таким образом, приоритет оператора тройного оператора в C кажется мне действительно странным. Показательный пример:Неожиданный результат, тернарный оператор в Gnu C

#include <stdio.h> 

int main() 
{ 
    int i=5; 
    int j=6; 
    int k=7; 
    printf("A: %d\n", i+j+(k!=7)?1:11); //prints 1 
    printf("B: %d\n", i+j+((k!=7)?1:11)); //prints 22 
    return 0; 
} 

Это, кажется, похоже на вопрос здесь:
C++ ternary conditional and assignment operator precedence
Ternary operator evaluation order

В разъяснении, я понимаю, что круглые скобки, чтобы он работал, как и мои комментарии в моем оригинальном посте указана ...

Мне просто интересно, почему авторы языка выбрали метод оценки, который так сильно обманет людей, когда первое утверждение похоже на то, что оно может быть отформатировано компилятор должен быть действительным.

Но этот вопрос касается операторов с левой стороны или внутри членов класса, где это странное поведение происходит на RHS.

+7

Мораль этой истории: используйте круглые скобки. –

+0

Да, это было трудно, просто интересно, почему. :) Мне, если компилятор видит '?', Почему он не может взять все, что было до него, в '()' для более сложного оператора или в простейшем случае один оператор без круглых скобок ... Это казалось бы больше смысла ... –

+2

Джейсон, все знают, что компьютеры созданы безумными учеными в лабораториях, поэтому, конечно, они не имеют смысла! –

ответ

6

Что уж быть странное здесь? Первая часть интерпретируется как:

(11 + (k != 7)) ? 1 : 11 

и второй интерпретируются как

11 + ((k !=7) ? 1 :11) 

первым вызываются по правилам приоритета (двоичная арифметика имеет более высокий приоритет, чем тройной оператор), а вторые обходят правила приоритета посредством группировки выражения с помощью скобок.

Ваше изменение запрашивает причины, и обычно можно только догадываться об этом, если кто-то из Комитета С, который присутствовал в то время, не помогает. Я предполагаю, что гораздо чаще использовать сложное выражение и запрашивать его значение истинности, чем использовать тернарный оператор для определения значения выражения в арифметике. Нечто подобное приходит на ум:

return (froble() + 3) == 0 ? 23 : 5; // parens for sanity but works without 

, если это будет истолковано как return (froble() + 3) == 5; я был бы по-настоящему шокирован.

+0

Я получаю это, но мне кажется, что правило приоритета будет сжигать много людей в первый раз, когда они попробуют тройной ... Для меня '(...)?' Для сложных ops, а затем '... ? 'для проверок с одним из операторов будет иметь больше смысла и быть более добрым для тех, кто изучает язык в первый раз. –

+0

Ну, @pmr прав, хотя, по крайней мере, в соответствии с установленным соглашением. Опытный программист C уже давно подготовил свой взгляд на то, чтобы придать низкий приоритет «тройному», и принят стиль программирования, чтобы опустить круглые скобки вокруг условия. – thb

+1

@ JasonR.Mick Я попытался представить пример, где ваша интерпретация приведет к ужасным последствиям и интерпретации стандарта для более чистого кода. – pmr

0

Нужно выбрать очень высокий или очень низкий приоритет, и тот или иной будет удивлять кого-то, кто делает неправильное предположение.

Полезная причина выбора низкого приоритета заключается в том, что это означает, что оператор функционирует как if if .. then .. else .. construct без каких-либо фигурных скобок, что может означать меньше работы для авторов компилятора (кто может использовать один и тот же код для обработки обоих), и простой рефакторинг с помощью кодеров, которые понимают приоритет.

На практике язык, по-видимому, стандартизован независимо от предыдущего приоритета, был самым популярным в коде, написанном в эпоху до стандартизации.

Смежные вопросы