Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: тернарный оператор
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
DASM
int test=2, a = 55, b = 22;
(test==1) ? a = 1 : b = 2;
printf("%d %d\n", a, cool.gif;
В голоМ С некорректна (С99) тоже, как я понимаю вопрос приоритетов (они в одной строчке)
Но в С++ проходит без единой запинки, да еще и выдает вполне ожидаемые результаты. Это что за сюрприз на старости лет ?



Похоже тут отличие присвоения от иницииализации. Хорошая тема валить на собеседовании
Сергей Борщ
Ничего не понял. Что ожидали, что получили, какие приоритеты, где тег [ code ]?
DASM
Код
int test=1, a = 55, b = 22;
(test==1) ? a = 1 : b = 2;
printf("%d %d\n", a, b);

Каков результат ?
ViKo
У оператора присваивания ( = ) приоритет ниже, чем у тернарного ( ? : ). - В скобки его!
Сергей Борщ
QUOTE (DASM @ Oct 8 2013, 11:58) *
Каков результат ?
C++ - "1 22", C - error: lvalue required as left operand of assignment, причем на b = 2. a = 1 кушает и выполняет. Не понимаю.


QUOTE (ViKo @ Oct 8 2013, 12:06) *
У оператора присваивания ( = ) приоритет ниже, чем у тернарного ( ? : ). - В скобки его!
А... точно. А в плюсах у них одинаковый приоритет, поэтому они группируются согласно правилам этого приоритета, т.е. справа налево.
DASM
Я думаю тут вопрос не в приоритете, а в том, что С++ трактует это не как присваивание, а как начальныю инициализацию, что-то в этом роде
Сергей Борщ
QUOTE (DASM @ Oct 8 2013, 12:38) *
Я думаю тут вопрос не в приоритете, а в том, что С++ трактует это не как присваивание, а как начальныю инициализацию, что-то в этом роде
Почему? В С приоритеты разные, поэтому выражение рассматривается как ((test==1) ? a = 1 : b ) = 2; что абсурдно.
В С++ приоритет одинаковый и для этого приоритета подвыражения группируются справа налево, т.е. получается (test==1) ? a = 1 : (b = 2);
DASM
не нашел ссылки про разность приоритетов
demiurg_spb
Цитата(DASM @ Oct 8 2013, 14:37) *
не нашел ссылки про разность приоритетов
Да хоть на вики гляньте в главе "Приоритет операций".
Сергей Борщ
QUOTE (DASM @ Oct 8 2013, 13:37) *
не нашел ссылки про разность приоритетов

Я просто гуглил "C operator precedence" и "C++ operator precedence"
AHTOXA
Хм. А как же обратная совместимость? sm.gif
GetSmart
Двоеточие в этом выражении имхо должен иметь приоритет на уровне оператора запятой, то есть самый высокий и выше чем присваивание. Так как разделяет две независимых друг от друга последовательности операций. Интересно, он ещё где-то в Си/Си++ применяется. А вот с оператором "?" тоже странно. При начальном разборе кода слева направо компилятор должен понимать, что далее последуют два независимых выражения, разделённых двоеточием. Соответственно внутри этой конструкции оператор "?" имеет самый высший приоритет, как и ":".


На похожую тему тоже есть интересное выражение вроде ++i++.
Если бы приоритет левого инкремента был выше правого, то вполне себе юзабельное выражение.
Genadi Zawidowski
Может, немного прояснит один из тестовых файлов для C-компилятора.
На неоднозначность результата тут тестов нет, только на приоритеты.
Код
void    func1(void), func2(void);

int    swt;
char    emain(void)
{
    swt != 0 ? func1() : func2();

    if (swt != 0)
        func1();
    else    func2();

    return 0;
}

int    n, m;

int test0(void)
{
    return ((n += 10) > 100) ? n , m : n;    /* Okay */
}
int test1(void)
{
    return ((n += 10) > 100) ? n : n, m;    /* Okay */
}
int test2(void)
{
    return ((n += 10) > 100) ? n = 0: n;    /* Okay */
}
int test3(void)
{
    return ((n += 10) > 100) ? n: n = 0;    /* Error */
}
int test4(void)
{
    return ((n += 10) > 100) ? n = 50: n = 0;    /* Error */
}
demiurg_spb
Цитата(Genadi Zawidowski @ Oct 9 2013, 01:03) *
Я бы ваши примеры слегка упростил, добавил симметрии и сделал чтобы они собирались.
Так ИМХО гораздо интереснее и вернее т.к. n является аргументом функции и не меняется предыдущими тестами.
Можно также понаблюдать результаты тестов 2 и 3, при изменении уровня оптимизации...
Код
#include <stdio.h>
#include <stdlib.h>

int test0(int n)
{
    return (n > 0) ? n , 33 : n;      // 33 Okay
}
int test1(int n)
{
    return (n > 0) ? n : n, 33;       // 33 Okay
}

int test2(int n)
{
    return (n > 0) ? (n=0) : (n=33);  // ??? and Error if missing ()
}
int test3(int n)
{
    return (n > 0) ? (n=33) : (n=0);  // ??? and Error if missing ()
}

int main(void)
{

    printf("test0 = %d\n", test0(1));
    printf("test1 = %d\n", test1(1));
    printf("test2 = %d\n", test2(1));
    printf("test3 = %d\n", test3(1));

    return 0;
}
Genadi Zawidowski
Ну сейчас тесты действительно другие были бы. Это была часть test set для компилятора под i8080 разработки 1988 года...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.