C# — Логическая операция C#


Содержание

C# — Операторы

Оператор — это символ, который сообщает компилятору выполнить определенные математические или логические манипуляции. C # имеет богатый набор встроенных операторов и предоставляет следующие типы операторов:

  • Арифметические операторы
  • Реляционные операторы
  • Логические операторы
  • Побитовые операторы
  • Операторы присваивания
  • Другие операторы

В этом учебном пособии поочередно описываются арифметические, реляционные, логические, побитовые, присваивающие и другие операторы.

Арифметические операторы

В следующей таблице показаны все арифметические операторы, поддерживаемые C #. Предположим, что переменная A содержит 10, а переменная B имеет 20, тогда —

Оператор Описание Пример
+ Добавляет два операнда A + B = 30
Вычитает второй операнд с первого A — B = -10
* Умножает оба операнда A * B = 200
/ Делит числитель на де-числитель B / A = 2
% Оператор модуля и остаток после целочисленного деления B% A = 0
++ Оператор приращения увеличивает целочисленное значение на единицу A ++ = 11
Оператор Decrement уменьшает целочисленное значение на единицу A— = 9

Реляционные операторы

В следующей таблице показаны все реляционные операторы, поддерживаемые C #. Предположим, что переменная A имеет место 10, а переменная B имеет 20, тогда —

Оператор Описание Пример
== Проверяет, равны ли значения двух операндов или нет, если да, то условие становится истинным. (A == B) не соответствует действительности.
знак равно Проверяет, равны ли значения двух операндов или нет, если значения не равны, условие становится истинным. (A! = B) истинно.
> Проверяет, превышает ли значение левого операнда значение правого операнда, если да, тогда условие становится истинным. (A> B) неверно.
= Проверяет, превышает ли значение левого операнда значение правого операнда, если да, тогда условие становится истинным. (A> = B) неверно.
> Двоичный оператор правого сдвига.Значение левых операндов перемещается вправо на количество бит, заданных правым операндом. A >> 2 = 15, что составляет 0000 1111

Операторы присваивания

Существуют следующие операторы присваивания, поддерживаемые C # —

Оператор Описание Пример
знак равно Простой оператор присваивания, присваивает значения из правых операндов в левый операнд C = A + B присваивает значение A + B в C
+ = Добавить AND присваивания, Он добавляет правый операнд в левый операнд и присваивает результат левому операнду C + = A эквивалентно C = C + A
знак равно Вычитание и оператор присваивания, он вычитает правый операнд из левого операнда и присваивает результат левому операнду C — = A эквивалентно C = C — A
знак равно Оператор умножения и присваивания, Он умножает правый операнд на левый операнд и присваивает результат левому операнду C * = A эквивалентно C = C * A
знак равно Оператор Divide AND assign. Он делит левый операнд на правый операнд и присваивает результат левому операнду C / = A эквивалентно C = C / A
знак равно Модуль и оператор присваивания, он принимает модуль с использованием двух операндов и присваивает результат левому операнду C% = A эквивалентно C = C% A
> = Оператор правой смещения и назначения C >> = 2 совпадает с C = C >> 2
знак равно Оператор побитового И присваивания C & = 2 является таким же, как C = C & 2
^ = побитовое исключающее ИЛИ и оператор присваивания C ^ = 2 является таким же, как C = C ^ 2
| = побитовое включение OR и оператор присваивания C | = 2 совпадает с C = C | 2

Есть несколько других важных операторов, включая sizeof, typeof и ? :поддерживается C #.

Оператор Описание Пример
размер() Возвращает размер типа данных. sizeof (int), возвращает 4.
тип() Возвращает тип класса. TypeOf (StreamReader);
& Возвращает адрес переменной. & А; возвращает фактический адрес переменной.
* Указатель на переменную. * А; создает указатель с именем ‘a’ для переменной.
? : Условное выражение Если условие верно? Тогда значение X: В противном случае значение Y
является Определяет, имеет ли объект определенный тип. Если (Ford — Car) // проверяет, является ли Ford объектом класса Car.
в виде Передача без создания исключения, если сбой выполняется. Object obj = new StringReader («Hello»);

StringReader r = obj как StringReader;

Приоритет оператора в C #

Приоритет оператора определяет группировку терминов в выражении. Это влияет на оценку выражения. Некоторые операторы имеют более высокий приоритет, чем другие; например, оператор умножения имеет более высокий приоритет, чем оператор сложения.

Например, x = 7 + 3 * 2; здесь x назначается 13, а не 20, потому что оператор * имеет более высокий приоритет, чем +, поэтому первая оценка выполняется для 3 * 2, а затем 7 добавляется в нее.

Здесь операторы с наивысшим приоритетом появляются в верхней части таблицы, а нижние — внизу. Внутри выражения сначала оцениваются операторы с более высоким приоритетом.

Логические выражения в C#

Информация о работе

Тип Лекции
Предмет Программирование
Количество страниц 7
Язык работы Русский язык
Дата загрузки 2015-01-04 00:04:32
Размер файла 34.98 кб
Количество скачиваний 21

Узнать стоимость работы

Заполнение формы не обязывает Вас к заказу работы

Скачать файл с работой

Помогла работа? Поделись ссылкой

Существуют задачи, при решении которых появляются величины, принимающие только одно из двух возможных значений. Одно из этих состояний принимается за «истинное», а другое за «ложное». Для этих величин не может быть задано никакое третье значение (естественно, процесс переключения такой величины из одного состояния в другое не рассматривается), например, лампочка может быть включена или выключена. Обычно логические величины появляются при проверке логических отношений.
Логические величины входят в состав логических выражений, используемых в операторах управления программой (операторах условного перехода, операторах цикла и т.д.). Логические выражения состоят из арифметических выражений, логических отношений и логических операций.
В языке C# определены следующие операции логических отношений:
> строго больше;
= больше или равно;
= b/2 — 1
c != S
В результате проверки логических отношений формируются значения истинности и ложности.
Помимо числовых величин в логических отношениях могут участвовать символы и строки. В этом случае символы сравниваются по своим числовым кодам в соответствие с кодовой таблицей. Аналогично строки сравнивают по кодам символов слева направо до первого, не совпадающего по коду символа, который и определяет, какая из строк больше (или меньше).
В языке C# существует тип данных bool, позволяющий объявлять переменные логического типа, которые могут принимать значения true (истинно) и false (ложно).
Кроме операций логических отношений в логических выражениях могут использоваться логические операции. Определены следующие логические операции:
Логическая операция Название Обозначение
Отрицание NOT (Не) !
Логическое сложение OR (ИЛИ) ||
Логическое умножение AND (И) &&
Исключительное ИЛИ (двуместная операция) XOR ^
Исключительное ИЛИ (одноместная операция) XOR

Поразрядное Логическое сложение OR (ИЛИ) |
Поразрядное Логическое умножение AND (И) &
Результаты выполнения логических операций наглядно можно представить в виде таблиц истинности. В этих таблицах A и B операнды, а R — результат выполнения операции. Следует отметить, что название логических операций соответствует их смыслу в разговорном языке (как русском, так и английском).
В языке С++ нет жесткого выделения логических констант, все целые числа кроме нуля в логических выражениях соответствуют понятию true, а целочисленный нуль соответствует понятию false. В языке C# эти значения принимают только переменные типа bool. Однако для наглядности пояснения логических операций удобно использовать систему языка С++, считая что 1 соответствует понятию true, 0 соответствует false.
|| (OR)
&& (AND) ^ (XOR)
A B R A B R A B R
0 0 0 0 0 0 0 0 0
0 1 1 0 1 0 0 1 1
1 0 1 1 0 0 1 0 1
1 1 1 1 1 1 1 1 0
Как видно из таблицы для операции ИЛИ (||), результат получается истинным, если истинным является хотя бы один из операндов. Логическое сложение отличается от арифметического тем, что при сложении двух единиц (значений «истинно») результат равен 1, а не 2. Это и не удивительно, поскольку для логических величин нет третьего состояния.
Обычно логические операции позволяют создать фильтры для отбора данных по какому-либо критерию. Логическая операция ИЛИ позволяет выбрать один или несколько элементов из списка. Например, если выполняется набор группы студентов специальности АСУ, желающих поехать в туристическую поездку, то подходящими кандидатами являются ИЛИ студенты группы 2бАСУ1, ИЛИ студенты группы 2бАСУ2. Таким образом, в группу могут попасть как студенты любой из групп, так и из обеих групп вместе.
Операция логического умножения И (&&) выдает результат «истинно», если истинными являются все участвующие в операции операнды. Эта операция практически не отличается от арифметического умножения, и позволяет выбрать элементы с полным совпадением ключевых признаков. Например, для проверки попадания величины в заданный диапазон значений требуется, чтобы значение величины было больше минимального значения И меньше минимального значения.
Операция исключительного ИЛИ (^ либо

) выдает результат «истинно», если истинным является только один участвующий в операции операнд. Эта операция в разговорном языке соответствует конструкции ИЛИ – ИЛИ («или вы ликвидируете задолженность, или будете отчислены из института»). При построении фильтров эта операция обеспечивает выбор альтернативы. Эта операция существует в двух вариантах: для двухместных операций (^) и для поразрядных операций (


).
Безусловно, также как и в арифметических выражениях, в логическом выражении могут быть более двух операндов для любой из логических операций, а последние могут быть связаны между собой в любых сочетаниях.
Перечисленные выше логические операции могут выполняться для результатов проверки логических отношений, но они могут также использоваться для поразрядного выполнения, т.е. для выполнения логических операций над отдельными разрядами двоичного представления элемента данных. Поразрядные логические операции позволяют выполнить три операции:
• Установить в единицу отдельный бит в двоичном представлении числа.
• Проверить значение отдельного бита в двоичном представлении числа
• Сбросить в нуль значение отдельного бита в двоичном представлении числа.
Для операции поразрядного логического умножения записывают один символ «&». Пусть объявлены и инициализированы две переменные a и mask, как показано ниже. В примечаниях приведены двоичные коды инициализированных переменных a, mask и результата c. Числа представлены в шестнадцатеричных кодах для наглядности, в компьютере числа всегда записаны в двоичной системе счисления.
Ниже представлена подпрограмма, распечатывающая двоичный код числа.
// Подпрограмма представления числа в двоичном коде
// n — число, w — сколько младших цифр представить
static string conv(uint n, int w)
<
uint mask = 1;
char p;
string st = «»; // Пустая строка для двоичных цифр
for (int i = 0; i
<
if (t == true) // Действие при первом проходе
else //Действие при втором проходе

Цукерберг рекомендует:  Обучение программированию через тестирование или TDD

t ^= false; // Это сокращенная форма записи оператора t = t ^ false;
>

Для установки в нуль отдельного бита, сохраняя единицы в остальных разрядах, требуется создать маску, которая содержит нулевой бит в изменяемом разряде и единицы во всех остальных разрядах. Для этого можно задать маску как обычно для поразрядной операции ИЛИ, а затем применить к ней одноместную операцию XOR.
static void Main(string[] args)
<
uint a, mask, c;
mask = 0x08; // Маска
a = 0xDC; // Исходное число
// Поразрядная операция И с инвертированной маской
c = a &

mask;
Console.WriteLine(» Операция a &

mask результат
<0,8:X>«, c);
Console.WriteLine(» <0>исходное число
<1>маска», conv(a,8),conv(mask,8));
Console.WriteLine(«<0>«,conv(c,8));
Console.ReadKey();
>
После выполнения этой операции будет выведено:

Кроме перечисленных возможно также выполнение операций сдвига содержимого для целочисленных переменных. Для обозначения этих операций используются знаки >>n (сдвиг вправо) или > 4;
x = y В этом примере переменной t присваивается значение переменной s после сдвига значения последней на 4 двоичных разряда вправо, а переменной x сдвинутое на один разряд влево содержимое переменной y.
Операция сдвига влево на каждый разряд сдвига увеличивает сдвигаемое значение в 2 раза (умножает на 2) и заполняет освобождающиеся справа разряды числа нулями. Сдвиг вправо равносилен делению числа на два, но при этом положительные числа дополняются слева нулями, а отрицательные единицами. Это может привести к ошибке, поскольку при сдвиге вправо отрицательного числа на количество разрядов, равное разрядности числа, результат всегда будет состоять из одних двоичных единиц, независимо от начального значения числа. Если же переменная объявлена с модификатором unsigned, то при сдвиге вправо число слева дополняется нулями, то есть, искажение результата не происходит

Урок №43. Логические операторы: И, ИЛИ, НЕ

Обновл. 14 мая 2020 |

В то время как операторы сравнения используются для проверки конкретного условия: ложное оно или истинное, они могут проверить только одно условие за определённый промежуток времени. Но бывают ситуации, когда нужно протестировать сразу несколько условий. Например, чтобы узнать, выиграли ли мы в лотерею, нам нужно сравнить все цифры купленного билета с выигрышными. Если в лотерее 6 цифр, то нужно выполнить 6 сравнений, все из которых должны быть true.

Также иногда нам нужно знать, является ли хоть одно из нескольких условий истинным. Например, мы не пойдём сегодня на работу, если больны или слишком устали, или если выиграли в лотерею �� Нам нужно проверить, является ли хоть одно из этих 3 условий истинным. Как это сделать? С помощью логических операторов! Они позволяют проверить сразу несколько условий за раз. В C++ есть 3 логических оператора:

Оператор Символ Пример Операция
Логическое НЕ ! !x true, если x — false и false, если x — true
Логическое И && x && y true, если x и y — true, в противном случае — false
Логическое ИЛИ || x || y true, если x или y — true, в противном случае — false

Логический оператор НЕ

Логический оператор НЕ (!)
Операнд Результат
true false
false true

Если операндом является true, то после применения логического НЕ результатом будет false. Если же операнд до применения оператора НЕ является false, то после его применения — станет true. Другими словами, логический оператор НЕ меняет результат с true на false и наоборот. Он часто используется в условных выражениях:

Следует помнить, что логический оператор НЕ имеет очень высокий уровень приоритета. Новички часто совершают следующую ошибку:

Результат выполнения программы выше:

Но х ведь не равно у, как это возможно? Поскольку приоритет логического оператора НЕ выше, чем приоритет оператора равенства, то выражение ! х == у обрабатывается как (! х) == у . Так как х — это 5 , то !x — это 0 . Условие 0 == у ложное, поэтому выполняется часть else!

Напоминание: Любое ненулевое целое значение в логическом контексте является true. Так как х = 5 , то х вычисляется как true, а вот !x = false , т.е. 0. Использование целых чисел в логических операциях подобным образом может запутать не только пользователя, но и самого разработчика, поэтому мы не советуем так делать!

Правильный способ написания программы выше:

Сначала обрабатывается х == у , а затем уже оператор НЕ изменяет результат на противоположный.

Правило: Если логический оператор НЕ должен работать с результатами работы других операторов, то другие операторы и их операнды должны находиться в круглых скобках.

Логический оператор ИЛИ

Если хоть одно из двух условий является истинным, то логический оператор ИЛИ является true.

Логический оператор ИЛИ (||)
Левый операнд Правый операнд Результат
false false false
false true true
true false true
true true true

Рассмотрим следующую программу:

Здесь мы использовали логический оператор ИЛИ, чтобы проверить, является ли хоть одно из двух условий истинным: левое (value == 0) или правое (value == 1). Если хоть одно из условий — true или оба сразу true, то выполняться будет стейтмент if. Если ни одно из условий не является true, то результат — false и выполняться будет стейтмент else.

Вы можете соединить сразу несколько условий:

Новички иногда путают логическое ИЛИ (||) с побитовым ИЛИ (|). Хоть у них и одинаковые названия, функции они выполняют разные.

Логический оператор И

Только при условии, что оба операнда будут истинными, логический оператор И будет true. Если нет, тогда false.

Логический оператор И (&&)
Левый операнд Правый операнд Результат
false false false
false true false
true false false
true true true

Например, мы хотим знать, находится ли значение переменной х в диапазоне от 10 до 20. Здесь у нас есть два условия: мы должны проверить, является ли х больше 10 и является ли х меньше 20.

Если оба условия истинны, то выполняется часть if. Если же хоть одно или сразу оба условия ложные, то выполняется часть else.

Как и с логическим ИЛИ, мы можем комбинировать сразу несколько условий И:

Короткий цикл вычислений

Для того, чтобы логическое И возвращало true, оба операнда должны быть истинными. Если первый операнд вычисляется как false, то оператор И должен сразу возвращать false независимо от результата второго операнда (даже без его обработки). Это называется коротким циклом вычисления (англ. «short circuit evaluation») и выполняется он, в первую очередь, в целях оптимизации.

Аналогично, если первый операнд логического ИЛИ является true, то и всё условие будет true (даже без обработки второго операнда).

Как и в случае с оператором ИЛИ, новички иногда путают логическое И (&&) с побитовым И (&).


Использование операторов И/ИЛИ

Иногда возникают ситуации, когда смешивания логических операторов И и ИЛИ в одном выражении не избежать. Тогда следует знать о возможных проблемах, которые могут произойти.

Многие программисты думают, что логические И и ИЛИ имеют одинаковый приоритет (или забывают, что это не так), так же как и сложение/вычитание или умножение/деление. Тем не менее, приоритет логического И выше приоритета ИЛИ. Таким образом, операции с оператором И будут всегда вычисляться первыми (если только операции с ИЛИ не находятся в круглых скобках).

Рассмотрим следующее выражение: value1 || value2 && value3 . Поскольку приоритет логического И выше, то обрабатываться выражение будет так:

value1 || (value2 && value3)

(value1 || value2) && value3

Хорошей практикой является использование круглых скобок с операциями. Это предотвратит ошибки приоритета, увеличит читабельность кода и чётко даст понять компилятору, как следует обрабатывать выражения. Например, вместо того, чтобы писать value1 && value2 || value3 && value4 , лучше записать (value1 && value2) || (value3 && value4) .

Законы Де Моргана

Многие программисты совершают ошибку, думая, что !(x && y) — это то же самое, что и !x && !y . К сожалению, вы не можете «использовать» логическое НЕ подобным образом.

!(x && y) эквивалентно !x || !y
!(x || y) эквивалентно !x && !y

Другими словами, логические операторы И и ИЛИ меняются местами! В некоторых случаях, это даже полезно: улучшает читабельность.

А где же побитовое исключающее ИЛИ (XOR)?

Побитовое исключающее ИЛИ (XOR) — это логический оператор, который используется в некоторых языках программирования для проверки на истинность нечётного количества условий.

Побитовое исключающее ИЛИ (XOR)
Левый операнд Правый операнд Результат
false false false
false true true
true false true
true true false

В C++ нет такого оператора. В отличии от логических И/ИЛИ, к XOR не применяется короткий цикл вычислений. Однако его легко можно сымитировать, используя оператор неравенства (!=):

C# — Логическая операция C#

Доброго времени суток! В этой статье я доступно и коротко расскажу о выражения и операциях, часто используемых в C#. Основной код программы, написанной на C#, состоит из операторов и блоков операторов. Операторы, состоят из выражений, а те, в свою очередь – из операций и операндов. Пример простейшего выражения: 2 + 5; где «2» и «5» являются операндами, а «+» – операцией.

В программах, написанных на C#, операндами обычно являются объекты классов (в том числе, пользовательских) или переменные/константы встроенных типов.

Операции, можно условно разделить на группы: унарные (с одним операндом), бинарные (с двумя операндами), тернарные (с тремя операндами), но я буду перечислять операции группируя их по приоритету выполнения (в порядке убывания).

Приоритет выполнения, показывает, в каком порядке, буду выполняться операции в выражении, состоящем более чем из одной операции. Как в математике, помните? Умножение выполняется перед сложением или вычитанием.

Давайте теперь рассмотрим основные операции, доступные в C#!

«.» – операция доступа к полю/свойству/методу класса. Использовать можно, например, так:

«()» – операция вызова метода. Использовать можно, следующим:

«[]» – операция доступа к массиву (если хотите, к элементу массива). Пример использования:

«++» и «» после операнда – операции постинкремента и постдекремента (как правило, увеличивает и уменьшает, соответственно, значение операнда на единицу). Использовать можно так:

«new» – операция создания объекта/массива. Использовать можно так:

«typeof» – операция получения информации о типе данных. Пример использования:

«» перед операндом – операция отрицания. Использовать можно так:

«!» перед операндом – операция логического отрицания. Использовать можно следующим образом:

» перед операндом – операция двоичного (побитового) отрицания. Инвертирует (0 меняет на 1, а 1 на ноль) каждый бит числа. Этой операцией, Вы будете пользоваться редко… Использовать можно так:

«++» и «» перед операндом – операции преинкремента и предекремента соответственно (как правило, увеличивает и уменьшает, соответственно, значение операнда на единицу). Использовать можно так:

Обратите внимание, префиксная форма операции инкремента/декремента очень похожа на постфиксную, отличия проявляются лишь при использовании в сложных выражениях. Преинкремент/декремент сначала выполняется сам, а потом возвращает значение, а постфиксная форма, сначала возвращает значение, а потом выполняется.

На практике, постфиксная форма работает так:

Цукерберг рекомендует:  Отклики на резюме - карьера, отклики на резюме в разделе карьера

«(…)» перед операндом – операция приведения типа. Используется для приведения переменной одного типа, к другому (так называемое, явное приведение типа). Использовать можно так:

«*» и «/» – операции умножения и деления. Думаю, использование этих операций в описании не нуждается.

«%» – данная операция, возвращает остаток от деления. К примеру, при делении четного числа на 2, вернет 0. На практике можно использовать так:

«+» и «» – операции сложения и вычитания. Думаю, в дополнительном описании не нуждаются.


« >» – операции побитового сдвига влево и вправо соответственно. Как это работает на практике:

«is» – операция проверки возможности приведения типа. На практике работает так:

«as» – операция преобразования типа, без генерации исключения в случае неудачи. Данная операция осуществляет попытку преобразовать объект одного типа к другому, но, если такое преобразование невозможно, возвращает null (пустую ссылку, если хотите). На практике это работает так:

«==» и «!=» – операции эквивалентности, эквивалентно и неэквивалентно (обратные друг другу операции).

«&» – операция побитового «И» для целочисленных типов и операция логического умножения, для bool-типов.

«^» – операция побитового исключающего «ИЛИ» для целочисленных типов и операция логического исключающего «ИЛИ», для bool-типов.

«|» – операция побитового «ИЛИ» для целочисленных типов и операция логического «ИЛИ», для bool-типов.

«&&» -– операция условного «И». Возвращает истину, если истины оба операнда, во всех остальных случаях, вернет ложь. Использовать можно так:

«||» -– операция условного «ИЛИ». Возвращает истину, если хоть один операнд имеет значение true. Использовать можно так:

«?» – условная операция. Имеет вид: [условие] ? [результат 1] : [результат 2]. Если выполняется условие, то возвращается [результат 1], если условие не выполняется – [результат 2]. Использовать можно так:

«=» – операция присваивания. Думаю, что пояснять для чего нужна эта операция не нужно, она использовалась не однократно в примерах выше.

«*=», «/=», «%=», «+=», «-=», « >=», «&=», «^=», «|=» – операции составного присваивания. Работу покажу на примере операции «+=»:

Добавить комментарий Отменить ответ

Для отправки комментария вам необходимо авторизоваться.

Логические выражения в C/C++. Как ошибаются профессионалы

Введение

Я занимаюсь разработкой статического анализатора кода для языков C/C++/C# — PVS-Studio. В моей работе приходится много сталкиваться с открытым и закрытым кодом разных проектов. Часто результатом такой работы являются статьи о проверке open source проектов, содержащие описание найденных ошибок и недочётов. После просмотра большого объёма кода начинаешь замечать различные паттерны ошибок, которые допускают программисты. Так, мой коллега Андрей Карпов писал статью про эффект последней строки после нахождения большого количества ошибок, допущенных в последних фрагментах однотипного кода.

В начале этого года я проверил с помощью анализатора много проектов крупных компаний в сфере IT, которые, следуя современной тенденции, выкладывают в открытый доступ исходный код своих проектов под свободными лицензиями. Я стал замечать, что почти в каждом проекте находится ошибка в условном выражении из-за неправильной записи условных операторов. Само выражение достаточно простое и состоит всего из трёх операторов:

  • != || !=
  • == || !=
  • == && ==
  • == && !=

Всего таких условных выражений можно записать 6 штук, но 4 из них являются ошибочными: два являются всегда истинным или ложным; в двух результат всего выражения не зависит от результата входящего в него подвыражения.

Для доказательства неверного результата выражения я буду строить таблицу истинности в каждом примере; также я приведу для каждого примера по одному фрагменту кода из открытого проекта. В этой статье будет упомянут и тернарный оператор ‘?:’, который имеет почти самый низкий приоритет из всех операторов, но очень много разработчиков не знают об этом.

Т.к. чаще всего я встречал неправильные условные выражения при проверке результата разных функций, код возврата которых сравнивают с кодами ошибок, то в приводимых далее синтетических примерах я буду использовать переменную с именем err, а code1 и code2 будут константами. При этом константы code1 и code2 не равны. Значение «other codes» будет означать любые другие константы, не равные code1 и code2.

Ошибки с использованием оператора ‘||’

Выражение != || !=

Синтетический пример, в котором результат условного выражения всегда будет равен истине:

Далее представлена таблица истинности для этого примера кода:

Теперь посмотрим на реальный пример ошибки, найденной в проекте LibreOffice.

V547 Expression is always true. Probably the ‘&&’ operator should be used here. sbxmod.cxx 1777

Выражение == || !=

Синтетический пример, в котором результат всего условного выражения не зависит от результата подвыражения (err == code1):

Далее представлена таблица истинности для этого примера кода:

Теперь посмотрим на реальный пример ошибки, найденной в проекте FreeBSD.

V590 Cons >
Не сильно он отличается от синтетического примера, не правда ли?

Ошибки с использованием оператора ‘&&’

Выражение == && ==

Синтетический пример, в котором результат условного выражения всегда будет ложным:

Далее представлена таблица истинности для этого примера кода:


Теперь посмотрим на реальный пример ошибки, найденной в проекте SeriousEngine.

V547 Expression is always false. Probably the ‘||’ operator should be used here. entity.cpp 3537

Выражение == && !=

Синтетический пример, в котором результат всего условного выражения не зависит от результата подвыражения «err != code2»:

Далее представлена таблица истинности для этого примера кода:

Теперь посмотрим на реальный пример ошибки, найденной в проекте ChakraCore — JavaScript-движке для Microsoft Edge.

V590 Cons expression. The expression is excessive or contains a misprint. rl.cpp 1388

Ошибки с использованием оператора ‘?:’

V502 Perhaps the ‘?:’ operator works in a different way than it was expected. The ‘?:’ operator has a lower priority than the ‘|’ operator. ata-serverworks.c 166

В заключение хочу сказать про тернарный оператор ‘?:’. Его приоритет почти самый низкий среди всех операторов. Ниже только у присваивания, throw и оператора «запятая». Приведённая в примере ошибка была найдена в ядре FreeBSD. Здесь тернарным оператором воспользовались для выбора нужного флажка и чтобы написать короткий красивый код. Но приоритет оператора побитового ‘ИЛИ’ выше, поэтому условное выражение вычисляется не в том порядке, в каком планировал программист. Эту ошибку я тоже решил описать в этой статье, т.к. она является очень распространённой среди проверенных мною проектов.

Заключение

Описанные шаблоны условных выражений могут нести большую опасность, если не проявлять повышенную внимательность при написании кода. Несмотря на небольшое количество операторов, всё условное выражение может пониматься неправильно. Код, в котором допустили такую ошибку, может выглядеть вполне логичным и будет пропущен после code-review. Подстраховать себя от таких ошибок можно путём проверки своего кода с помощью построения таблиц истинности, если есть сомнения в правильности условия, а также с помощью регулярных проверок статическими анализаторами.

Логические операции и операторы

Дата изменения: 27.08.2020

Логические операторы в C# (возвращающие значение true или false типа bool) есть такие:

Оператор

Операция

Написание

Проверка неравенства (всегда противоположно к ==)

Логическое НЕ (отрицание)

Больше чем (true, если левый операнд больше правого)

Больше или равно

Данный материал был вам полезен?

Не забудьте оставить свой комментарий, а также поблагодарить автора и поддержать его для создания новых полезных материалов

C# — Операторы

Оператор — это символ, который сообщает компилятору выполнить определенные математические или логические манипуляции. C # имеет богатый набор встроенных операторов и предоставляет следующие типы операторов:

  • Арифметические операторы
  • Реляционные операторы
  • Логические операторы
  • Побитовые операторы
  • Операторы присваивания
  • Другие операторы

В этом учебном пособии поочередно описываются арифметические, реляционные, логические, побитовые, присваивающие и другие операторы.

Арифметические операторы

В следующей таблице показаны все арифметические операторы, поддерживаемые C #. Предположим, что переменная A содержит 10, а переменная B имеет 20, тогда —

Оператор Описание Пример
+ Добавляет два операнда A + B = 30
Вычитает второй операнд с первого A — B = -10
* Умножает оба операнда A * B = 200
/ Делит числитель на де-числитель B / A = 2
% Оператор модуля и остаток после целочисленного деления B% A = 0
++ Оператор приращения увеличивает целочисленное значение на единицу A ++ = 11
Оператор Decrement уменьшает целочисленное значение на единицу A— = 9

Реляционные операторы

В следующей таблице показаны все реляционные операторы, поддерживаемые C #. Предположим, что переменная A имеет место 10, а переменная B имеет 20, тогда —

Оператор Описание Пример
== Проверяет, равны ли значения двух операндов или нет, если да, то условие становится истинным. (A == B) не соответствует действительности.
знак равно Проверяет, равны ли значения двух операндов или нет, если значения не равны, условие становится истинным. (A! = B) истинно.
> Проверяет, превышает ли значение левого операнда значение правого операнда, если да, тогда условие становится истинным. (A> B) неверно.
= Проверяет, превышает ли значение левого операнда значение правого операнда, если да, тогда условие становится истинным. (A> = B) неверно.
> Двоичный оператор правого сдвига.Значение левых операндов перемещается вправо на количество бит, заданных правым операндом. A >> 2 = 15, что составляет 0000 1111

Операторы присваивания


Существуют следующие операторы присваивания, поддерживаемые C # —

Оператор Описание Пример
знак равно Простой оператор присваивания, присваивает значения из правых операндов в левый операнд C = A + B присваивает значение A + B в C
+ = Добавить AND присваивания, Он добавляет правый операнд в левый операнд и присваивает результат левому операнду C + = A эквивалентно C = C + A
знак равно Вычитание и оператор присваивания, он вычитает правый операнд из левого операнда и присваивает результат левому операнду C — = A эквивалентно C = C — A
знак равно Оператор умножения и присваивания, Он умножает правый операнд на левый операнд и присваивает результат левому операнду C * = A эквивалентно C = C * A
знак равно Оператор Divide AND assign. Он делит левый операнд на правый операнд и присваивает результат левому операнду C / = A эквивалентно C = C / A
знак равно Модуль и оператор присваивания, он принимает модуль с использованием двух операндов и присваивает результат левому операнду C% = A эквивалентно C = C% A
> = Оператор правой смещения и назначения C >> = 2 совпадает с C = C >> 2
знак равно Оператор побитового И присваивания C & = 2 является таким же, как C = C & 2
^ = побитовое исключающее ИЛИ и оператор присваивания C ^ = 2 является таким же, как C = C ^ 2
| = побитовое включение OR и оператор присваивания C | = 2 совпадает с C = C | 2

Есть несколько других важных операторов, включая sizeof, typeof и ? :поддерживается C #.

Цукерберг рекомендует:  Логическое программирование и кому оно нужно
Оператор Описание Пример
размер() Возвращает размер типа данных. sizeof (int), возвращает 4.
тип() Возвращает тип класса. TypeOf (StreamReader);
& Возвращает адрес переменной. & А; возвращает фактический адрес переменной.
* Указатель на переменную. * А; создает указатель с именем ‘a’ для переменной.
? : Условное выражение Если условие верно? Тогда значение X: В противном случае значение Y
является Определяет, имеет ли объект определенный тип. Если (Ford — Car) // проверяет, является ли Ford объектом класса Car.
в виде Передача без создания исключения, если сбой выполняется. Object obj = new StringReader («Hello»);

StringReader r = obj как StringReader;

Приоритет оператора в C #

Приоритет оператора определяет группировку терминов в выражении. Это влияет на оценку выражения. Некоторые операторы имеют более высокий приоритет, чем другие; например, оператор умножения имеет более высокий приоритет, чем оператор сложения.

Например, x = 7 + 3 * 2; здесь x назначается 13, а не 20, потому что оператор * имеет более высокий приоритет, чем +, поэтому первая оценка выполняется для 3 * 2, а затем 7 добавляется в нее.

Здесь операторы с наивысшим приоритетом появляются в верхней части таблицы, а нижние — внизу. Внутри выражения сначала оцениваются операторы с более высоким приоритетом.

Операции в языке Си

Над объектами в языке Си могут выполняться различные операции:

  • операции присваивания;
  • операции отношения;
  • арифметические;
  • логические;
  • сдвиговые операции.

Результатом выполнения операции является число.

Операции могут быть бинарными или унарными.
Бинарные операции выполняются над двумя объектами, унарные — над одним.

Операция присваивания

Операция присваивания обозначается символом = и выполняется в 2 этапа:

  • вычисляется выражение в правой части;
  • результат присваивается операнду, стоящему в левой части:

объект = выражение;

В случае если объекты в левой и правой части операции присваивания имеют разные типы используется операция явного приведения типа.
объект = (тип)выражение;

Операции отношения

Основные операции отношения:

  • == эквивалентно — проверка на равенство;
  • != не равно — проверка на неравенство;
  • меньше;
  • > больше;
  • меньше или равно;
  • >= больше или равно.

Операции отношения используются при организации условий и ветвлений. Результатом этих операций является 1 бит, значение которого равно 1 , если результат выполнения операции — истина, и равно 0 , если результат выполнения операции — ложь.

Арифметические операции

Основные бинарные операции, расположенные в порядке уменьшения приоритета:

  • * — умножение;
  • / — деление;
  • + — сложение;
  • — вычитание;
  • % — остаток от целочисленного деления.

Основные унарные операции:

  • ++ — инкрементирование (увеличение на 1);
  • –– — декрементирование (уменьшение на 1);
  • — изменение знака.

Результат вычисления выражения, содержащего операции инкрементирования или декрементирования, зависит от того, где расположен знак операции (до объекта или после него). Если операция расположена до объекта, то сначала происходит изменение значения переменной на 1, а потом это значение используется для выполнения следующих операций. Если операция ++ или расположена после переменной, то сначала выполняется операция, а потом значение переменной изменяется на 1.

Бинарные арифметические операции могут быть объединены с операцией присваивания:

  • объект *= выражение; // объект = объект * выражение
  • объект /= выражение; // объект = объект / выражение
  • объект += выражение; // объект = объект + выражение
  • объект -= выражение; // объект = объект — выражение
  • объект %= выражение; // объект = объект % выражение


Логические операции

Логические операции делятся на две группы:

Условные логические операции чаще всего используются в операциях проверки условия if и могут выполняться над любыми объектами. Результат условной логической операции:

  • 1 если выражение истинно;
  • 0 если выражение ложно.

Вообще, все значения, отличные от нуля, интерпретируются условными логическими операциями как истинные.

Основные условные логические операции:

  • && — И (бинарная) — требуется одновременное выполнение всех операций отношения;
  • || — ИЛИ (бинарная) — требуется выполнение хотя бы одной операции отношения;
  • ! — НЕ (унарная) — требуется невыполнение операции отношения.

Побитовые логические операции оперируют с битами, каждый из которых может принимать только два значения: 0 или 1.

Основные побитовые логические операции в языке Си:

инверсия (логическое НЕ) — унарная операция, результат которой равен 0 если операнд единичный, и равен 1, если операнд нулевой;

  • ^ исключающее ИЛИ — бинарная операция, результат которой равен 1, если только один из двух операндов равен 1 (в общем случае если во входном наборе операндов нечетное число единиц).
  • Для каждого бита результат выполнения операции будет получен в соответствии с таблицей.

    a

    a b a & b a | b a ^ b
    1
    1 1 1 1
    1 1 1
    1 1 1 1

    a; // e = 241 = 1111 0001
    f = a ^ b; // f = 7 = 0000 0111

    Побитовые операции позволяют осуществлять установку и сброс отдельных битов числа. С этой целью используется маскирование битов . Маски, соответствующие установке каждого бита в байте, представлены в таблице

    Бит Маска
    0x01
    1 0x02
    2 0x04
    3 0x08
    4 0x10
    5 0x20
    6 0x40
    7 0x80

    Для установки определенного бита необходимо соответствующий бит маски установить в 1 и произвести операцию побитового логического ИЛИ с константой, представляющей собой маску:

    Для сброса определенного бита необходимо соответствующий бит маски сбросить в 0 и произвести операцию побитового логического И с константой, представляющей собой инверсную маску:

    0x02); // a = 1, бит 1 сброшен

    Бинарные побитовые логические операции могут быть объединены с операцией присваивания:

    • объект &= выражение; // объект = объект & выражение
    • объект |= выражение; // объект = объект | выражение
    • объект ^= выражение; // объект = объект ^ выражение

    Сдвиговые операции

    Операции арифметического сдвига применяются в целочисленной арифметике и обозначаются как:

    • >> — сдвиг вправо;
    • — сдвиг влево.

    Общий синтаксис осуществления операции сдвига:
    объект = выражение сдвиг КоличествоРазрядов;

    Арифметический сдвиг целого числа вправо >> на 1 разряд соответствует делению числа на 2.
    Арифметический сдвиг целого числа влево на 1 разряд соответствует умножению числа на 2.

    Программируем на C#

    Блог содержит статьи, исходные тексты программ на C#. Здесь можно скачать исходник нужной программы.

    Операторы отношения, логические и поразрядные операторы


    Операторы отношения используются для сравнения двух величин, а поразрядные операторы — для выполнения поразрядных операций между величинами.

    Логическое отрицание

    Оператор ! возвращает отрицание логической (булевой) величины.

    Операторы отношения

    В C# определяются следующие операторы отношения:

    Возвращает истину, если a равно b

    Возвращает истину, если a не равно b

    Возвращает истину, если a больше b

    Возвращает истину, если a больше или равно b

    Эти операторы возвращают результат типа bool.

    При сравнении двух объектов ссылочного типа компилятор сначала ищет операторы отношения, определенные для этих объектов. Если он не находит подходящего оператора, то для операторов отношения == и != вызывается соответствующий оператор отношения класса object. Этот оператор сравнивает, относятся ли два операнда к одному объекту; значения их переменных при этом не сравниваются.

    Для типа string операторы отношения перегружаются так, чтобы == и != сравнивали не ссылки, а содержимое строк.

    Логические и поразрядные операторы

    В C# определяются следующие логические и поразрядные операторы:

    Поразрядная операция AND с двумя операндами

    Поразрядная операция OR с двумя операндами

    Поразрядная операция XOR (исключающее OR) с двумя операндами

    Логическая операция AND с двумя операндами

    Логическая операция OR с двумя операндами

    Операторы &, | и ^ обычно используются с целыми типами данных, хотя они также могут применяться и к типу bool.

    Операторы && и || отличаются от своих односимвольных версий тем, что они выполняют ускоренные вычисления. В выражении

    b вычисляется лишь в том случае, если a равно true. В выражении

    b вычисляется лишь в том случае, если a равно false.

    Оператор проверки

    Оператор проверки (?:), также называемый тернарным оператором, выбирает одно из двух выражений на основании логического условия.

    IT1300: Императивное программирование

    В C# предусмотрены также специальные, укороченные, варианты логических операторов И и ИЛИ, предназначенные для получения более эффективного кода. Поясним это на следующих примерах логических операций.

    Если первый операнд логической операции И имеет ложное значение ( false ), то ее результат будет иметь ложное значение независимо от значения второго операнда.

    Если же первый операнд логической операции ИЛИ имеет истинное значение ( true ), то ее результат будет иметь истинное значение независимо от значения второго операнда.

    Благодаря тому, что значение второго операнда в этих операциях вычислять не нужно, экономится время и повышается эффективность кода.

    Укороченная логическая операция И выполняется с помощью оператора && , а укороченная логическая операция ИЛИ — с помощью оператора || . Этим укороченным логическим операторам соответствуют обычные логические операторы & и | . Единственное отличие укороченного логического оператора от обычного заключается в том, что второй его операнд вычисляется только по мере необходимости.

    В приведенном ниже примере программы демонстрируется применение укороченного логического оператора И. В этой программе с помощью операции деления по модулю определяется следующее: делится ли значение переменной d на значение переменной n нацело. Если остаток от деления n/d равен нулю, то n делится на d нацело.

    Но поскольку данная операция подразумевает деление, то для проверки условия деления на нуль служит укороченный логический оператор И.

    Для исключения ошибки из-за деления на нуль в операторе if сначала проверяется условие: равно ли нулю значение переменной d . Если оно равно нулю, то на этом выполнение укороченного логического оператора И завершается, а последующая операция деления по модулю не выполняется. Так, при первой проверке значение переменной d оказывается равным 2, поэтому выполняется операция деления по модулю. А при второй проверке это значение оказывается равным нулю, следовательно, операция деления по модулю пропускается, чтобы исключить деление на нуль. И наконец, выполняется обычный логический оператор И, когда вычисляются оба операнда. Если при этом происходит деление на нуль, то возникает ошибка при выполнении.

    Укороченные логические операторы иногда оказываются более эффективными, чем их обычные аналоги. Так зачем же нужны обычные логические операторы И и ИЛИ? Дело в том, что в некоторых случаях требуется вычислять оба операнда логической операции И либо ИЛИ из-за возникающих побочных эффектов. Рассмотрим следующий пример программы.

    Прежде всего обратим внимание на то, что переменная someCondition типа bool инициализируется значением false . Далее проанализируем каждый оператор if . Как следует из комментариев к данной программе, в первом операторе if переменная i инкрементируется, несмотря на то, что значение переменной someCondition равно false . Когда применяется логический оператор & , как это имеет место в первом операторе if , выражение в правой части этого оператора вычисляется независимо от значения выражения в его левой части. А во втором операторе if применяется укороченный логический оператор. В этом случае значение переменной i не инкрементируется, поскольку левый операнд (переменная someCondition ) имеет значение false , следовательно, выражение в правой части данного оператора пропускается. Из этого следует вывод: если в коде предполагается вычисление правого операнда логической операции И либо ИЛИ, то необходимо пользоваться неукороченными формами логических операций, доступных в C#.

    И последнее замечание: укороченный оператор И называется также условным логическим оператором И, а укороченный оператор ИЛИ — условным логическим оператором ИЛИ.

    Понравилась статья? Поделиться с друзьями:
    Все языки программирования для начинающих