Флаг, бинарный флаг — что это в программировании
Флагом в программировании часто называют переменную, которая может принимать только одно из двух значений:
- или «да» (говорят «флаг поднят»)
- или «нет» (говорят «флаг опущен»)
— то есть по аналогии с сигнальным флагом на корабле (когда он поднят это значит что-то одно, а когда нет — что-то другое).
В некоторых языках программирования для экономии памяти в качестве флага можно использовать значение логического типа (напр. типа boolean в Паскале).
Переменные-флаги
В старые времена с помощью флагов командовали войсками. Например, если флаг поднят — нужно атаковать, опущен — отступать.
В программировании “флагом” называют переменную булевого типа, т.е. в которой хранится либо True , либо False . Их так называют потому, что управление с их помощью похоже на флаги: есть всего 2 варианта, флаг или поднят, или опущен.
Например, вам интересно, есть ли человек на видео. Вы пишете функцию, которая проходит по кадрам видео и проверяет каждый из них. Если найдёт человека, то сообщит об этом:
def check_human_in_video(video): human_found = False for frame in video: if frame.has_human(): human_found = True print(human_found)
Обратите внимание, что True и False написаны без кавычек! Так и задумано — это не строки, а отдельный тип данных.
По умолчанию считаем, что человека нет, поэтому создаём флаг human_found = False . Далее для каждого кадра в видео проверяем, есть ли на нём человек — вызываем метод объекта frame.has_human() . Если человек найден, то меняем флаг на True . В конце выводим флаг с помощью print .
Если ни на одном кадре человек не найдётся, то флаг так и останется False , потому что условие if frame.has_human() ни разу не сработает.
Если хоть на одном кадре есть человек, то при обработке этого кадра сработает условие if frame.has_human() и флаг станет True .
Как улучшить код
Теперь усовершенствуем код. Функция станет удобнее, если откажется от вывода на экран в пользу return .
def is_human_in_video(video): human_found = False for frame in video: if frame.has_human(): human_found = True return human_found print(is_human_in_video(video))
Следующим шагом ускорим работу функции. Сейчас код продолжит проверку, даже если встретит человека на самом первом кадре видео. Если кадров в video будет много, то проверка займёт время. Это даёт возможность для оптимизации. Прервём проверку сразу, как только станет ясен результат:
def is_human_in_video(video): human_found = False for frame in video: if frame.has_human(): human_found = True return human_found return human_found print(is_human_in_video(video))
Теперь заметно, что от переменной human_found можно избавиться, сделав код немного лаконичнее:
def is_human_in_video(video): for frame in video: if frame.has_human(): return True return False print(is_human_in_video(video))
Но и это ещё не всё. Флаги являются таким частым приёмом, что они попали в стандартную библиотеку Python. Код выше можно записать в одну строку:
def is_human_in_video(video): return any(frame.has_human() for frame in video)
- Про функцию any
- Что такое list comprehension?
Попробуйте бесплатные уроки по Python
Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.
Переходите на страницу учебных модулей «Девмана» и выбирайте тему.
7. Переменные-флаги
Флаг – это полотнище правильной (как правило, прямоугольной) формы прикрепленное к древку или поднимаемое на специальной мачте (флагштоке). Исторически флаги появились для передачи простых сигналов на поле боя. Например: подняли флаг, и конница понеслась в атаку! Как-то так. В простейшем случае с помощью флага передается информация объемом 1 бит (одно из двух: флаг поднят или нет). Переменная флаг – это, как правило, переменная логического типа, значение которой сигнализирует о состоянии вычислительного процесса. Приведем несколько примеров, когда результат может характеризоваться всего одной логической переменной: 1) Подводится баланс коммерческого предприятия. Дальнейшие действия могут зависеть от того, будет он положительным или отрицательным. Если отрицательный, надо просить кредит, положительный – планировать отдых на Багамах. В общем, самая существенная информация может быть передана одним битом. 2) Решаем квадратное уравнение. Если дискриминант не отрицательный – ищем корни. Для хода вычислительного важен факт не отрицательности, который также содержит 1 бит информации и может, таким образом, быть сохранен с помощью логической переменной. 3) Детям на уроке физкультуры велено построиться по росту. Если они построились не по росту, надо на них наорать. Опять действия учителя зависят от информации объемом 1 бит. Но кто и кому может передавать информацию в ходе выполнения программы? Дело в том, что при разработке больших программ происходит разделение задачи на более мелкие подзадачи (блоки), каждая из которых решается отдельно и, может быть даже, разными людьми. В этом случае один блок, закончив свою работу должен передать ее результат другому блоку. Здесь и могут пригодиться флаги. Пример 1. Решение квадратного уравнения. Предположим, что программу решения квадратного уравнения пишут два человека (ну, можно же). Пусть первый умеет решать квадратные уравнения, но не знает, как вывести результат (не ходил на лекции). Второй знает, как вывести результат, но про квадратные уравнения слышит первый раз в жизни. Попробуем представить, какую программу они напишут.
var a, b, c: real; d: real; x1, x2: real; RootsExist: boolean; begin readln(a, b, c); d := sqr(b)-4*a*c; RootsExist := (d>=0); if RootsExist then begin x1:=(-b+sqrt(d))/(2*a); x2:=(-b-sqrt(d))/(2*a); end; if RootsExist then writeln(x1, x2) else writeln('Roots don’t exist'); end.
Переменная-флаг передает информацию о наличии корней. С ее помощью первый блок сигнализирует второму блоку. Вы скажете, почему бы второму программисту вместо строчки
if RootsExist then
не написать
if d>=0 then
Зачем использовать еще одну переменную? Давайте вспомним, что второй программист ничего не знает о квадратных уравнениях и в частности не в курсе, что наличие корней определяется знаком дискриминанта. Не вдаваясь в тонкости чужой задачи, он просто просит первого программиста передать существенную информацию, через переменную-флаг. На таком простом примере, как решение квадратного уравнения трудно проникнутся ощущением полезности флагов. Я, пожалуй, соглашусь, что в данном случае флаг это лишнее. Однако, нетрудно представить себе более сложную задачу, где такой подход окажется полезным. Представьте себе, что вам требуется написать программу размером несколько тысяч строк (это сравнительно небольшая программа). Есть единственный способ создавать программы такого размера – это разбиение решаемой задачи на подзадачи и написание отдельных блоков программы, решающих каждый свою подзадачу. Чтобы можно было сосредоточиться на решении отдельной подзадачи надо сделать их решение по возможности максимально независимым друг от друга. Для этого от одного блока к другому должно передаваться как можно меньше информации. Так что даже если программу пишет всего один человек, флаги облегчат его работу. Как уже отмечалось, флаги минимизируют информацию, передаваемую между блоками. Так в примере с квадратным уравнением использование флага позволило передавать всего 1 бит вместо 8-ми байт, которые пришлось бы потратить на значение дискриминанта. Общий принцип здесь такой – чем меньше информации, тем труднее допустить ошибку. При разработке сложных программ поиск ошибок занимает больше времени, чем собственно их написание и любая возможность уменьшить вероятность их появления должна приветствоваться. В дополнение еще один пример. Пример 2. Проверка упорядоченности последовательности. Пользователь вводит 10 чисел. Требуется проверить, упорядочены ли они по возрастанию, и передать эту информацию с помощью переменной флага. Решение:
Growing:=true; readln(x); for i:=2 to 10 do begin x2:=x; readln(x); Growing:=Growing and (x > x2); end;
Если очередное введенное число (x) будет меньше предыдущего (x2), то флаг примет значение false и сохранит это значение до конца цикла. Блоки, передающие друг другу информацию с помощью флагов, не обязательно должны идти последовательно друг за другом. Можно представить себе ситуацию, когда один блок является составной частью другого. Например: Пример 3: Найти все простые числа от 1 до N. Число называется простым, если не делится ни на какое другое число кроме 1 и самого себя. Простейший алгоритм поиска таких чисел состоит в том, чтобы перебрать все числа и для каждого проверить наличие делителей. Поиск делителей можно мыслить себе как отдельный блок программы, результатом работы которого будет присваивание значения флаговой переменной.
Блок поиска простых чисел будет включать в себя блок проверки на наличие делителей.
Программную реализацию этого алгоритма выполните в качестве самостоятельного упражнения (см. задачу 7.1). Не обязательно использовать в качестве флага именно логическую переменную. В принципе флагом может считаться любая переменная, принимающая небольшое количество возможных значений, каждое из которых характеризует тот или иной результат вычислительного процесса.
В примере с квадратным уравнением можно было бы предусмотреть еще одну ситуацию, когда a = 0, то есть уравнение не квадратное. Тогда для передачи информации в следующий блок можно использовать либо две переменные логического типа, либо одну, но принимающую три значения (в качестве таковой можно использовать, например, переменную целого типа). Следующий раздел:
Для чего нужны переменные флаги?
Я только недавно натолкнулся на этот термин, и я не понимаю для чего они нужны.
Я не уверен, когда использовать переменную флаг и как это сделать?
Если можно с примерами на Java. Спасибо.
boolean flag = false;
- Вопрос задан более трёх лет назад
- 11393 просмотра
3 комментария
Простой 3 комментария
gleendo @evgeniy8705
Вы про такие флаги говорите? boolean flag = false; или про JVM?
rraderio @rraderio Автор вопроса
gleendo @evgeniy8705
public boolean has(int key) < // Метод для проверки существования элемента например в списке boolean found = false; // Флаг, найден ли элемент или нет. По умолчанию не найден (false) if (find(key)) found = true; // Ищем элемент. Если находим то выставляем значение флага в true return found; // Возвращаем значение флага >
Решения вопроса 0
Ответы на вопрос 3
senior software developer
не нужно воспринимать флаги как что-то супер-специфическое или суперсложное
это не более чем обычная переменная которая влияет на поток программы
пример из жизни
вы программируете целый день на работе и вечером идете домой
допустим в течении дня может позвонить супруга и попросить зайти вечером в магазин (выставляет флаг ЗАЙТИ_В_МАГАЗИН = True)
в конце дня этот флаг проверяется — если он True — то мы зайдем в магаз, если нет — соответственно не зайдем
нюансы здесь:
— флаг может быть выставлен в ЛЮБОЕ время
— флаг не обязательно выставляете Вы сами!
— Ваша реакция на флаг не обязательно сиюминутная
— перед уходом домой лучше позвонить супруге и уточнить состояние флага 🙂
флаг не обязательно должен быть буленовской переменной, это понятие скорее логическое, например вместо флага ЗАЙТИ_В_МАГАЗИН (при котором не совсем понятно что покупать то) может использоваться более умная конструкция типа ArrayList списокПокупок = <>. Вначале дня список пустой, в течении дня жена вспоминает чтото — и дописывает вещи в спискоПокупок
в конце дня вы просто проверяете — пуст ли список (флага нет) — и тогда идете домой с чистой совестью
если же там есть хоть что-то (флаг поднят) — Вы уже знаете что 1) идти нужно 2) что именно нужно купить
Ответ написан более трёх лет назад
Комментировать
Нравится 4 Комментировать
Программист
Переменные флаги как правило глобальные переменные булевого типа и используется обычно для синхронизации выполнения подпрограмм в разных потоках. Понятие флаг установлен, флаг снят — эквивалентно true и false.