Как зайти в Даркнет?!
25th January, 01:11
5
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
893
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
912
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4350
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4395
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
C# логический порядок и поведение компилятора
В C#, (и не стесняйтесь отвечать за другие языки), в каком порядке среда выполнения оценивает логический оператор?
Пример:
DataTable myDt = new DataTable();
if (myDt != null && myDt.Rows.Count > 0)
{
//do some stuff with myDt
}
Какое утверждение делает во время выполнения оценки первого -
myDt != null
или:
myDt.Rows.Count > 0
?
Есть ли время, когда компилятор будет когда-либо оценивать оператор назад? Возможно, когда задействован оператор "OR"?
& известен как логический побитовый оператор и всегда вычисляет все вложенные выражения
Каков хороший пример использования побитового оператора вместо "короткого замыкания логического"?
"C#: слева направо, и обработка останавливается, если найдено совпадение (оценивается как true)."
Зомби-овца ошибается,не хватает репутации, чтобы ее опустить.
Вопрос заключается в операторе &&, а не в операторе||.
В случае && оценка остановится, если будет найден FALSE.
В случае || оценка останавливается, если найден TRUE.
Я понимаю, что на этот вопрос уже дан ответ, но я хотел бы добавить еще немного информации, которая имеет отношение к этой теме.
В таких языках, как C++, где вы можете фактически перегружать поведение операторов && и||, настоятельно рекомендуется этого не делать . Это происходит потому, что когда вы перегружаете это поведение, вы в конечном итоге заставляете оценивать обе стороны операции. Это делает две вещи:
- Это нарушает механизм ленивой оценки, потому что перегрузка-это функция, которая должна быть вызвана, и поэтому оба параметра оцениваются перед вызовом функции.
- Порядок оценки указанных параметров не гарантирован и может быть определен компилятором. Следовательно, объекты не будут вести себя так же, как в примерах, перечисленных в вопросе/предыдущих ответах.
Для получения дополнительной информации прочтите книгу Скотта Мейерса " более эффективный C++". Ваше здоровье!
vb.net
if( x isNot Nothing AndAlso x.go()) then
- Оценка производится слева направо
- Оператор AndAlso удостоверяется, что только если левая сторона была TRUE, то правая сторона будет оценена (очень важно, так как ifx ничего x.go не даст сбой)
Вы можете использовать и вместо ofAndAlso в vb. в этом случае левая сторона также будет оценена первой, но правая сторона будет оценена независимо от результата.
Лучшая практика: всегда используйте AndAlso, если только у вас нет очень веской причины этого не делать.
Его спросили в последующем, почему или когда кто-то будет использовать и вместо AndAlso (или & вместо &&): вот пример:
if ( x.init() And y.init()) then
x.process(y)
end
y.doDance()
В этом случае я хочу инициализировать как X, так и Y. Y должен быть инициализирован, чтобы y.DoDance мог выполняться. Однако в функции init() я делаю также некоторые дополнительные вещи, такие как проверка того, что сокет открыт, и только если это работает нормально , для обоих я должен идти вперед и делать x.process(y).
Опять же, это, вероятно, не нужно и не элегантно в 99% случаях, поэтому я сказал, что по умолчанию следует использовать AndAlso .
@shsteimer
Понятие скромности относится к перегрузке оператора. в заявлении: ... Сначала вычисляется значение A, если оно равно false, то B никогда не вычисляется. То же самое относится и к
Это не перегрузка оператора. Перегрузка операторов-это термин, используемый для определения пользовательского поведения операторов, таких как *, +, = и так далее.
Это позволит вам написать свой собственный класс 'Log', а затем сделать
a = new Log(); // Log class overloads the + operator
a + "some string"; // Call the overloaded method - otherwise this wouldn't work because you can't normally add strings to objects.
Делающий это
a() || b() // be never runs if a is true
на самом деле это называется оценка короткого замыкания
ZombieSheep находится в тупике. Единственное, что может ожидать "gotcha", это то, что это верно только в том случае, если вы используете оператор &&. При использовании оператора & оба выражения будут вычисляться каждый раз, независимо от того, является ли одно или оба значения равными false.
if (amHungry & whiteCastleIsNearby)
{
// The code will check if White Castle is nearby
// even when I am not hungry
}
if (amHungry && whiteCastleIsNearby)
{
// The code will only check if White Castle is nearby
// when I am hungry
}
Обратите внимание, что существует разница между && и & относительно того, сколько вашего выражения оценивается.
&& известен как короткозамкнутое логическое выражение AND, и, как отмечают здесь другие, остановится рано, если результат может быть определен до того, как будут вычислены все вложенные выражения.
& известен как логический побитовый оператор и всегда будет вычислять все вложенные выражения.
По существу:
if (a() && b())
Вызовет только b , Если a возвращает true .
тем не менее, это:
if (a() & b())
Всегда будет вызывать как a , так и b, даже если результат вызова a ложен и поэтому известен как ложь независимо от результата вызова B.
Это же различие существует и для операторов || и|.
В некоторых языках есть интересные ситуации, когда выражения выполняются в другом порядке. Я специально думаю о Ruby, но я уверен, что они заимствовали его из другого места (вероятно, Perl).
Выражения в логике останутся слева направо, но например:
puts message unless message.nil?
Выше будет дана оценка "message.nil?"во-первых, затем, если он вычисляется как false (если это не похоже на if except, то он выполняется, когда условие false вместо true), "puts message" будет выполняться, что выводит содержимое переменной message на экран.
Иногда это довольно интересный способ структурировать свой код... Лично мне нравится использовать его для очень коротких лайнеров 1, как описано выше.
Редактировать:
Чтобы сделать это немного яснее, вышеизложенное то же самое, что и:
unless message.nil?
puts message
end
Понятие скромности относится к перегрузке оператора. в заявлении:
if( A && B){
// do something
}
Сначала вычисляется значение A, если оно равно false, то B никогда не вычисляется. То же самое относится и к
if(A || B){
//do something
}
Сначала вычисляется A,если он принимает значение true, то B никогда не вычисляется.
Это понятие, перегрузка, относится (я думаю)ко всем языкам стиля C, а также ко многим другим.
Каков хороший пример того, когда следует использовать побитовый оператор вместо "короткозамкнутого булева"?
Каков хороший пример того, когда следует использовать побитовый оператор вместо "короткозамкнутого булева"?
Предположим, у вас есть флаги, скажем, для атрибутов файлов. Предположим, что вы определили READ как 4, WRITE как 2 и EXEC как 1. В двоичном коде это так:
READ 0100
WRITE 0010
EXEC 0001
Каждый флаг имеет один битный набор, и каждый из них уникален. Побитовые операторы позволяют объединить эти флаги:
flags = READ & EXEC; // value of flags is 0101
Когда все идет по плану, они исполняются left-to-right.
Когда вещи вложены, они выполняются inner-to-outer. Это может показаться запутанным, так как обычно то, что "innermost" находится на правой стороне линии, поэтому кажется, что это происходит в обратном направлении...
Например
a = Foo( 5, GetSummary( "Orion", GetAddress("Orion") ) );
Все происходит вот так:
- Вызов
GetAddressс литералом"Orion" - Вызов
GetSummaryс литералом"Orion"и результатомGetAddress - Вызовите
Fooс литералом5и результатомGetSummary - Присвоить это значение
a
Мне нравятся ответы Ориона. Я добавлю две вещи:
- left-to-right все еще применяется в первую очередь
- В inner-to-outer, чтобы убедиться, что все аргументы вычисляются до вызова функции
Допустим, у нас есть следующий пример:
a = Foo(5, GetSummary("Orion", GetAddress("Orion")),
GetSummary("Chris", GetAddress("Chris")));
Вот порядок исполнения приговора:
GetAddress("Orion")GetSummary("Orion", ...)GetAddress("Chris")GetSummary("Chris", ...)Foo(...)- Присваивает значение
a
Я не могу говорить о юридических требованиях C#'s (хотя я тестировал аналогичный пример с использованием Mono перед написанием этого поста), но этот порядок гарантирован в Java.
И просто для полноты (поскольку это также языковая нить-агностик), существуют языки, такие как C и C++, где порядок не гарантирован, если нет точки последовательности. Список литературы: 1, 2 . Однако при ответе на вопрос потока && и || являются точками последовательности в C++ (если только они не перегружены; Также см. Отличный ответ OJ). Итак, несколько примеров:
foo() && bar()foo() & bar()
В случае && foo() гарантированно выполняется до bar() (если последний вообще выполняется), так как && является точкой последовательности. В случае & такая гарантия не предоставляется (в C и C++), и действительно bar() может работать до foo() или наоборот.
Язык программирования D действительно делает оценку left-to-right с коротким замыканием и не допускает перегрузки операторов && и '||' .
@csmba :
Его спросили в последующем, почему или когда кто-то будет использовать и вместо AndAlso (или & вместо &&): вот пример:
if ( x.init() And y.init()) then x.process(y) end y.doDance()В этом случае я хочу инициализировать как X, так и Y. Y должен быть инициализирован, чтобы y.DoDance мог выполняться. Однако в функции init() я делаю также некоторые дополнительные вещи, такие как проверка того, что сокет открыт, и только если это работает нормально, для обоих я должен идти вперед и делать x.process(y).
Я считаю, что это довольно запутанно. Хотя ваш пример работает, это не типичный случай для использования And (и я, вероятно, напишу это по-другому, чтобы сделать его более ясным). And ( & в большинстве других языков) на самом деле является побитовой операцией-и. Вы можете использовать его для вычисления битовых операций, например удаления бита флага или маскировки и тестирования флагов:
Dim x As Formatting = Formatting.Bold Or Formatting.Italic
If (x And Formatting.Italic) = Formatting.Italic Then
MsgBox("The text will be set in italic.")
End If
Вы используете &, когда конкретно хотите оценить все вложенные выражения, скорее всего, потому, что они имеют побочные эффекты, которые вы хотите, даже если конечный результат будет ложным и, таким образом, не выполнит вашу тогдашнюю часть вашего if-оператора.
Обратите внимание, что & и | работает как для битовых масок, так и для логических значений, а не только для битовых операций. Они называются побитовыми, но они определены как для целых чисел, так и для булевых типов данных в C#.