реклама на сайте
подробности

 
 
> тернарный оператор
DASM
сообщение Oct 8 2013, 08:19
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



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



Похоже тут отличие присвоения от иницииализации. Хорошая тема валить на собеседовании
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 14)
Сергей Борщ
сообщение Oct 8 2013, 08:27
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Ничего не понял. Что ожидали, что получили, какие приоритеты, где тег [ code ]?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
DASM
сообщение Oct 8 2013, 08:58
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Код
int test=1, a = 55, b = 22;
(test==1) ? a = 1 : b = 2;
printf("%d %d\n", a, b);

Каков результат ?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 8 2013, 09:06
Сообщение #4


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



У оператора присваивания ( = ) приоритет ниже, чем у тернарного ( ? : ). - В скобки его!
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 8 2013, 09:17
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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) *
У оператора присваивания ( = ) приоритет ниже, чем у тернарного ( ? : ). - В скобки его!
А... точно. А в плюсах у них одинаковый приоритет, поэтому они группируются согласно правилам этого приоритета, т.е. справа налево.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
DASM
сообщение Oct 8 2013, 09:38
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Я думаю тут вопрос не в приоритете, а в том, что С++ трактует это не как присваивание, а как начальныю инициализацию, что-то в этом роде
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 8 2013, 10:03
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (DASM @ Oct 8 2013, 12:38) *
Я думаю тут вопрос не в приоритете, а в том, что С++ трактует это не как присваивание, а как начальныю инициализацию, что-то в этом роде
Почему? В С приоритеты разные, поэтому выражение рассматривается как ((test==1) ? a = 1 : b ) = 2; что абсурдно.
В С++ приоритет одинаковый и для этого приоритета подвыражения группируются справа налево, т.е. получается (test==1) ? a = 1 : (b = 2);


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
DASM
сообщение Oct 8 2013, 10:37
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



не нашел ссылки про разность приоритетов
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Oct 8 2013, 10:48
Сообщение #9


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(DASM @ Oct 8 2013, 14:37) *
не нашел ссылки про разность приоритетов
Да хоть на вики гляньте в главе "Приоритет операций".


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 8 2013, 10:52
Сообщение #10


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (DASM @ Oct 8 2013, 13:37) *
не нашел ссылки про разность приоритетов

Я просто гуглил "C operator precedence" и "C++ operator precedence"


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 8 2013, 10:58
Сообщение #11


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Хм. А как же обратная совместимость? sm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 8 2013, 20:23
Сообщение #12


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



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


На похожую тему тоже есть интересное выражение вроде ++i++.
Если бы приоритет левого инкремента был выше правого, то вполне себе юзабельное выражение.

Сообщение отредактировал GetSmart - Oct 9 2013, 01:25


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Oct 8 2013, 21:03
Сообщение #13


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Может, немного прояснит один из тестовых файлов для 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 */
}


Сообщение отредактировал Genadi Zawidowski - Oct 8 2013, 21:05
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Oct 9 2013, 06:34
Сообщение #14


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(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;
}


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Oct 9 2013, 20:00
Сообщение #15


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Ну сейчас тесты действительно другие были бы. Это была часть test set для компилятора под i8080 разработки 1988 года...

Сообщение отредактировал Genadi Zawidowski - Oct 9 2013, 20:03
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 16:01
Рейтинг@Mail.ru


Страница сгенерированна за 0.01511 секунд с 7
ELECTRONIX ©2004-2016