Подтвердить что ты не робот

Есть ли разница между && и & с bool (s)?

В С++ существует ли разница между выполнением && (логический) и & (побитно) между bool (s)?

bool val1 = foo();
bool val2 = bar();

bool case1 = val1 & val2;
bool case2 = val1 && val2;

Являются ли case1 и case2 идентичными, или если нет, как они отличаются друг от друга и почему вы выбираете один из них? Является побитовым и bools портативным?

4b9b3361

Ответ 1

стандарт гарантирует, что false преобразуется в ноль, а true преобразуется в целые числа:

4.7 Интегральные преобразования

...

Если тип назначения - bool, см. 4.12. Если тип источника - bool, значение false преобразуется в ноль, а значение true преобразуется в единицу.

Таким образом, эффект в примере, который вы даете, гарантированно будет таким же и будет на 100% переносимым.

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

Однако для булевых выражений expr1 и expr2 в общем случае неверно, что expr1 && expr2 совпадает с expr1 & expr2, потому что && выполняет оценку "короткого замыкания". То есть, если expr1 оценивается как false, expr2 даже не будет оцениваться. Это может повлиять на производительность (если expr2 является сложным) и поведение (если expr2 имеет побочные эффекты). (Но обратите внимание, что форма & может быть быстрее, если она избегает условной ветки... Играющая с такими вещами по соображениям производительности почти всегда плохая идея.)

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

По моему мнению, если вы специально не полагаетесь на поведение "короткого замыкания", вы должны выбрать формулировку, которая наиболее четко выражает ваше намерение. Поэтому используйте && для логических И и & для бит-twiddling AND, и любой опытный программист на С++ найдет, что ваш код легко следовать.

Ответ 2

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

На это полагается много кода C/С++/С#, например: if (p != null && p->Foo()).

В вашем примере я бы использовал case2 (логический и). Используйте только поразрядные операции с битовыми флагами и т.д.

Однако, если foo() и bar() возвращают только bool (0, 1), то case1 и case2 совпадают.

Ответ 3

Есть разница (ну, два), хотя вы не увидите ее в своем примере.

"&" выполняет поразрядную операцию "И", что означает 0x1 & 0x1 = 0x1, но 0x1 & 0x2 = 0x0. OTOH, && является логическим/логическим "И", означая, что он обрабатывает любое ненулевое значение как ИСТИННОЕ, поэтому 0x1 && 0x1 = TRUE (которое обычно представляется как -1, т.е. все [или, возможно, оно представлено как 1 в С++, я забываю ]), а 0x1 && 0x2 = TRUE.

Кроме того, "& &" является короткозамкнутым, что означает, что если первый операнд FALSE, второй не будет оцениваться. Итак, пока FALSE & null_pointer->booleanField ==> null pointer exception, FALSE && null_pointer->booleanField = FALSE.

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

Ответ 4

Алгоритмически нет никакой разницы, однако использование && позволяет вам "закоротить" чек. То есть, чтобы решить case2, если val1 является ложным, тогда скомпилированный код не имеет никакого смысла проверять значение val2, чтобы определить ответ, где case1 требует фактического выполнения AND.

Реально, хороший компилятор распознает это и создаст тот же код... он сводится к тому, насколько хорош ваш компилятор.

Ответ 5

" &" является "условным логическим" И " он оценивает второе выражение ТОЛЬКО, если первый имеет значение TRUE

" &" является "не условным логическим И" < - (если вы играете с булевыми выражениями) он оценивает как выражение


ПОМИМО "& Амп;" является "поразным" оператором, что означает, что он работает на уровне бит.

В этом примере вы можете лучше понять.

4 = 00000100  // 'four' bit set
5 = 00000101  // 'four' bit and 'one' bit set

00000100 (4) & // AND: only keep bits set in both
00000101 (5)
--------
00000100 (4)

00000100 (4) | // OR: keep bits set in either
00000101 (5)
--------
00000101 (5)

00000100 (4) ^ //  EXCLUSIVE OR: keep bits only set in one but not the other
00000101 (5)
--------
00000001 (1)

Ответ 6

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

Оператор || соответствует логической логической операции OR. Эта операция возвращает значение true, если один из двух операндов истинен, поэтому он является ложным только тогда, когда оба операнда сами являются ложными.

Ответ 7

int a = 0, b = 10;

if(a == 1 && (b/a) == 0) cout << "This is okay\n"; // the 2nd expression is never checked as the first one is false

cout << "Bingo\n";

if(a == 1 & (b/a) == 0) cout << "This is not okay\n"; // program crashes here trying to divide by zero

cout << "Bingo\n"; // this will never get printed