Что такое flag boolean

Это блог

Эта статья для студентов базового курса по javascript в HTML Academy.

Уберите лишние if

Рассмотрим простую задачу: если оценка меньше трёх, будем грустить, иначе не будем.

Одна строка вместо пяти. Если вы не уверены, что этот код делает то же, что с условием, — проверьте.

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

Этот подход хорошо работает с элементами форм. У них есть булевые свойства типа required, disabled, checked, и их тоже можно выставлять сразу, без лишних условий:

Ещё по условию можно переключать классы:

То есть, вместо пяти строк можно снова написать одну:

Выносите части условий в переменные

В этом коде при беглом взгляде не понятно, что происходит:

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

или вынести проверку в функцию:

Научитесь работать с логическими операторами

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

Это можно записать в таблицу (вместо false обычно пишут 0, а вместо true — 1):

Значение
a
Значение
b
Значение
a && b
000
010
100
111

Таблица истинности для выражения a && b

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

Получается, что вместо:

Потренируйтесь вычислять логические выражения в уме.

Подписывайтесь на телеграм-канал про фронтенд, дизайн, работу и жизнь.

Источник

Boolean Структура

Определение

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

Представляет логическое значение ( true или false ).

Комментарии

BooleanСтруктура предоставляет методы, которые поддерживают следующие задачи:

Преобразование логических значений в строки: ToString

Синтаксический анализ строк для преобразования их в логические значения: Parse и TryParse

Сравнение значений: CompareTo и Equals

В следующих разделах описаны эти задачи и другие сведения об использовании.

Форматировать логические значения

ToStringДля преобразования логических значений в строки используется метод. Логическая структура включает две ToString перегрузки: метод без параметров ToString() и ToString(IFormatProvider) метод, который включает параметр, управляющий форматированием. Однако, поскольку этот параметр игнорируется, две перегрузки создают идентичные строки. ToString(IFormatProvider)Метод не поддерживает форматирование с учетом языка и региональных параметров.

Поскольку Boolean структура может иметь только два значения, можно легко добавить пользовательское форматирование. Для простого пользовательского форматирования, в котором другие строковые литералы заменяются на «true» и «false», можно использовать любую функцию условной оценки, поддерживаемую языком, например Условный оператор в C# или оператор if в Visual Basic. В следующем примере используется этот метод для форматирования Boolean значений «Yes» и «No», а не «true» и «false».

Для более сложных операций пользовательского форматирования, включая форматирование с учетом языка и региональных параметров, можно вызвать String.Format(IFormatProvider, String, Object[]) метод и предоставить ICustomFormatter реализацию. В следующем примере реализуются ICustomFormatter интерфейсы и, IFormatProvider которые обеспечивают зависящие от языка и региональных параметров логические строки для языков и региональных параметров «английский (США)», «французский (Франция)» и «Русский (Россия)».

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

Преобразование в логические значения и из них

При преобразовании Boolean в числовые значения методы преобразования Convert класса преобразуют true в 1 и false в 0. однако функции преобразования Visual Basic преобразуются true в 255 (для преобразований в Byte значения) или-1 (для всех других числовых преобразований). в следующем примере true выполняется преобразование в числовые значения с помощью Convert метода и, в случае с Visual Basic примере, с помощью собственного оператора преобразования языка Visual Basic.

Анализ логических значений

В следующем примере Parse методы и используются TryParse для синтаксического анализа нескольких строк. Обратите внимание, что синтаксический анализ возможен только для эквивалентов «true» и «false» без учета регистра.

Сравнение логических значений

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

эквивалентны, но второй является более компактным. Однако оба метода обеспечивают сравнимую производительность.

Работа с логическими значениями в виде двоичных значений

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

Структуру можно использовать System.Collections.Specialized.BitVector32 для работы с наборами логических значений.

Вы можете преобразовать логическое значение в его двоичное представление, вызвав BitConverter.GetBytes(Boolean) метод. Метод возвращает массив байтов с одним элементом. Чтобы восстановить логическое значение из двоичного представления, можно вызвать BitConverter.ToBoolean(Byte[], Int32) метод.

В следующем примере вызывается BitConverter.GetBytes метод для преобразования логического значения в его двоичное представление и отображения отдельных битов значения, а затем вызывается BitConverter.ToBoolean метод для восстановления значения из его двоичного представления.

Выполнение операций с логическими значениями

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

Логические значения в качестве флагов

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

Логическое значение иногда используется для указания наличия условия, запускающего математическое вычисление. Например, hasShippingCharge переменная может служить флагом для указания, следует ли добавить плату за доставку в сумму счета.

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

В следующем примере показано вычисление суммы, состоящей из промежуточного итога, платы за доставку и дополнительной сервисной платы. hasServiceCharge Переменная определяет, применяется ли плата за обслуживание. Вместо преобразования hasServiceCharge в числовое значение и его умножения на объем сервисной платы, в примере используется условная логика для добавления суммы сервисной платы, если она применима.

Логические значения и взаимодействие

При маршалировании базовых типов данных в модель COM, как правило, Boolean тип данных является исключением. Можно применить MarshalAsAttribute атрибут для маршалирования Boolean типа в любое из следующих представлений:

Представляет логическое значение false в виде строки. Это поле доступно только для чтения.

Представляет логическое значение true в виде строки. Это поле доступно только для чтения.

Методы

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

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

Возвращает значение, указывающее, равен ли данный экземпляр заданному объекту Boolean.

Возвращает значение, показывающее, равен ли данный экземпляр заданному объекту.

Возвращает хэш-код данного экземпляра.

Возвращает код типа для типа значения Boolean.

Преобразует заданное представление логического значения в виде диапазона в его эквивалент Boolean.

Преобразует заданное строковое представление логического значения в эквивалентное значение Boolean.

Преобразовывает значение этого экземпляра в эквивалентное ему строковое представление («True» или «False»).

Преобразовывает значение этого экземпляра в эквивалентное ему строковое представление («True» или «False»).

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

Пытается преобразовать заданное представление логического значения в виде диапазона в его эквивалент типа Boolean.

Пытается преобразовать заданное строковое представление логического значения в его эквивалент типа Boolean.

Явные реализации интерфейса

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

Возвращает TypeCode для этого экземпляра.

Описание этого члена см. в разделе ToBoolean(IFormatProvider).

Описание этого члена см. в разделе ToByte(IFormatProvider).

Это преобразование не поддерживается. При попытке использовать этот метод выбрасывается исключение InvalidCastException.

Это преобразование не поддерживается. При попытке использовать этот метод выбрасывается исключение InvalidCastException.

Описание этого члена см. в разделе ToDecimal(IFormatProvider).

Описание этого члена см. в разделе ToDouble(IFormatProvider).

Описание этого члена см. в разделе ToInt16(IFormatProvider).

Описание этого члена см. в разделе ToInt32(IFormatProvider).

Описание этого члена см. в разделе ToInt64(IFormatProvider).

Описание этого члена см. в разделе ToSByte(IFormatProvider).

Описание этого члена см. в разделе ToSingle(IFormatProvider).

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

Описание этого члена см. в разделе ToType(Type, IFormatProvider).

Описание этого члена см. в разделе ToUInt16(IFormatProvider).

Описание этого члена см. в разделе ToUInt32(IFormatProvider).

Описание этого члена см. в разделе ToUInt64(IFormatProvider).

Применяется к

Потокобезопасность

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

Источник

Флаги в аргументах функций

Вы когда-нибудь сталкивались с таким кодом?

Эта функция, судя по названию, что-то обрабатывает (process). Но что означают параметры? Какой параметр здесь true, а какой false? По вызывающему коду об этом нельзя судить.

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

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

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

Но я перепутал порядок аргументов.

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

И это слишком похоже на именованные параметры функции — возможность, отсутствующую в C++. Если б она была, то могла бы выглядеть как-нибудь так:

Но если бы даже в C++ такое было, вряд ли это было бы совместимо с прямой передачей (perfect forwarding):

С этим может быть связан еще более коварный баг, который гораздо труднее отследить. Представьте, что функция process — это виртуальный метод класса. И в каком-то другом классе мы его переопределяем, при этом располагая флаги в неправильном порядке:

Компилятор не заметит проблемы, поскольку параметры различаются только по именам, а их типы одинаковы (оба bool).

Баги, возникающие по причине использования логических параметров в интерфейсе, на этом не заканчиваются. Из-за того, что почти все встроенные типы преобразовываются в bool, следующий пример компилируется без ошибок, но делает не то, что ожидается:

Более распространенная проблема — с использованием bool в конструкторах. Пускай есть класс с двумя конструкторами:

В какой-то момент Вы решаете удалить второй конструктор, и может быть надеетесь, что компилятор укажет Вам на все места, требующие исправления. Но этого не происходит. Из-за неявных преобразований в bool, первый конструктор будет использован везде, где раньше использовался второй.

Однако есть причина, почему люди обычно используют bool для представления флагов. Это единственный встроенный тип, доступный «из коробки» и предназначенный для представления только двух возможных значений.

Перечисления

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

— для каждого флага создается уникальный тип,
— неявные преобразования запрещаются.

C++11 вводит понятие классов перечислений, которые удовлетворяют обоим требованиям. Также мы можем использовать тип bool как базовый тип перечисления; таким образом, мы гарантируем, что перечисление содержит только два возможных значения и имеет размер одного bool. Вначале определяем классы флагов:

Теперь мы можем объявить нашу функцию:

Есть некоторая избыточность в этом объявлении, но зато порядок использования функции теперь такой, какой нужен:

И если я поставлю флаги в неправильном порядке, то получу ошибку компиляции из-за несоответствия типов:

Каждый флаг имеет уникальный тип, который исправно работает при прямой передаче (perfect forwarding), и Вы никак не сможете расположить параметры в неправильном порядке в объявлениях функций и переопределениях виртуальных методов.

Но использование перечислений в качестве флагов имеет свою цену. Флаги в некоторой мере похожи на значения типа bool, но классы перечислений не имитируют эту схожесть. Неявные преобразования в bool и обратно не работают (и это хорошо), но явные преобразования тоже не работают, и это проблема. Если мы взглянем еще раз на тело функции process, то поймем, что оно не компилируется:

Мне приходится использовать явное преобразование:

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

Кроме того, для экземпляра класса перечисления Вы не можете сделать прямую инициализацию из bool:

Опять придется делать явное преобразование:

Это можно считать дополнительной гарантией безопасности, но здесь слишком много явных преобразований. В классах перечислений больше «explicit», чем в конструкторах и операторах преобразования, объявленных как «explicit».

tagged_bool

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

Вам придется сделать предварительное объявление класса-тэга, такого как «WithValidation_tag». Определение для него писать не нужно. Он используется для создания уникальной специализации шаблона класса tagged_bool. Эта специализация может быть явно преобразована в bool и обратно, а также в другие специализации шаблона tagged_bool, поскольку, как обычно бывает на практике, какой-нибудь bool, передающийся на нижние уровни приложения, становится впоследствии другим флагом с другим именем. Использовать созданные таким образом флаги можно вот так:

Вот и все. tagged_bool — это часть библиотеки Explicit library, которая содержит несколько инструментов, позволяющих более явно выразить Ваши намерения при проектировании интерфейсов.

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

У Анджея ранее была другая статья про тэги — «Intuitive interface — Part I» от 5 июля 2013 г. (Part 2 так и не появилась на свет, не ищите). Если вкратце, то там поднималась такая проблема:

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

Что такое 5 и 6? Это будет 5 шестерок или 6 пятерок? Если забыли — идите смотреть документацию.

И хотелось бы иметь еще один конструктор, создающий пустой вектор с заданной capacity: std::vector v(100). К сожалению, конструктор, принимающий один size_t, уже занят — он создает вектор с заданным size’ом, заполненный сконструированными по умолчанию объектами.

Анджей упоминает, что такой порядок вещей не дает в полной мере воспользоваться возможностями прямой передачи, но в комментариях ему разъяснили, что эта проблема решается без всяких тэгов.

Анджей пришел к выводу, что реализация вектора в библиотеке STL не вполне удачная. Было бы куда проще, если бы в его конструкторах использовались тэги:

Применительно к настоящей статье, это выглядело бы так:

Разница в том, что тэг и значение теперь объединены в один объект. В статье «Competing constructors» от 29 июля 2016 г. Анджей мимоходом написал, что ему не нравится идея такого объединения.

Теперь это уже не тэги, а полноценные объекты. Кому-нибудь может прийти в голову положить их в контейнер:

Поведение этого кода опять зависит от формы скобочек. Что за радость была вводить тэги, если мы снова вернулись к той же проблеме? По крайней мере, простые тэги вряд ли кому-нибудь захочется хранить в контейнере. Ведь они могут иметь только одно значение.

С bool, однако, эта угроза не так страшна. Конструкторы контейнеров STL не принимают bool, иначе как в составе initializer_list’ов. Видимо, поэтому Анджей и решился в этот раз объединить тэг и значение.

Напоследок приведу перевод нескольких комментариев к статье.

Комментарии

kszatan
February 17, 2017 at 11:36 am
Я бы в первую очередь подумал об избавлении от всех этих флагов и вывел бы код для подтверждений (validations) и нового/старого движка (new/old engine) в отдельные классы, чтобы передавать их как аргументы. Функция «process» и так уже делает слишком много.

Andrzej Krzemieński
February 17, 2017 at 12:03 pm
В простых случаях отказ от любых флагов действительно может оказаться лучшим выбором. Но когда решение установить флаг принимается несколькими уровнями выше в стеке вызовов, такой рефакторинг может оказаться неосуществимым или непрактичным.

micleowen
February 17, 2017 at 10:41 pm

«explicit» используется в конструкторах с одним параметром.

Andrzej Krzemieński
February 20, 2017 at 8:22 am

ARNAUD
February 18, 2017 at 6:39 pm

«Неявные преобразования в bool и обратно не работают (и это хорошо), но явные преобразования тоже не работают, и это проблема»

Не понимаю, что в этом плохого:

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

И еще. Представьте, что через какое-то время один из параметров перестанет быть bool и сможет принимать значения no_engine, engine_v1, engine_v2… Класс перечисления позволяет сделать такое расширение естественным путем, в отличие от Вашего tagged_bool.

Andrzej Krzemieński
February 20, 2017 at 8:36 am

Вы подняли два вопроса.

И, в случае использования пространств имен:

Для меня это компромисс между желаемым уровнем безопасности и удобством использования. Мой личный выбор — что-то безопаснее bool, но не такое многословное как классы перечислений. Видимо, Ваш компромисс лежит ближе к классам перечислений.

2. Возможность добавить третье состояние

Если Вы предвидите, что в будущем Вам может понадобиться третье состояние, то классы перечислений и правда могут быть предпочтительнее. А могут и не быть. Потому что, когда Вы добавляете третье состояние, все Ваши if’ы продолжают исправно компилироваться, хотя Вы, может быть, желаете их отредактировать, чтобы добавить проверку третьего состояния.

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

mftdev00
March 13, 2017 at 1:05 pm

Я вообще не люблю флаги. Они противоречат принципу единственной ответственности. Делай что-то, если true, делай что-то другое, если false…

Andrzej Krzemieński
March 13, 2017 at 1:10 pm

Согласен. Везде, где это возможно, нужно обходиться без флагов.

SebB
March 21, 2017 at 6:09 pm

Можно ли вместо явного удаления конструкторов для каждого типа:

…просто удалить их для всех типов (кроме bool) разом?

Andrzej Krzemieński
March 22, 2017 at 7:32 am

Я просто не учел такую возможность, когда разрабатывал интерфейс. Может, и полезно было бы это добавить. Но теперь, когда Вы это предложили, я вижу один случай, где это имело бы отрицательный эффект: кто-то может использовать свой собственный (безопасный) логический тип с неявным преобразованием в bool. В этом случае, нам, может быть, нужно позволить этому типу работать с tagged_bool.

Источник

Персональная страничка
Диканева Тараса
Викторовича

7.1. Переменные-флаги: теория

Флаг – это полотнище правильной (как правило, прямоугольной) формы прикрепленное к древку или поднимаемое на специальной мачте (флагштоке). Исторически флаги появились для передачи простых сигналов на поле боя. Например: подняли флаг, и конница понеслась в атаку! Как-то так. В простейшем случае с помощью флага передается информация объемом 1 бит (одно из двух: флаг поднят или нет).

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

1) Подводится баланс коммерческого предприятия. Дальнейшие действия могут зависеть от того, будет он положительным или отрицательным. Если отрицательный, надо просить кредит, положительный – планировать отдых на Багамах. В общем, самая существенная информация может быть передана одним битом.

2) Решаем квадратное уравнение. Если дискриминант не отрицательный – ищем корни. Для хода вычислительного важен факт не отрицательности, который также содержит 1 бит информации и может, таким образом, быть сохранен с помощью логической переменной.

3) Детям на уроке физкультуры велено построиться по росту. Если они построились не по росту, надо на них наорать. Опять действия учителя зависят от информации объемом 1 бит.

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

Пример 1. Решение квадратного уравнения.

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

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

Зачем использовать еще одну переменную? Давайте вспомним, что второй программист ничего не знает о квадратных уравнениях и в частности не в курсе, что наличие корней определяется знаком дискриминанта. Не вдаваясь в тонкости чужой задачи, он просто просит первого программиста передать существенную информацию, через переменную-флаг.

На таком простом примере, как решение квадратного уравнения трудно проникнутся ощущением полезности флагов. Я, пожалуй, соглашусь, что в данном случае флаг это лишнее. Однако, нетрудно представить себе более сложную задачу, где такой подход окажется полезным.

Представьте себе, что вам требуется написать программу размером несколько тысяч строк (это сравнительно небольшая программа). Есть единственный способ создавать программы такого размера – это разбиение решаемой задачи на подзадачи и написание отдельных блоков программы, решающих каждый свою подзадачу. Чтобы можно было сосредоточиться на решении отдельной подзадачи надо сделать их решение по возможности максимально независимым друг от друга. Для этого от одного блока к другому должно передаваться как можно меньше информации. Так что даже если программу пишет всего один человек, флаги облегчат его работу.

Как уже отмечалось, флаги минимизируют информацию, передаваемую между блоками. Так в примере с квадратным уравнением использование флага позволило передавать всего 1 бит вместо 8-ми байт, которые пришлось бы потратить на значение дискриминанта. Общий принцип здесь такой – чем меньше информации, тем труднее допустить ошибку. При разработке сложных программ поиск ошибок занимает больше времени, чем собственно их написание и любая возможность уменьшить вероятность их появления должна приветствоваться.

В дополнение еще один пример.

Пример 2. Проверка упорядоченности последовательности.

Пользователь вводит 10 чисел. Требуется проверить, упорядочены ли они по возрастанию, и передать эту информацию с помощью переменной флага.

Если очередное введенное число (x) будет меньше предыдущего (x2), то флаг примет значение false и сохранит это значение до конца цикла.

Блоки, передающие друг другу информацию с помощью флагов, не обязательно должны идти последовательно друг за другом. Можно представить себе ситуацию, когда один блок является составной частью другого. Например:

Пример 3: Найти все простые числа от 1 до N.

Число называется простым, если не делится ни на какое другое число кроме 1 и самого себя. Простейший алгоритм поиска таких чисел состоит в том, чтобы перебрать все числа и для каждого проверить наличие делителей. Поиск делителей можно мыслить себе как отдельный блок программы, результатом работы которого будет присваивание значения флаговой переменной.
Блок поиска простых чисел будет включать в себя блок проверки на наличие делителей.
Программную реализацию этого алгоритма выполните в качестве самостоятельного упражнения (см. задачу 7.1).

Не обязательно использовать в качестве флага именно логическую переменную. В принципе флагом может считаться любая переменная, принимающая небольшое количество возможных значений, каждое из которых характеризует тот или иной результат вычислительного процесса.
В примере с квадратным уравнением можно было бы предусмотреть еще одну ситуацию, когда a = 0, то есть уравнение не квадратное. Тогда для передачи информации в следующий блок можно использовать либо две переменные логического типа, либо одну, но принимающую три значения (в качестве таковой можно использовать, например, переменную целого типа).

Источник

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *