Сравнение типов данных bool в С++
Тип данных bool
обычно представлен как 0
(как false
) и 1
(как true
). Однако некоторые говорят, что true
значения могут быть представлены значением, отличным от 1
. Если последнее утверждение true
, то следующее выражение может быть неверным.
bool x = 1;
if (x==1)
Do something..
Мне интересно, будут ли следующие утверждения работать как обычно и ожидаемо на часто используемых компиляторах.
-
bool x = 1;
if (x==1)
Do something.
-
bool y = 0;
if (y>0.5)
Do something..
-
bool z = 1;
if(z>0.5)
Do something...
Ответы
Ответ 1
§ 4.5 стандарта C++ гласит:
Значение типа bool может быть преобразовано в значение типа int, при этом значение false становится равным нулю, а значение true становится единым.
в отношении 2 и 3 происходит преобразование типов, поэтому операторы будут работать так, как нужно
Ответ 2
Согласно правилу булевых преобразований:
Значение целочисленного типа с перечислением с плавающей точкой, с незаданной областью, указатель и указатель на член может быть преобразовано в значение типа bool
.
Нулевое значение (для целочисленного значения, перечисления с плавающей точкой и перечисления с незаданной областью), а также нулевой указатель и нулевые значения указателя на член становятся false
. Все остальные ценности становятся true
.
затем
bool x = 1; // x will be true
bool y = 0; // y will be false
bool z = 1; // z will be true
Для 1-го случая, if (x==1)
, x
будет повышен до int
,
тип bool
могут быть преобразованы в int
со значением false
становится 0
и true
становится 1
.
тогда (x==1)
true
.
Во втором случае, if (y>0.5)
, y
будет повышен до int
со значением 0
, а затем преобразован в double
для сравнения;
Если операнды имеют арифметический или перечислимый тип (с областью или без области), обычные арифметические преобразования выполняются для обоих операндов в соответствии с правилами для арифметических операторов. Значения сравниваются после преобразования:
а также
Если операнд, переданный арифметическому оператору, является целочисленным или незаданным типом перечисления, то перед любым другим действием (но после преобразования lvalue в rvalue, если применимо) операнд подвергается интегральному продвижению.
...
- В противном случае, если один из операндов является
double
, другой операнд преобразуется в double
тогда y>0.5
false
.
В третьем случае, if (z>0.5)
, z
будет повышен до int
со значением 1
, а затем для сравнения будет преобразован в double
; тогда z>0.5
true
.
Ответ 3
if (x==1)
не является неправильным. Все представления истинных значений преобразуются в 1 при преобразовании логического значения в числовой тип.
При условии, что bool z=true
, if(z>0.5)
будет true, потому что 1.0 больше 0.5.
Ответ 4
bool
имеет только два значения, и они являются true
и false
. 1
и 0
- целочисленные литералы, поэтому они могут быть преобразованы в bool
. Вы должны учитывать, что преобразование работает в обоих направлениях, но вы не обязательно получите одно и то же целое число:
int a = 5;
bool b = a; // int -> bool conversion
int c = b; // bool -> int conversion
std::cout << a << " " c;
печатает:
5 1
Любое целое значение, отличное от 0
преобразуется в true
, но true
всегда преобразуется в 1
.
Имея это в виду, все ваши примеры будут работать как положено. Тем не менее, обратите внимание, что основная цель bool
состоит в том, что мы можем использовать true
и false
в нашем коде вместо того, чтобы давать числа в виде 0
и 1
специального значения. Всегда лучше быть явным, поэтому, когда вы имеете в виду true
, лучше написать true
не 1
.
Ответ 5
- Если вы приведете bool к int, значение
true
будет равно 1, так что это сработает. - Когда вы преобразуете bool в int (и удваиваете), вы получите '0.0', так что это не будет хорошо.
- Когда вы преобразуете bool в int (и удваиваете), вы получите '1.0', так что все будет в порядке.
Вы должны использовать static_cast<int>(bool)
или (int)bool
.
Но эти сравнения бессмысленны и вызывают много ошибок.