/ / Niespodziewany wynik, Ternary Operator w Gnu C - c, warunkowy, trójskładnikowy, trójskładnikowy, kolejność operacji

Nieoczekiwany wynik, Ternary Operator w Gnu C - c, warunkowy, trójskładnikowy, trójskładnikowy, porządek operacji

Tak więc operator pierwszeństwo operatora trójskładnikowego w C wydaje mi się naprawdę dziwaczny. Przykładem:

#include <stdio.h>

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

Wydaje się to podobne do pytania tutaj:
C ++ trójskładnikowe warunkowe i pierwszeństwo operatora przypisania
Trójpoziomowy porządek oceny operatora

Jako wyjaśnienie rozumiem, że nawiasy sprawiają, że działa, ponieważ moje komentarze w moim pierwotnym wpisie wskazywały ...

Zastanawiam się tylko, dlaczego autorzy języków wybiorą metodę oceny, która jest tak prawdopodobna, że ​​podstępnie zwodzi ludzi, kiedy wydaje się, że pierwsza instrukcja może być sformatowana pod względem kompilacji, aby była poprawna.

Ale te pytania dotyczą operatorów po lewej stronie lub w obrębie członków klasy, gdzie to dziwne zachowanie występuje w RHS.

Odpowiedzi:

6 dla odpowiedzi № 1

Co jest tu dziwnego? Pierwsza część jest interpretowana jako:

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

a drugi jest interpretowany jako

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

Pierwsze jest spowodowane regułami pierwszeństwa(arytmetyka binarna ma wyższy priorytet niż operator trójargumentowy), a druga omija reguły pierwszeństwa poprzez grupowanie wyrażenia za pomocą nawiasów.

Twoja edycja prosi o przyczyny i jedną z nichzwykle tylko zgadywać, chyba że ktoś z komitetu C, który był obecny w tym czasie, przyjdzie mu z pomocą. Sądzę, że znacznie częściej używa się złożonego wyrażenia i prosi się o jego prawdziwą wartość niż użycie potrójnego operatora do określenia wartości wyrażenia w arytmetyce. Coś takiego przychodzi na myśl:

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

jeśli byłoby to interpretowane jako return (froble() + 3) == 5; Byłbym naprawdę zszokowany.


0 dla odpowiedzi nr 2

Należy wybrać bardzo wysokie lub bardzo niskie pierwszeństwo, a jedno lub drugie będzie zaskakujące dla kogoś, kto robi złe założenie.

Przydatnym powodem wyboru niskiego pierwszeństwa jestoznacza to, że operator działa jak konstruktor if ... then .. else .. bez żadnych nawiasów klamrowych, co może oznaczać mniej pracy dla twórców kompilatorów (którzy mogą używać tego samego kodu do obsługi obu) i prostego refaktoryzowania przez koderów, którzy rozumieją pierwszeństwo.

W praktyce język prawdopodobnie standaryzował wszelkie pierwszeństwo, które było najpopularniejszym zastosowaniem w kodzie napisanym w erze przed standaryzacją.