Для установки нажмите кнопочку Установить расширение. И это всё.

Исходный код расширения WIKI 2 регулярно проверяется специалистами Mozilla Foundation, Google и Apple. Вы также можете это сделать в любой момент.

4,5
Келли Слэйтон
Мои поздравления с отличным проектом... что за великолепная идея!
Александр Григорьевский
Я использую WIKI 2 каждый день
и почти забыл как выглядит оригинальная Википедия.
Статистика
На русском, статей
Улучшено за 24 ч.
Добавлено за 24 ч.
Что мы делаем. Каждая страница проходит через несколько сотен совершенствующих техник. Совершенно та же Википедия. Только лучше.
.
Лео
Ньютон
Яркие
Мягкие

Тернарная условная операция

Из Википедии — свободной энциклопедии

Терна́рная усло́вная опера́ция (от лат. ternarius — «тройной») — реализованная во многих языках программирования операция, возвращающая свой второй или третий операнд в зависимости от значения логического выражения, заданного первым операндом. Аналогом тернарной условной операции в математической логике и булевой алгебре является условная дизъюнкция, которая записывается в виде и реализует алгоритм: «если , то , иначе ».

Обычно тернарная условная операция ассоциируется с операцией ?:, используемой в си-подобных языках программирования. На самом деле, подобные операции с другим синтаксисом имеются и во многих далёких по синтаксису от Си языках программирования. Среди популярных языков, в синтаксис которых встроена тернарная условная операция — Си, C++, JavaScript, Objective-C, C#, D, Java, ECMAScript, Perl, PHP, Python,Tcl, Ruby, Verilog, Turbo Basic. Своим появлением непосредственно в тернарной инфиксной форме эта операция обязана языку Алгол-60, в котором она имела синтаксис if o1 then o2 else o3 и затем языку BCPL (o1 -> o2, o3)[1] вместо привычного теперь o1 ? o2 : o3. Прототипом же этой операции, в свою очередь, является условная функция cond языка Лисп, записываемая по правилам Лиспа в префиксной форме и имеющая произвольное количество аргументов.

Обычно в реализацию операции закладывается вычисление условия и только одного из выражений, что обеспечивает в ряде случаев расширенные возможности, например, выражение x > 0 ? 0 : sqrt(x) считается корректным, несмотря на то, что из отрицательных чисел корень не берётся.

Примеры

Символ Кронекера:

y = x == 0 ? 1 : 0.

Минимальное из чисел a и b:

min = (a < b) ? a : b

Может быть использована в ситуации, не связанной с присваиванием:

sprintf(
  Title,
  "%s %s",
  tv_system == TV_PAL ?
    "PAL" :
    "SECAM",
  tv_input ?
    Tv_Name[ tv_input - 1 ]:
    "TEST"
);

— в данном случае эквивалентная конструкция с использованием if-then-else потребовала бы записи вызова функции sprintf четыре раза.

Си-подобные языки

В базовом Си нет логического типа данныхC99 появился логический тип _Bool), поэтому первый операнд должен быть числом (целым или вещественным) или указателем[2]; сначала вычисляется именно его значение и сравнивается с нулём, и, если оно не равно нулю, вычисляется и возвращается второй операнд, в случае равенства — третий. Второй и третий операнды могут быть различных типов (включая void).

В C++ тернарная условная операция имеет тот же синтаксис, что и в Си[3], однако за счёт наличия разницы между инициализацией и присваиванием, бывают ситуации, когда операцию ?: нельзя заменить конструкцией if-then-else, как, например, в следующем случае:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main(int argc, char** argv)
{
    string name;
    ofstream fout;
    if (argc > 1 && argv[1])
    {
        name = argv[1];
        fout.open(name.c_str(), ios::out | ios::app);
    }
    ostream& sout = name.empty() ? cout : fout;
    return 0;
}

Здесь переменная sout инициализируется в момент объявления результатом работы тернарной операции. Подобного эффекта не удалось бы достичь простым присваиванием в том или ином случае.

Кроме того, тернарная условная операция может быть применена в левой части оператора присвоения:

#include <iostream>
int main () 
{
    int a=0, b=0;

    const bool cond = ...;
    (cond ? a : b) = 1;
    std::cout << "a=" << a << ','
              << "b=" << b << '\n';
}

В этом примере, если логическая переменная cond в строке 5 будет содержать значение true, то значение 1 будет присвоено переменной a, иначе, оно будет присвоено переменной b.

В C# на тернарную операцию накладываются дополнительные ограничения, связанные с типобезопасностью. Выражения 1 и 2 должны быть одного типа. Это приводит к следующему:

int a = 1;
double b = 0.0;
int nMax = (a>b) ? a : b;

Такой исходный код не будет компилироваться несмотря на то, что в конечном итоге значение nMax будет равно а. Поскольку a и b должны быть одного и того же типа, a повысится до double, чтобы соответствовать b. Тип результирующего значения тернарной операции оказывается double, и этот тип должен быть понижен до int при присваивании:[4]

int a = 1;
double b = 0.0;
int nMax;
// Можно поступить так:
nMax = (int) ((a>b) ? a : b) ;
// ...или так
nMax = (a>b) ? a : (int)b;

Python

В Python используется синтаксис с применением ключевых слов if-else:

a = 42
b = 41
result = a if a > b else b
assert result == 42

Также можно реализовать через список:

[<выражение 1>, <выражение 2>][<условие>]

— будет возвращён результат выражения 1, если условие ложно; и выражения 2, если условие истинно. Если условие будет не булевым выражением, возможен выход за границы списка с исключением.

PHP

В PHP используется си-подобный синтаксис:

 $a = $b==1 ? "first value" :
      ($b==2 ? "second value" :
      ($b==3 ? "result value" : "default value"));

Тернарный оператор в PHP эквивалентен более длинной конструкции if — else. Следующие два примера эквивалентны:

//Первый пример
$result = isset($a) ? $a : 'DefaultValue';
//Второй пример
if (isset($a)) {
    $result = $a;
} else {
    $result = 'DefaultValue';
}

Такие конструкции часто применяются чтобы в любом случае проинициализировать переменную для последующих вычислений (иначе PHP выдаст ошибку уровня E_NOTICE).

Начиная с версии 5.3 появилась возможность не указывать второй параметр операции. Например, две следующих записи эквивалентны:

 $Variable = $_GET['Parameter'] ? $_GET['Parameter'] : 'DefaultValue';
 $Variable = $_GET['Parameter'] ?: 'DefaultValue';

Visual Basic

В классической версии Visual Basic существует тернарный оператор в виде функции IIf(Expr, TruePart, FalsePart). Данная функция имеет особенность: при оценке выражения Expr, также будут вычисляться TruePart и FalsePart, вне зависимости от результата выражения: истинно оно или ложно. Это может привести к неожиданным результатам, а иногда и к замедлению выполнения кода, если в качестве возвращаемых значений будет вызов функций с длительными операциями.

Dim iCount As Long

Public Sub Main()
    iCount = 1
    MsgBox IIf(1 = 1, FuncYes, FuncNo)
    
    'Переменная iCount будет содержать "3", т.к. обе функции будут выполнены
    MsgBox iCount
End Sub

Public Function FuncYes() As String
    iCount = iCount + 1
    FuncYes = "Да"
End Function

Public Function FuncNo() As String
    iCount = iCount + 1
    FuncNo = "Нет"
End Function

Для замены функции IIf можно переписать выражение в одну строку, но это не будет являться аналогом функции, а будет всего лишь краткая форма записи оператора ветвления

If Expr Then TruePart Else FalsePart

С появлением VB.NET, в синтаксис языка был включен привычный тернарный оператор и записывается как If(Expr, TruePart, FalsePart). Данный оператор использует сокращенные вычисления, в отличие от функции IIf, которая также для совместимости с прошлыми версиями доступна разработчику.[5]

Встроенный язык 1С

В языке конфигурирования платформы 1С:Предприятие тернарный оператор имеет синтаксис:

?(логическое выражение, выражение 1, выражение 2)

Широко применяется в качестве сокращенной записи конструкций Если <логическое выражение> Тогда ... Иначе ... КонецЕсли
В версии платформы 7.7 была возможность использования тернарного оператора в правой части оператора присваивания[6].

Haskell

В Haskell операция ветвления if является условным выражением: else-выражение является обязательным и должно совпадать по типу с then-выражением. Также в стандартной библиотеке Data.Bool[7] есть функция bool, возвращающая одно из двух выражений в зависимости от значения предиката.

Тернарная операция в привычной форме может быть определена как инфиксная функция через сопоставление с образцом (указание типов не обязательно):

(?) :: Bool -> a -> a -> a
(?) True  a _ = a
(?) False _ b = b

или через любую операцию ветвления, например if или case of:

(?) predicate thenExpr elseExpr = if predicate then thenExpr else elseExpr

(?) predicate thenExpr elseExpr = case predicate of {True -> thenExpr; _ -> elseExpr}

Поскольку (?) — инфиксная (бинарная) функция, то она принимает первые 2 аргумента и возвращает функцию одного аргумента. Для её применения к третьему аргументу используется аппликация ($):

True  ? "then" $ "else"
> "then"

False ? "then" $ "else"
> "else"

Примечания

  1. BCPL Ternary operator (page 15). BCPL Reference Manual. Дата обращения: 8 мая 2009. Архивировано из оригинала 31 марта 2012 года.
  2. Ю. Ю. Громов, С. И. Татаренко. 1.3.12. Условная операция // Программирование на языке си / Рецензент: профессор А. П. Афанасьев. Архивировано 14 апреля 2009 года.
  3. Б. Страуструп. 7.13. Условная операция // Справочное руководство по C++. Архивировано 12 мая 2009 года.
  4. Оператор ?: (C#) // https://msdn.microsoft.com/ru-ru/library/ty67wk28.aspx Архивная копия от 2 апреля 2015 на Wayback Machine
  5. Оператор If (Visual Basic) // https://msdn.microsoft.com/ru-ru/library/bb513985.aspx Архивная копия от 2 апреля 2015 на Wayback Machine
  6. Оператор ? 1С 7.7 | Оператор. Дата обращения: 25 февраля 2018. Архивировано 25 февраля 2018 года.
  7. Data.Bool. hackage.haskell.org. Дата обращения: 29 апреля 2018. Архивировано 29 апреля 2018 года.

Литература

  • Стефан Рэнди Дэвис, Чак Сфер. Глава 4. Операторы // C# 2005 для "чайников" = C# 2005 for dummies / под редакцией Т. Г. Сковородниковой. — М.-Спб.: Wiley, Диалектика, 2006. — С. 83. — ISBN 5-8459-1068-4.
Эта страница в последний раз была отредактирована 11 декабря 2023 в 17:27.
Как только страница обновилась в Википедии она обновляется в Вики 2.
Обычно почти сразу, изредка в течении часа.
Основа этой страницы находится в Википедии. Текст доступен по лицензии CC BY-SA 3.0 Unported License. Нетекстовые медиаданные доступны под собственными лицензиями. Wikipedia® — зарегистрированный товарный знак организации Wikimedia Foundation, Inc. WIKI 2 является независимой компанией и не аффилирована с Фондом Викимедиа (Wikimedia Foundation).