LINUX.ORG.RU

C и ava: оператор "?"


0

0

Есть следующий код на С:

char *s1 = NULL;
char *s2 = "asd";
char *s3 = "new";
s1 == NULL ? (s1 = s3) : (s2 = s3);

Смысл — записываем значение s3 в нулевой указатель либо в s2.

Пишем такой же код на Java:

Integer a = null;
Integer b = 7;
Integer c = 10;
a == null ? (a = c) : (b = c);

Говорит, что not a statement. Ей обязательно нужно, чтобы слева от выражения стояла переменная. Как можно сделать то, что я написал иначе, или я что-то недопонимаю глобально?

Изначально я хотел что-то вроде:

(a == null ? a : b) = c

но так даже С не захотел :)
★★★★★

Напиши ты if'ами, нефиг мудрить. Такие конструкции плохо читаются.

anonymous
()
Ответ на: комментарий от anonymous

Да понятно что if-ами можно, но мне такое вполне нормально читается, а главное — компактно. И мне уже больше интересно, почему у Джавы такое поведение?

roy ★★★★★
() автор топика

Мутабельные переменные - зло.

Miguel ★★★★★
()
Ответ на: комментарий от anonymous

Вы наверное неправильно меня поняли. Я хочу с помощью оператора ? выбирать не что записывать, а куда записывать.

roy ★★★★★
() автор топика
Ответ на: комментарий от roy

В java вообще краткость не очень приветствуется. Такой вот язык

anonymous
()
Ответ на: комментарий от roy

> Вы наверное неправильно меня поняли.

Именно поэтому не стоит так делать.

Вот обходные пути (имхо так тоже делать не стоит):

Integer x;
x = (a == null) ? (a = c) : (b = c);

Integer[] array = new Integer[3];
array[array[0] == null ? 0 : 1] = array[2];

Кстати, в C прекрасно компилируется, чем я когда-то регулярно пользовался:

int main() {
char *s1 = 0;
char *s2 = "asd";
char *s3 = "new";
(s1 ? s1 : s2) = s3;
}


Имхо как раз конструкция `(condition ? lvalue : lvalue) = rvalue' вполне читаема, а вот идея использовать `condition ? assignment : assignment' - как правило идея сомнительная.

Минусы в ней такие:
1. лишнее ограничение на одинаковость типа в обоих присваиваниях;
2. именно для этого есть стандартная конструкция if/then/else, и именно она на человеческом языке соответствует тому, что ты делаешь;
3. когда поставишь == вместо =, человек этого не заметит (из-за необычности), да и за компилятор я тоже не уверен;
4. конструкция слишком сложна при своей экзотичности (4 аргумента в одних только присваиваниях!), плохо читаема, и потому слишком легко ошибиться при написании и допускает неправильное прочтение (как уже произошло с анонимусом). Перечитай это предложение ещё раз - оно проще, чем твоя конструкция :)

Резюме:
либо пиши (s1 ? s2 : s3) = rvalue (только C),
либо используй if/then/else.

alexsaa
()
Ответ на: комментарий от alexsaa

> Кстати, в C прекрасно компилируется (s1 ? s1 : s2) = s3;

в Си так енльзя писать. Только в С++.

dilmah ★★★★★
()

В общем понятно, спасибо за ваши комментарии. На счёт читаемости, всё же, не совсем согласен. Это непривычно, да, как и само использование оператора "?" (по крайней мере мне так вначале было), а сейчас читается нормально. Но городить костыли в Джаве не хочется, поэтому буду с ифами писать.

roy ★★★★★
() автор топика
Ответ на: комментарий от roy

>Это непривычно, да, как и само использование оператора "?" (по крайней мере мне так вначале было), а сейчас читается нормально.

Пока пишешь для себя "в стол" - нормально.

KRoN73 ★★★★★
()

Есть простое и понятное

(s1 && (s2 = s3, 1)) || (s1 = s3);

или, если вам так хочется,

* (s1 ? &s2 : &s1) = s3;

anonymous
()
Ответ на: комментарий от KRoN73

> По сабжу - ты ещё Питона не видел :D

+1. Змеюко волосатая одноглазая умеет самый полезный из операторов, тренарный, только путём какой-то замысловатой комбинации отступов без применения других символов, а поясняющая его глава в документации написана пробелами.

anonymous
()

Ещё кстати забыл не менее очевидный

* (char ** []) {&s1, &s2} [!!s1] = s3;

Полезен если назначений несколько более двух.

anonymous
()
Ответ на: комментарий от anonymous

Нет, такие "извраты" мне точно не нужны. Тем более, мне для Джавы. На Си это просто пример был. Уж лучше ифами обойтись.

roy ★★★★★
() автор топика
Ответ на: комментарий от roy

> Уж лучше ифами обойтись.

+1

оффтопик: в Фокале иф просто замечательный: он не бинарный, а тернарный -- бранчится на три ветки в зависимости от того аргумент <0, ==0 или >0

dilmah ★★★★★
()
Ответ на: комментарий от roy

Да, на жаве это будет весьма неуклюже выглядеть. Жаль, что её создатели никогда не предполагали её практического использования. Иначе наверное постарались бы сделать её менее запутанной и более очевидной.

anonymous
()
Ответ на: комментарий от dilmah

наверное там switch/case не было :(

anonymous
()
Ответ на: комментарий от anonymous

Бросайте уже принимать тяжелые наркотики.

ЗЫ Тернарный.

anonymous
()
Ответ на: комментарий от anonymous

>Ещё кстати забыл не менее очевидный

>* (char ** []) {&s1, &s2} [!!s1] = s3;

Я тебя зарежу.

anonymous
()
Ответ на: комментарий от anonymous

>Да, на жаве это будет весьма неуклюже выглядеть. Жаль, что её создатели никогда не предполагали её практического использования. Иначе наверное постарались бы сделать её менее запутанной и более очевидной.

Джавафобы набежали. Обычно такие плюются от джавы, но почему-то юзают дотнет.

Kpoxman ★★
()
Ответ на: комментарий от Kpoxman

Не передёргивай, товарищ. Независимо от наличия жабафобов/филов, жаба по ТТХ ушла весьма недалеко от gwbasic, да и этот лишек использовать почему-то стрёмаются. Наивные видимо думают, что если для описания каждого незамысловатого действия настрочить семитомник о восьми томах, желательно произведя иерархию (недо)классов поразвесистее, то читаемость кода немилосердно повысится, глякавость и тормознутость понизится, и настанет вселенское счастие.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.