I just want to flip a boolean based on what it already is. If it’s true — make it false. If it’s false — make it true.
Here is my code excerpt:
switch(wParam) {
case VK_F11:
if (flipVal == true) {
flipVal = false;
} else {
flipVal = true;
}
break;
case VK_F12:
if (otherVal == true) {
otherValVal = false;
} else {
otherVal = true;
}
break;
default:
break;
}
0
You can flip a value like so:
myVal = !myVal;
so your code would shorten down to:
switch(wParam) {
case VK_F11:
flipVal = !flipVal;
break;
case VK_F12:
otherVal = !otherVal;
break;
default:
break;
}
6
Clearly you need a factory pattern!
KeyFactory keyFactory = new KeyFactory();
KeyObj keyObj = keyFactory.getKeyObj(wParam);
keyObj.doStuff();
class VK_F11 extends KeyObj {
boolean val;
public void doStuff() {
val = !val;
}
}
class VK_F12 extends KeyObj {
boolean val;
public void doStuff() {
val = !val;
}
}
class KeyFactory {
public KeyObj getKeyObj(int param) {
switch(param) {
case VK_F11:
return new VK_F11();
case VK_F12:
return new VK_F12();
}
throw new KeyNotFoundException("Key " + param + " was not found!");
}
}
</sarcasm>
answered Mar 4, 2009 at 16:56
6
Easiest solution that I found:
x ^= true;
8
If you know the values are 0 or 1, you could do flipval ^= 1
.
answered Mar 4, 2009 at 16:55
Mike DunlaveyMike Dunlavey
39.8k14 gold badges90 silver badges133 bronze badges
10
Just for information — if instead of an integer your required field is a single bit within a larger type, use the ‘xor’ operator instead:
int flags;
int flag_a = 0x01;
int flag_b = 0x02;
int flag_c = 0x04;
/* I want to flip 'flag_b' without touching 'flag_a' or 'flag_c' */
flags ^= flag_b;
/* I want to set 'flag_b' */
flags |= flag_b;
/* I want to clear (or 'reset') 'flag_b' */
flags &= ~flag_b;
/* I want to test 'flag_b' */
bool b_is_set = (flags & flag_b) != 0;
Boiethios
35.7k17 gold badges129 silver badges177 bronze badges
answered Mar 4, 2009 at 16:58
AlnitakAlnitak
332k70 gold badges404 silver badges490 bronze badges
Just because my favorite odd ball way to toggle a bool is not listed…
bool x = true;
x = x == false;
works too.
(yes the x = !x;
is clearer and easier to read)
This seems to be a free-for-all … Heh. Here’s another varation, which I guess is more in the category «clever» than something I’d recommend for production code:
flipVal ^= (wParam == VK_F11);
otherVal ^= (wParam == VK_F12);
I guess it’s advantages are:
- Very terse
- Does not require branching
And a just as obvious disadvantage is
- Very terse
This is close to @korona’s solution using ?: but taken one (small) step further.
answered Mar 5, 2009 at 7:56
unwindunwind
387k64 gold badges468 silver badges600 bronze badges
1
The codegolf’ish solution would be more like:
flipVal = (wParam == VK_F11) ? !flipVal : flipVal;
otherVal = (wParam == VK_F12) ? !otherVal : otherVal;
answered Mar 4, 2009 at 16:00
koronakorona
2,3101 gold badge24 silver badges37 bronze badges
0
flipVal ^= 1;
same goes for
otherVal
I prefer John T’s solution, but if you want to go all code-golfy, your statement logically reduces to this:
//if key is down, toggle the boolean, else leave it alone.
flipVal = ((wParam==VK_F11) && !flipVal) || (!(wParam==VK_F11) && flipVal);
if(wParam==VK_F11) Break;
//if key is down, toggle the boolean, else leave it alone.
otherVal = ((wParam==VK_F12) && !otherVal) || (!(wParam==VK_F12) && otherVal);
if(wParam==VK_F12) Break;
answered Mar 4, 2009 at 15:25
JosephStyonsJosephStyons
56.6k63 gold badges160 silver badges232 bronze badges
1
Clearly you need a flexible solution that can support types masquerading as boolean. The following allows for that:
template<typename T> bool Flip(const T& t);
You can then specialize this for different types that might pretend to be boolean. For example:
template<> bool Flip<bool>(const bool& b) { return !b; }
template<> bool Flip<int>(const int& i) { return !(i == 0); }
An example of using this construct:
if(Flip(false)) { printf("flipped falsen"); }
if(!Flip(true)) { printf("flipped truen"); }
if(Flip(0)) { printf("flipped 0n"); }
if(!Flip(1)) { printf("flipped 1n"); }
No, I’m not serious.
answered Mar 4, 2009 at 17:14
dmadma
1,73810 silver badges25 bronze badges
For integers with values of 0 and 1 you can try:
value = abs(value - 1);
MWE in C:
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Hello, World!n");
int value = 0;
int i;
for (i=0; i<10; i++)
{
value = abs(value -1);
printf("%dn", value);
}
return 0;
}
Just because I like to question code. I propose that you can also make use of the ternary by doing something like this:
Example:
bool flipValue = false;
bool bShouldFlip = true;
flipValue = bShouldFlip ? !flipValue : flipValue;
I have some checks to see if a screen is active. The code looks like this:
if (GUI.Button(new Rect(Screen.width / 2 - 10, 50, 50, 30), "Rules")) //Creates a button
{
if (ruleScreenActive == true) //check if the screen is already active
ruleScreenActive = false; //handle according to that
else
ruleScreenActive = true;
}
Is there any way to — whenever I click the button — invert the value of ruleScreenActive
?
(This is C# in Unity3D)
Tom Wright
11.2k15 gold badges77 silver badges146 bronze badges
asked Jan 18, 2012 at 15:04
Simon VerbekeSimon Verbeke
2,8457 gold badges35 silver badges55 bronze badges
2
You can get rid of your if/else statements by negating the bool’s value:
ruleScreenActive = !ruleScreenActive;
answered Jan 18, 2012 at 15:05
Ahmad MageedAhmad Mageed
93.2k18 gold badges162 silver badges172 bronze badges
5
I think it is better to write:
ruleScreenActive ^= true;
that way you avoid writing the variable name twice … which can lead to errors
answered Apr 21, 2013 at 7:49
6
ruleScreenActive = !ruleScreenActive;
answered Jan 18, 2012 at 15:05
MusiGenesisMusiGenesis
73.7k40 gold badges187 silver badges332 bronze badges
This would be inlined, so readability increases, runtime costs stays the same:
public static bool Invert(this bool val) { return !val; }
To give:
ruleScreenActive.Invert();
answered Apr 21, 2013 at 9:31
JackJack
4,5442 gold badges28 silver badges22 bronze badges
7
This can be useful for long variable names. You don’t have to write the variable name twice.
public static void Invert(this ref bool b) => b = !b;
Example:
bool superLongBoolVariableName = true;
superLongBoolVariableName.Invert()
answered Jul 10, 2022 at 13:18
I have some checks to see if a screen is active. The code looks like this:
if (GUI.Button(new Rect(Screen.width / 2 - 10, 50, 50, 30), "Rules")) //Creates a button
{
if (ruleScreenActive == true) //check if the screen is already active
ruleScreenActive = false; //handle according to that
else
ruleScreenActive = true;
}
Is there any way to — whenever I click the button — invert the value of ruleScreenActive
?
(This is C# in Unity3D)
Tom Wright
11.2k15 gold badges77 silver badges146 bronze badges
asked Jan 18, 2012 at 15:04
Simon VerbekeSimon Verbeke
2,8457 gold badges35 silver badges55 bronze badges
2
You can get rid of your if/else statements by negating the bool’s value:
ruleScreenActive = !ruleScreenActive;
answered Jan 18, 2012 at 15:05
Ahmad MageedAhmad Mageed
93.2k18 gold badges162 silver badges172 bronze badges
5
I think it is better to write:
ruleScreenActive ^= true;
that way you avoid writing the variable name twice … which can lead to errors
answered Apr 21, 2013 at 7:49
6
ruleScreenActive = !ruleScreenActive;
answered Jan 18, 2012 at 15:05
MusiGenesisMusiGenesis
73.7k40 gold badges187 silver badges332 bronze badges
This would be inlined, so readability increases, runtime costs stays the same:
public static bool Invert(this bool val) { return !val; }
To give:
ruleScreenActive.Invert();
answered Apr 21, 2013 at 9:31
JackJack
4,5442 gold badges28 silver badges22 bronze badges
7
This can be useful for long variable names. You don’t have to write the variable name twice.
public static void Invert(this ref bool b) => b = !b;
Example:
bool superLongBoolVariableName = true;
superLongBoolVariableName.Invert()
answered Jul 10, 2022 at 13:18
Noob.net Темная сторона .Net 592 / 489 / 39 Регистрация: 21.07.2012 Сообщений: 1,668 |
||||
1 |
||||
10.08.2012, 13:38. Показов 22676. Ответов 3 Метки нет (Все метки)
Ведь нету ф-и которая заменяет тру на фелс и наоборот?
0 |
Etrimus 398 / 365 / 54 Регистрация: 23.05.2010 Сообщений: 716 |
||||
10.08.2012, 13:41 |
2 |
|||
3 |
Темная сторона .Net 592 / 489 / 39 Регистрация: 21.07.2012 Сообщений: 1,668 |
|
10.08.2012, 13:42 [ТС] |
3 |
эх я
0 |
buntar 543 / 544 / 181 Регистрация: 16.03.2012 Сообщений: 1,160 Записей в блоге: 2 |
||||
10.08.2012, 13:42 |
4 |
|||
1 |
|
|
|
BOOL
, инвертировать значение
- Подписаться на тему
- Сообщить другу
- Скачать/распечатать тему
|
|
Рейтинг (т): нет |
Привет! Есть небольшой вопросик С типом bool я делала так: b=!b; Сообщение отредактировано: Marihuana — 06.11.09, 07:24 |
KILLER |
|
Аналогично и c BOOL |
ss |
|
Senior Member Рейтинг (т): 41 |
BOOL b = TRUE; b = !( (bool)b ); |
KILLER |
|
Цитата ss @ 06.11.09, 07:34 BOOL b = TRUE; а так что не скомпиллеца или работать будет неправильно? : BOOL b = TRUE; b = !b; |
ss |
|
Senior Member Рейтинг (т): 41 |
Всё ок, ты прав. Приводить к bool излишество. Но безопасное |
Marihuana |
|
Рейтинг (т): нет |
Что-то я совсем ступила Добавлено 06.11.09, 08:12 |
Masterkent |
|
Senior Member Рейтинг (т): 113 |
Значение у переменной типа bool можно инвертировать ещё и так: b ^= 1; Но в случае с BOOL так делать не стоит. |
ss |
|
Senior Member Рейтинг (т): 41 |
Masterkent, даже в случае с bool так делать не стоит, ибо, на мой взгляд, ухудшает читаемость кода и не даёт чёткого представления о намерениях. |
Marihuana |
|
Рейтинг (т): нет |
Никогда не видела такого интересного оператора b^=1. Проверила тоже работает! |
ss |
|
Senior Member Рейтинг (т): 41 |
Это XOR, побитовое исключающее ИЛИ, описание тут, например. ЗЫ, прошлый раз соврал насчёт значений, пардон. Сообщение отредактировано: ss — 06.11.09, 09:32 |
Marihuana |
|
Рейтинг (т): нет |
А понятно! Забыла, что оператор ^ означает XOR. Я с ним никогда не сталкивалась. |
Masterkent |
|
Senior Member Рейтинг (т): 113 |
Цитата ss @ 06.11.09, 08:57 на мой взгляд, ухудшает читаемость кода А на мой взгляд, читаемость кода ухудшает двойное указание модифицируемого объекта. Вместо b может быть имя подлиннее или вообще какое-нибудь сложное выражение. Цитата ss @ 06.11.09, 08:57 и не даёт чёткого представления о намерениях Это известный приём, и никаких затруднений в понимании такого кода быть не должно, IMHO. Впрочем, я справа от ^= обычно использовал true вместо 1. |
Bug Hunter |
|
Senior Member Рейтинг (т): 46 |
А вот так: b=b?0:1; не подойдет? |
Alek86 |
|
для bool как по мне идеал b ^= true; а BOOL вообще использовать, имхо, фигово. к примеру, никак не пойму, для чего вообще TRUE задефайнили (разве что для того, чтобы приколоться над программистами, что результат winapi функции на TRUE проверят) |
ss |
|
Senior Member Рейтинг (т): 41 |
Чо вы к этому XOR’у присохли? «b != b» чем не угодило? А ещё прикольно, что ПРАВДА для BOOL и VARIANT_BOOL — разная. Дополнительный источник для «странных» ошибок. |
0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
0 пользователей:
- Предыдущая тема
- C/C++: Общие вопросы
- Следующая тема
[ Script execution time: 0,0348 ] [ 16 queries used ] [ Generated: 10.02.23, 12:57 GMT ]
|
Инверсия переменной boolean в С/С++
|
07/10/15 |
Доброго времени суток уважаемые любители и профессиональные программисты. Дело в том, что нужно не просто присвоить конкретное значение, переменной, а проинвертировать его. Разумеется, предпочтительно сделать это через унарную операцию, и интуитивно, я предположил, что сделать это можно так но этот код, как на зло, не работает, элементы массива flag так всё время и остаются нулевыми, хотя при непосредственном присваивании значений они изменяются как положено. Подскажите, как правильно реализовать инверсию переменной boolean? — 09.03.2020, 18:25 — Вот так всё работает *(flag+id)=!(*(flag+id)); но неужели для этого нет унарного оператора?
|
|
|
arseniiv |
Re: Инверсия переменной boolean в С/С++
|
||
27/04/09 |
Нету. А зачем? (И зачем писать *(flag + id) вместо flag[id]? В одно и то же компилируется ведь.)
|
||
|
|||
mihaild |
Re: Инверсия переменной boolean в С/С++
|
||
16/07/14 |
|||
|
|||
Andrey_Kireew |
Re: Инверсия переменной boolean в С/С++
|
07/10/15 |
А зачем? Для удобства, по аналогии с унарным минусом. flag[id] ^= true Да, как один из вариантов. Но это уже xor а не not
|
|
|
mihaild |
Re: Инверсия переменной boolean в С/С++
|
||
16/07/14 |
по аналогии с унарным минусом. Унарный минус не модифицирует аргумент. Единственные модифицирующие угарные операторы — это инкремент и декремент.
|
||
|
|||
Andrey_Kireew |
Re: Инверсия переменной boolean в С/С++
|
07/10/15 |
Унарный минус не модифицирует аргумент Значит тоже ничего не даст? Этого я не знал, спасибо за информацию.
|
|
|
worm2 |
Re: Инверсия переменной boolean в С/С++
|
||
01/08/06 |
Ну вообще исторически интересный вопрос: почему существует, например, инкремент, но не существует аналогичный «синтаксический сахар» для других унарных операций? Вопрос не только к С, но и вообще ко всем языкам. Хотя к C, конечно, в первую очередь, ведь в системе команд PDP-11 (для которой этот язык изначально разрабатывался), наряду с унарной командой INC/DEC есть и другие унарные присваивающие команды: NEG, COM, …
|
||
|
|||
SergeCpp |
asm
|
10/10/18 |
Ну вообще исторически интересный вопрос: почему существует, например, инкремент, но не существует аналогичный «синтаксический сахар» для других унарных операций? Можно на асме что-нибудь придумать. Помню, делал для RDTSC. #pragma warning( disable : 4035 ) // no return value __forceinline DWORD rdtsc() #pragma warning( default : 4035 ) // <…> DWORD cpu_in( rdtsc() ); // <…> g_cpu[ CPU_PERF ] = rdtsc() — cpu_in; DWORD для моих надобностей хватало.
|
|
|
Dmitriy40 |
Re: Инверсия переменной boolean в С/С++
|
||
20/08/14 |
Ну вообще исторически интересный вопрос: почему существует, например, инкремент, но не существует аналогичный «синтаксический сахар» для других унарных операций? Вопрос не только к С, но и вообще ко всем языкам. Наверное из-за частоты использования, инкремент/декремент используются на порядки чаще всех прочих. Настолько чаще, что даже предусмотрели пре- и пост- варианты. И если конструкции !!a и a!! и ~~a и a~~ ещё имеют смысл, то смена знака —a или a— конфликтует с декрементом. А конструкции a! и a- и a~ бессмысленны с точки зрения синтаксиса языка: унарная операция должна брать правый операнд, а не левый, инкременту/декременту и тут сделано исключение из-за частоты использования. предусмотрели кольцевых сдвигов (хотя они есть практически на всех процессорах и часто нужны, например в расчёте CRC) и длинных сдвигов, что вынуждает городить C код с проверками битов и временными переменными (или условными операторами что ещё больший вред уже лет 40).
|
||
|
|||
warlock66613 |
Re: Инверсия переменной boolean в С/С++
|
||
02/08/11 |
Это всё из-за отсутствия foreach и смежных концепций. Rust — где foreach есть — избавился от этих монстров (++ и —).
|
||
|
|||
arseniiv |
Re: Инверсия переменной boolean в С/С++
|
||
27/04/09 |
Я бы сказал, что частота использования ++ — не совсем аргумент. Люди используют их как минимум потому что они есть, без них писали бы += 1, а некоторые могут и по сей день думать, что ++ «быстрее» или ещё по какой-то кроме длины кода причине «лучше». Постинкремент/декремент так не сделаешь, но частота его необходимости не такая уж большая — люди пишут на языках без них и сильно не страдают. Кроме того само действие может быть доступно в языке, но не с синтаксисом операции. Как инкремента/декремента (вон в паскале, по крайней мере традиционном, есть Inc и Dec), так и обращения знака значения переменной, например (не видел, но кто ж мешает?), так и циклического сдвига значения. Выдумывать особый синтаксис не нужно и называть трудность этого причиной не вводить штуку тоже странно.
|
||
|
|||
Dmitriy40 |
Re: Инверсия переменной boolean в С/С++
|
||
20/08/14 |
В таком случае никто не мешает доопределить Not() и Neg() и сдвиги — ровно так же как и Inc()/Dec() в паскале. Речь ведь не про это.
|
||
|
|||
arseniiv |
Re: Инверсия переменной boolean в С/С++
|
||
27/04/09 |
В таком случае никто не мешает доопределить Not() и Neg() и сдвиги — ровно так же как и Inc()/Dec() в паскале. Речь ведь не про это. Ну в C и C++ есть препроцессорные макросы, так что можно что-то такое написать, когда знаешь все платформы, под которые код будут компилировать, и ассемблер каждой из них, чтобы написать подходящий макрос. Но ведь как раз хотелось не делать ничего такого, а чтобы это входило уже в сам язык. А в С++ наверное можно и унарную операцию как-то доопределить для своих типов данных с желаемым синтаксисом. Очень удивлюсь если это там когда-нибудь появится. Определение произвольных бинарных операций — это рискованная фича (намного рискованнее, чем перегрузка функций/методов, например, или некоторых из операций, которые изначально определены для языка), на неё решаются единичные языки, а уж операций с произвольным синтаксисом — оо, ещё меньше.
|
||
|
|||
Dmitriy40 |
Re: Инверсия переменной boolean в С/С++
|
||
20/08/14 |
arseniiv В Форте можно определить операцию/функцию/процедуру (они там не различаются) почти произвольного синтаксиса. Правда и никакого контроля типов нет.
|
||
|
|||
arseniiv |
Re: Инверсия переменной boolean в С/С++
|
||
27/04/09 |
Dmitriy40 Ну нет, в форте и синтаксис не алголоподобный с самого начала. (Как и в произвольном языке, который уместно назвать конкатенативным, это как раз синтаксическое свойство, что «в основном» можно взять два любых корректных куска кода и сложить их в один кусок, который будет (в большей части случаев) делать сначала то, что делает первый, а потом то, что делает второй.) И кстати там тоже вроде предполагается, чтобы обычные функции выглядели просто как одинарное слово, а не как изощрённая синтаксическая конструкция, что требует оснований.
|
||
|
|||
Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы