Две булевские переменные могут быть сравнены в C++?

Следующая часть кода предположена работать?

bool b1 = true;
bool b2 = 1 < 2;
if (b1 == b2)
{
// do something
}

Я подозреваю, что не все 'trues' равны.

7
задан Daniel Daranas 2 June 2010 в 12:25
поделиться

7 ответов

Да. Все треи равали.

19
ответ дан 6 December 2019 в 05:01
поделиться

В C с int s вы можете быть правы (хотя даже здесь я думаю, что эта конкретная последовательность будет в порядке). В C ++ - да, это безопасно.

1
ответ дан 6 December 2019 в 05:01
поделиться

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

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

Взгляните на следующий (плохой) пример:

  bool b1 = true; 
  bool b2 = true; 
  *((char*)&b1) = 3;

  if( b1 ) cout << "b1 is true" << endl;
  if( b2 ) cout << "b2 is true" << endl;
  if (b1 != b2) cout << "b2 is not equal to b1" << endl;

On Visual Studio 9, он показывает:

b1 is true

b2 is true

b2 is not equal to b1

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

11
ответ дан 6 December 2019 в 05:01
поделиться

Да, как говорили другие, bools можно сравнить на равенство в C ++. Возможно, вы думаете о том, что слышали от К.Поскольку C не имеет типа bool, логические значения представлены как целые числа. В логическом контексте любое ненулевое целое число истинно. Однако они могут иметь разные битовые комбинации и, следовательно, не быть равными. Таким образом, правилом C было не сравнивать «булевы».

Изменить: согласно комментариям, C99 имеет тип bool. Однако суть ответа заключалась в том, чтобы указать , почему идея не сравнивать булевые значения витает в воздухе. Он основан на долгой истории C до C99.

7
ответ дан 6 December 2019 в 05:01
поделиться

Когда вы присваиваете целое значение логическому объекту (или инициализируете логический объект целым значением), оно неявно преобразуется в истину или false стандартным логическим преобразованием (4.12). Итак, с точки зрения языка ваши 1 и 2 бесследно пропали задолго до того, как вы даже проведете сравнение. Они оба стали одной и той же истиной . Здесь нет проблемы «все истины равны». Есть только одно истинное .

Конечно, какой-нибудь компилятор, вероятно, может применить «ленивый» подход и сохранить несколько разных «истин», убедившись, что они «все равны» в момент сравнения и тому подобное, но я сомневаюсь, что это разумный / жизнеспособный подход.

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

bool b1 = true; 
bool b2 = 1 < 2;
if (memcmp(&b1, &b2, sizeof(bool)) == 0) {
  /* We should get in here */
}

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

2
ответ дан 6 December 2019 в 05:01
поделиться

В C ++ bool - это отдельный тип с двумя возможными значениями true и false . Все сравнения пройдут так, как вы ожидаете. Все логические значения true - это одно и то же, и то же самое со всеми false . Это правда, что не все выражения, которые можно оценить как истина или ложь , одинаковы.

В C89, возвращаясь настолько далеко, насколько я хочу, любое нулевое значение (любого указателя или числового типа) ложно, а все остальное - истина. Это означает, что истинные значения не обязательно равны друг другу. 1 и 2 являются истинными значениями, но 1! = 2 , а 1 & 2 оценивается как 0, что неверно.

Также возможно, что ложные значения C89 не будут сравниваться равными, хотя они будут в каждой реализации, которую я когда-либо использовал. Значение нулевого указателя - это постоянное целочисленное преобразование нуля к значению указателя. Возможно, что непостоянное значение 0, приведенное к значению указателя, не будет нулевым указателем (и были системы, где нулевые указатели не все были битами 0). Следовательно, (void *) 0 является значением нулевого указателя и, следовательно, ложным, но int i; ... i = 0; ... (void *) i возможно не быть значением нулевого указателя и, следовательно, не является ложным.

Однако в C89 все операции, которые предназначены для возврата логического значения (например, && или == ]), будут возвращать 1 или 0, так что (1 == 3) == (4 == 3) .

1
ответ дан 6 December 2019 в 05:01
поделиться

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

Представьте себе:

У вас есть функция keyPressed (), которая возвращает 0, если ни одна клавиша не нажата, номер клавиши, когда клавиша нажата.

Вы написали простой переключатель в цикле:

if(keyPressed() && allow)
...

Теперь ваша компания вводит в устройства нормально открытые триггеры, и вам нужен преф.

bool key_switches_on = getPref("KeySwitchesOn");

if((keyPressed() && allow) == key_switches_on)
...

Затем вы замечаете, что "разрешить" размещено неправильно ...

if((keyPressed() == key_switches_on) && allow)

и внезапно работает только ключ номер 1.

0
ответ дан 6 December 2019 в 05:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: