Тернарная условная операция — это… Что такое Тернарная условная операция?
Терна́рная усло́вная опера́ция (от лат. ternarius — «тройной») (обычно записывается как ?:
) — во многих языках программирования операция, возвращающая свой второй или третий операнд в зависимости от значения логического выражения, заданного первым операндом. Как можно судить из названия, тернарная операция принимает всего три указанных операнда. Аналогом тернарной условной операции в математической логике и булевой алгебре является условная дизъюнкция, которая записывается в виде [p, q, r] и реализует алгоритм: «Если q, то p, иначе r», что можно переписать как «p или r, в зависимости от q или не q».
Обычно тернарная условная операция ассоциируется с операцией ?:
, используемой в си-подобных языках программирования. На самом деле, подобные операции с другим синтаксисом имеются и во многих далёких по синтаксису от Си языках программирования. К наиболее популярным языкам, содержащим тернарную условную операцию, можно отнести C, C++, JavaScript, Objective-C, C#, D, Java, ECMAScript, Perl, PHP, Python,Tcl, Ruby, Verilog и другие. Своим появлением непосредственно в тернарной инфиксной форме эта операция обязана языку Алгол-60, в котором она имела синтаксис
и затем языку BCPL (o1 -> o2, o3
)[1] вместо привычного теперь o1 ? o2 : o3
. Прототипом же этой операции, в свою очередь, является условная функция cond
языка Лисп, записываемая по правилам Лиспа в префиксной форме и имеющая произвольное количество аргументов.
Определение
Безотносительно определённого языка программирования, тернарную операцию можно определить так:
логическое выражение ? выражение 1 : выражение 2
Алгоритм работы операции следующий:
- Вычисляется
логическое выражение
. - Если
логическое выражение
истинно, то вычисляется значение выражениявыражение 1
, в противном случае — значение выражениявыражение 2
. - Вычисленное значение возвращается.
Нужно обратить внимание, что вычисляется только одно из выражений: выражение 1
или выражение 2
. Это сделано для оптимизации и, в некотором смысле, соответствует принципу ленивых вычислений.
Использование и реализации
Тернарная условная операция используется в выражениях для получения одного из двух вариантов в зависимости от условия.
alarm_time = today in [SUNDAY, MONDAY] ? 12.00 : 8.00
В этом примере условному программируемому электронному будильнику проставляется время, в которое он должен звонить, в зависимости от текущего дня недели. Нужно заметить, что пример снова приведён для некоторого абстрактного алгоритмического языка программирования.
В следующем примере вычисляется значение простейшего дельта-символа.
y = x == 0 ? 1 : 0
В действительности, немедленное присваивание результата тернарной условной операции редко оправдано с точки зрения стиля программирования, так как подобные операторы компактно переписываются в виде эквивалентной конструкции if-then-else. Более оправдано использование данной операции в более сложных конструкциях, не связанных с присваиванием, например в фактических параметрах вызова функции:
sprintf(Title, "%s %s", tv_system == TV_PAL ? "PAL" : "SECAM", tv_input == 0 ? "TEST" : Tv_Name[tv_input-1]);
В данном случае эквивалентная конструкция с использованием if-then-else потребовала бы записи вызова функции sprintf четыре раза. Либо, в качестве альтернативы, потребовалось бы написать аналогичный по назначению (но формально не эквивалентный) код с использованием двух дополнительных временных переменных, либо нескольких последовательных вызовов sprintf.
Си
В Си тернарная операция имеет следующий синтаксис: [2]
Как известно, в Си нет логического типа данных (в C99 появился логический тип _Bool). Поэтому операнд o1
должен быть числом (целым или вещественным) или указателем. Сначала вычисляется именно его значение. Оно сравнивается с нулём и, если оно не равно нулю, вычисляется и возвращается o2
, в случае равенства — o3
. Операнды o2
и o3
могут быть различных, вообще говоря, несовпадающих типов, включая void.
В следующем примере вычисляется минимальное из чисел a и b:
C++
В 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
инициализируется в момент объявления результатом работы тернарной операции. Подобного эффекта не удалось бы достичь простым присваиванием в том или ином случае.
Кроме того, тернарная условная операция может быть применена в левой части оператора присвоения:
0. #include <iostream> 1. int main () 2. { 3. int a=0, b=0; 4. 5. const bool cond = ...; 6. (cond ? a : b) = 1; 7. std::cout << "a=" << a << ',' 8. << "b=" << b << '\n'; 9. }
В этом примере, если логическая переменная cond в строке 5 будет содержать значение true, то значение 1 будет присвоено переменной a, иначе, оно будет присвоено переменной b.
Python
b = 3 a = 1 if b==1 else \ 2 if b==2 else \ 3 assert a==3
PHP
$a = 1==0 ? "first value" : (2==0 ? "second value" : (3==3 ? "result value" : "default value"));
Начиная с версии 5.3 появилась возможность не указывать второй параметр операции. Например, две следующих записи эквивалентны:
$Variable = $_GET['Parameter'] ? $_GET['Parameter'] : 'DefaultValue'; $Variable = $_GET['Parameter'] ?: 'DefaultValue';
C#
На тернарную операцию накладываются дополнительные ограничения, связанные с типобезопасностью. Выражения 1 и 2 должны быть одного типа. Это приводит к следующему:
int a = 1; double b = 0.0; int nMax = (a>b) ? a : b;
Такой исходный код не будет компилироваться несмотря на то, что в конечном итоге значение nMax будет равно а. Поскольку a и b должны быть одного и того же типа, a
int a = 1; double b = 0.0; int nMax; // Можно поступить так: nMax = (int) ((a>b) ? a : b) ; // ...или так nMax = (a>b) ? a : (int)b;
Примечания
Литература
Стефан Рэнди Дэвис, Чак Сфер Глава 4. Операторы // C# 2005 для «чайников» = C# 2005 for dummies / под редакцией Т. Г. Сковородниковой. — М.-Спб.: Wiley, Диалектика, 2006. — С. 83. — ISBN 5-8459-1068-4
dic.academic.ru
ОПЕРАЦИЯ УСЛОВИЯ: ?:. Язык Си
ОПЕРАЦИЯ УСЛОВИЯ: ?:
В языке Си имеется короткий способ записи одного из видов оператора if-else. Он называется «условным выражением» и использует операцию условия — ?:. Эта операция состоит из двух частей и содержит три операнда. Ниже приводится пример оператора с помощью которого находится абсолютное значение числа:
x = (y < 0 )? -y : y;
Все, что находится между знаком = и символом «точка с занятой» представляет собой условное выражение. Смысл этого оператора заключается в следующем: если у меньше 0, то х = — у; в противном случае х = у. В терминах оператора if-else данный оператор мог выглядеть так:
if(у < 0) x = (y < 0 )? -y : y;
х = -у;
else
х = у;
В общем виде условное выражение можно записать следующим образом:
выражение1 ? выражение2 : выражение3
Если выражение1 истинно (больше нуля), то значением всего условного выражения является величина
если выражение1 ложно (равно 0), то значение всего условного выражения — величина выражения3.
Условное выражение удобно использовать в тех случаях, когда имеется некоторая переменная, которой можно присвоить одно из двух возможных значений. Типичным примером является присваивание переменной значения большей из двух величин:
mах = (а > b)? а : b;
Вообще говоря, использование условных выражений не являетcя обязательным, поскольку тех же результатов можно достичь при помощи операторов if-else. Однако условные выражения более компактны, и их применение обычно приводит к получению более компактного машинного кода.
Поделитесь на страничке Следующая глава >it.wikireading.ru
24. Условная трехместная операция.
Оператор ? часто можно использовать вместо оператора вида if-then-else.
Выражение1 ? Выражение2 : Выражение3;
Сначала вычисляется Выражение1, если оно истинно, то вычисляется Выражение2 и его значение присваивается всему выражение; если Выражение1 ложно, то вычисляется Выражение3 и всему выражению присваивается его значение.
x=10;
y=x>9 ? 100:200; переменной у будет присвоено значение 100.
25. Преобразование типов.
Если в выражении встречаются переменные и константы разных типов, они преобразуются к одному типу. Компилятор преобразует «меньший» тип в «больший». Этот процесс называется продвижением типов (type promotion). Все переменные типов char и short int автоматически продвигаются в int. Это называется целочисленным расширением. Кроме того, действует следующее правило: если один из операндов имеет тип long, а второй – unsigned int, притом значениеunsignedintне может быть представлено типомlong, то оба операнда преобразуются вunsignedlong. После выполнения преобразований оба операнда относятся к одному и тому же типу, к этому типу относится и результат операции.
Программист может «принудительно» преобразовать значение выражения к нужному ему типу, используя операцию приведения типов. Общая форма оператора явного приведения типа:
(тип) выражение
Здесь тип – это любой поддерживаемый тип данных. Например, следующая запись преобразует значение выражения x/2 к типу float:
(float)x/2
Явное преобразование типа – это операция. Оператор приведения типа является унарным и имеет тот же приоритет, что и остальные унарные операторы.
26. Приоритет операций и порядок вычисления выражений.
Приоритет | Оператор | Описание |
1 | ++ | Префиксный инкремент |
— | Префиксный декремент | |
() | Вызов функции или подвыражение | |
[] | Выделение элемента массива | |
-> | Указатель структуры | |
. | Член структуры | |
2 | ! | Логическое отрицание |
~ | Поразрядное логическое НЕ (двоичная инверсия) | |
— | Унарный минус (изменение знака) | |
+ | Унарный плюс | |
(type) | Преобразование к типу | |
* | Разыменование указателя | |
& | Определение адреса переменной | |
sizeof | Определение размера в байтах | |
3 | * | Умножение |
/ | Деление | |
% | Остаток от деления | |
4 | + | Сложение |
— | Вычитание | |
5 | >> | Поразрядный сдвиг вправо |
<< | Поразрядный сдвиг влево | |
6 | < | Меньше |
> | Больше | |
<= | Меньше или равно | |
>= | Больше или равно | |
7 | == | Равно |
!= | Не равно | |
8 | & | Поразрядное логическое И |
9 | ^ | Поразрядное исключающее ИЛИ |
10 | | | Поразрядное логическое ИЛИ |
11 | && | Логическое И |
12 | || | Логическое ИЛИ |
13 | ?: | Оператор условия |
14 | = | Присваивание |
+= | Составное сложение | |
-= | Составное вычитание | |
*= | Составное умножение | |
/= | Составное деление | |
%= | Составное определение остатка от деления | |
>>= | Составной поразрядный сдвиг вправо | |
<<= | Составной поразрядный сдвиг влево | |
&= | Составное поразрядное логическое И | |
^= | Составное поразрядное исключающее ИЛИ | |
|= | Составное поразрядное логическое ИЛИ | |
15 | , | Операция «запятая» |
++ | Постфиксный инкремент | |
— | Постфиксный декремент |
Все операторы, кроме унарных и ? связывают свои операнды слева направо. Унарные операторы (*, &, -) и ? связывают свои операнды справа налево.
Вычисление выражений выполняется по определенным правилам преобразования, группировки, ассоциативности и приоритета, которые зависят от используемых в выражениях операций, наличию круглых скобок и типов данных операндов. Последовательность вычисления операций в выражении зависит от приоритета операций, наличия круглых скобок. Выражения с более приоритетными операциями вычисляются первыми. Круглые скобки можно использовать для того, чтобы принудительно задать порядок вычисления в выражениях.
studfiles.net
46.Побитовые логические операции языка Си. Операции сдвига
Поразрядное логическое «И» — «&»
Поразрядное исключающее «ИЛИ» — «^»
Поразрядное логическое «ИЛИ» — «|» (слева направо).
Сдвиг влево: <<
Сдвиг вправо: >>
Поразрядные операции состоят из четырех основных операций: отрицание, логическое И, логическое ИЛИ и исключающее ИЛИ.
При выполнении операции поразрядного отрицания все биты, равные 1, устанавливаются равными 0, а все биты равные нулю, устанавливаются равными 1. Сдвиг, при котором уходящий бит уходит, не влияя на оставшееся биты, а на место появившегося бита записывается бит 0.
47. Условный оператор и оператор выбора языка Си.
Инструкция «if» используется для выбора одного из двух направлений дальнейшего продолжения программы. Выбор той или иной последовательности инструкций осуществляется в зависимости от значения условия, заключенного в круглые скобки и записанного после оператора if. Поэтому команда «if» часто называется командой условного перехода или командой ветвления. Алгоритмы задач, использующих команды ветвления, называют разветвляющимися. Алгоритм называется разветвляющимся, если он состоит из нескольких блоков, ветвей млм частей, каждая из которых выполняется в зависимости от выполнения некоторых условий. 1. Простейшая (укороченная) форма оператора условного перехода if.
If (условие ) оператор Условие — это логическое выражение. Оно принимает значение либо «истинно», либо «ложно». В языке С принято, что значение «истинно» — это ненулевое значение величины, которая записана и проверяется в условии. Значение «ложно» — это ноль.
Наряду с простейшей или неполной формой оператора if существует еще полная форма оператора if.
if (условие) оператор1 else оператор2; Инструкция, записанная сразу вслед за оператором if, как было уже сказано ранее, выполняется только при выполнении логического условия. Это значит, что значение логического выражения будет не равно нулю. Инструкция, записанная после else, выполняется только в том случае, если логическое условие не выполняется. Это значит, что будет равно нулю. Вне зависимости от исхода того или иного направления выбора всегда выполняется только один оператор. Если же при соблюдении или несоблюдении условия надо выполнять несколько инструкций, то эти инструкции необходимо объединять фигурными скобками в отдельную группу операторов.
Оператор switch предназначен для организации выбора из множества различных вариантов. Формат оператора следующий:
switch ( выражение ){ [объявление]
:
[ case константное-выражение1]: [ список-операторов1]
[ case константное-выражение2]: [ список-операторов2]
:
:
[ default: [ список операторов ]]
}
Выражение, следующее за ключевым словом switch в круглых скобках, может быть любым выражением, допустимым в языке СИ, значение которого должно быть целым. Тело оператора switch состоит из нескольких операторов, помеченных ключевым словом case с последующим константным выражением. Так как константное выражение вычисляется во время трансляции, оно не может содержать переменные или вызовы функций. Обычно в качестве константного выражения используются целые или символьные константы.
Все константные выражения в операторе switch должны быть уникальны. Кроме операторов, помеченных ключевым словом case, может быть, но обязательно один фрагмент помеченный ключевым словом default. Список операторов может быть пустым, либо содержать один или более операторов. Причем в операторе switch не требуется заключать последовательность операторов в фигурные скобки. В операторе switch можно использовать свои локальные переменные, объявления которых находятся перед первым ключевым словом case, однако в объявлениях не должна использоваться инициализация.
Схема выполнения оператора switch следующая:
— вычисляется выражение в круглых скобках;
— вычисленные значения последовательно сравниваются с константными выражениями, следующими за ключевыми словами case;
— если одно из константных выражений совпадает со значением выражения, то управление передается на оператор, помеченный соответствующим ключевым словом case;
— если ни одно из константных выражений не равно выражению, то управление передается на оператор, помеченный ключевым словом default, а в случае его отсутствия управление передается на следующий после switch оператор.
Конструкция со словом default может быть не последней в теле оператора switch. Все операторы, между начальным оператором и концом тела, выполняются вне зависимости от ключевых слов, если только какой-то из операторов не передаст управления из тела оператора switch. Для того, чтобы выполнить одни и те же действия для различных значений выражения, можно пометить один и тот же оператор несколькими ключевыми словами case.
Пример:
int i=2;
switch (i)
{
case 1: i += 2;
case 2: i *= 3;
case 0: i /= 2;
case 4: i -= 5;
default: ;
}
Выполнение оператора switch начинается с оператора, помеченного case 2. Таким образом, переменная i получает значение, равное 6, далее выполняется оператор, помеченный ключевым словом case 0, а затем case 4, переменная i примет значение 3, а затем значение -2. Оператор, помеченный ключевым словом default, не изменяет значения переменной.
Рассмотрим ранее приведенный пример, в котором иллюстрировалось использование вложенных операторов if, переписанной теперь с использованием оператора switch.
Использование оператора break позволяет в необходимый момент прервать последовательность выполняемых операторов в теле оператора switch, путем передачи управления оператору, следующему за switch.
Отметим, что в теле оператора switch можно использовать вложенные операторы switch, при этом в ключевых словах case можно использовать одинаковые константные выражения.
studfiles.net
Операции и выражения языка Си.
Арифметические операции. Аддитивные и мультипликативные операции.
Думаю, понятно, для чего нужны арифметические операции, арифметика в программировании намного проще чем в математике. Нас интересуют следующие арифметические операции в C++:
+ — сложение; — — вычитание; * — умножение; / — деление; % — остаток от деления.
Мультипликативные операции *Операция умножения.
Операндами могут быть выражения арифметического типа. Значением выражения является произведение значений. Тип результата выражения любой бинарной операции определяется в зависимости от принятых в C++ процедур преобразования типов данных.
/Операция деления.
Операндами могут быть выражения арифметического типа. Значением выражения является частное от деления значения первого операнда на второй операнд. Тип результата выражения любой бинарной операции определяется в зависимости от принятых в C++ процедур преобразования типов данных.
%Операция получения остатка от деления
Операндами могут быть выражения арифметического типа. В процессе выполнения операции операнды приводятся к целому типу. При неотрицательных операндах остаток положительный. В противном случае знак остатка определяется в зависимости от реализации. Известно, что для Borland C++
15%6=3, (-15)%6=-3, 15%(-6)=3, (-15)%(-6)=-3.
При ненулевом делителе для целочисленных операндов выполняется соотношение
(a/b)*b+a%b=a
Аддитивные операции +Операция сложения.
Операция используется с операндами арифметического типа. Один из операндов может иметь тип указателя. В любом случае значением выражения является либо сумма значений, либо сумма адреса и целочисленного значения, кратного размерам данного типа.
Результат сложения указателя с целым числом эквивалентен результату соответствующего количества операций инкремента, пррименённых к укаазателю.
Тип и значение результата выражения любой бинарной операции определяется в зависимости от принятых в C++ соглашений о преобразовании типов, о которых будет сказано ниже. -Операция вычитания. Симметричная по отношению к операции сложения бинарная операция.
27 Условный оператор if.Оператор if служит для того, чтобы выполнить какую-либо операцию в том случае, когда условие является верным. Условная конструкция в С++ всегда записывается в круглых скобках после оператора if. Внутри фигурных скобок указывается тело условия. Если условие выполнится, то начнется выполнение всех команд, которые находятся между фигурными скобками. Пример:
if (num < 10) { // Если введенное число меньше 10.
cout << «Это число меньше 10.» << endl;
} else { // иначе
cout << «Это число больше либо равно 10.» << endl; // }
Здесь говорится: «Если переменная num меньше 10 — вывести соответствующее сообщение. Иначе, вывести другое сообщение».
28 Тернарная условная операция ?:.— во многих языках программирования операция, возвращающая свой второй или третий операнд в зависимости от значения логического выражения, заданного первым операндом. Как можно судить из названия, тернарная операция принимает всего три указанных операнда. Аналогом тернарной условной операции в математической логике и булевой алгебре является условная дизъюнкция, которая записывается в виде [p, q, r] и реализует алгоритм: «Если q, то p, иначе r», что можно переписать как «p или r, в зависимости от q или не q». Обычно тернарная условная операция ассоциируется с операцией ?:, используемой в си-подобных языках программирования. На самом деле, подобные операции с другим синтаксисом имеются и во многих далёких по синтаксису от Си языках программирования. К наиболее популярным языкам, содержащим тернарную условную операцию, можно отнести C, C++, JavaScript, Objective-C, C#, D, Java, ECMAScript, Perl, PHP, Python,Tcl, Ruby, Verilog и другие. Своим появлением непосредственно в тернарной инфиксной форме эта операция обязана языку Алгол-60, в котором она имела синтаксис if o1 then o2 else o3 и затем языку BCPL (o1 -> o2, o3)[1] вместо привычного теперь o1 ? o2 : o3. Прототипом же этой операции, в свою очередь, является условная функция cond языка Лисп, записываемая по правилам Лиспа в префиксной форме и имеющая произвольное количество аргументов.
Оператор выбора альтернатив switch.
Вторым оператором выбора в С++ является оператор switch, который обеспечивает многонаправленное ветвление программы. Следовательно, этот оператор позволяет сделать выбор среди нескольких альтернативных вариантов дальнейшего выполнения программы. Несмотря на то что многонаправленная проверка может быть организована с помощью последовательного ряда вложенных операторов if, во многих случаях более эффективным оказывается применение оператора switch. Этот оператор действует следующим образом. Значение выражения последовательно сравнивается с константами выбора из заданного списка. Как только будет обнаружено совпадение с одним из условий выбора, выполняется последовательность операторов, связанных с этим условием. Ниже приведена общая форма оператора switch:
switch(выражение) {
case константа1:
последовательность операторов
break;
case константа2:
последовательность операторов
break;
case константаЗ:
последовательность операторов
break;
…
default:
последовательность операторов
break;
}
infopedia.su
Прио—ритет | Операция | Название | Порядок выполнения |
1 | () | Скобки, вызов функции | Слева направо |
[] | Квадратные скобки, выделение элемента массива | Слева направо | |
. | Выделение элемента структуры или объединения | Слева направо | |
–> | Выделение элемента структуры (объединения), адресуемой (го) указателем | Слева направо | |
2 | ! | Логическое отрицание | Справа налево |
~ | Побитовое отрицание | Справа налево | |
– | Изменение знака | Справа налево | |
+ + | Увеличение на единицу | Справа налево | |
– – | Уменьшение на единицу | Справа налево | |
& | Определение адреса | Справа налево | |
* | Обращение по адресу (содержимое адреса), разыменование | Справа налево | |
(тип) | Преобразование типа | Справа налево | |
sizeof | Определение размера в байтах | Справа налево | |
3 | * | Умножение | Слева направо |
/ | Деление | Слева направо | |
% | Остаток от деления | Слева направо | |
4 | + | Сложение | Слева направо |
– | Вычитание | Слева направо | |
5 | << | Сдвиг влево | Слева направо |
>> | Сдвиг вправо | Слева направо | |
6 | < | Меньше | Слева направо |
<= (!=>) | Меньше или равно | Слева направо | |
> | Больше | Слева направо | |
>= (!<) | Больше или равно | Слева направо | |
7 | = = | Равно | Слева направо |
!= | Не равно | Слева направо | |
8 | & | Поразрядное И | Слева направо |
9 | ^ | Исключающее ИЛИ | Слева направо |
10 | | | Поразрядное ИЛИ | Слева направо |
11 | && | Логическое И | Слева направо |
12 | || | Логическое ИЛИ | Слева направо |
13 | ?: | Условная операция | Справа налево |
14 | = | Присваивание | Справа налево |
*= | Умножение и присваивание | Справа налево | |
/= | Деление и присваивание | Справа налево | |
%= | Остаток и присваивание | Справа налево | |
+= | Сложение и присваивание | Справа налево | |
– = | Вычитание и присваивание | Справа налево | |
<<= | Сдвиг влево и присваивание | Справа налево | |
>>= | Сдвиг вправо и присваивание | Справа налево | |
&= | Поразрядное И и присваивание | Справа налево | |
^= | Исключающее ИЛИ и присваивание | Справа налево | |
|= | Поразрядное ИЛИ и присваивание | Справа налево | |
15 | , | Операция запятая | Слева направо |
studfiles.net