2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу 1, 2, 3  След.
 
 Инверсия переменной boolean в С/С++
Сообщение09.03.2020, 16:48 
Доброго времени суток уважаемые любители и профессиональные программисты.
Возникла проблема при работы с переменными типа bool в C/C++, которые я раньше как то не использовал, но появилось приложение, в котором они оказались как нельзя кстати.

Дело в том, что нужно не просто присвоить конкретное значение, переменной, а проинвертировать его. Разумеется, предпочтительно сделать это через унарную операцию, и интуитивно, я предположил, что сделать это можно так
Используется синтаксис C++
!(*(flag+id));
 

но этот код, как на зло, не работает, элементы массива flag так всё время и остаются нулевыми, хотя при непосредственном присваивании значений
Используется синтаксис C++
*(flag+id)=true);
 

они изменяются как положено.

Подскажите, как правильно реализовать инверсию переменной boolean?

-- 09.03.2020, 18:25 --

Вот так всё работает
Используется синтаксис C++
*(flag+id)=!(*(flag+id));
 

но неужели для этого нет унарного оператора?

 
 
 
 Re: Инверсия переменной boolean в С/С++
Сообщение09.03.2020, 17:54 
Нету. А зачем? (И зачем писать *(flag + id) вместо flag[id]? В одно и то же компилируется ведь.)

 
 
 
 Re: Инверсия переменной boolean в С/С++
Сообщение09.03.2020, 17:56 
Аватара пользователя
flag[id] ^= true

 
 
 
 Re: Инверсия переменной boolean в С/С++
Сообщение09.03.2020, 18:46 
arseniiv в сообщении #1443890 писал(а):
А зачем?

Для удобства, по аналогии с унарным минусом.
mihaild в сообщении #1443891 писал(а):
flag[id] ^= true

Да, как один из вариантов. Но это уже xor а не not

 
 
 
 Re: Инверсия переменной boolean в С/С++
Сообщение09.03.2020, 18:53 
Аватара пользователя
Andrey_Kireew в сообщении #1443895 писал(а):
по аналогии с унарным минусом.
Унарный минус не модифицирует аргумент. Единственные модифицирующие угарные операторы - это инкремент и декремент.

 
 
 
 Re: Инверсия переменной boolean в С/С++
Сообщение09.03.2020, 18:59 
mihaild в сообщении #1443896 писал(а):
Унарный минус не модифицирует аргумент

Значит
Используется синтаксис C
-a;
 

тоже ничего не даст? Этого я не знал, спасибо за информацию.

 
 
 
 Re: Инверсия переменной boolean в С/С++
Сообщение10.03.2020, 12:41 
Аватара пользователя
Ну вообще исторически интересный вопрос: почему существует, например, инкремент, но не существует аналогичный "синтаксический сахар" для других унарных операций? Вопрос не только к С, но и вообще ко всем языкам. Хотя к C, конечно, в первую очередь, ведь в системе команд PDP-11 (для которой этот язык изначально разрабатывался), наряду с унарной командой INC/DEC есть и другие унарные присваивающие команды: NEG, COM, ...

 
 
 
 asm
Сообщение10.03.2020, 13:43 
Аватара пользователя
worm2 в сообщении #1444015 писал(а):
Ну вообще исторически интересный вопрос: почему существует, например, инкремент, но не существует аналогичный "синтаксический сахар" для других унарных операций?
Можно на асме что-нибудь придумать. Помню, делал для RDTSC.

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#pragma warning( disable : 4035 ) // no return value

__forceinline DWORD rdtsc()
{
    __asm rdtsc // edx:eax
}

#pragma warning( default : 4035 )

// <...>

DWORD cpu_in( rdtsc() );

// <...>

g_cpu[ CPU_PERF ] = rdtsc() - cpu_in;

DWORD для моих надобностей хватало.

 
 
 
 Re: Инверсия переменной boolean в С/С++
Сообщение10.03.2020, 17:49 
worm2 в сообщении #1444015 писал(а):
Ну вообще исторически интересный вопрос: почему существует, например, инкремент, но не существует аналогичный "синтаксический сахар" для других унарных операций? Вопрос не только к С, но и вообще ко всем языкам.
Наверное из-за частоты использования, инкремент/декремент используются на порядки чаще всех прочих. Настолько чаще, что даже предусмотрели пре- и пост- варианты. И если конструкции !!a и a!! и ~~a и a~~ ещё имеют смысл, то смена знака --a или a-- конфликтует с декрементом. А конструкции a! и a- и a~ бессмысленны с точки зрения синтаксиса языка: унарная операция должна брать правый операнд, а не левый, инкременту/декременту и тут сделано исключение из-за частоты использования.
По тем же причинам (редкость использования) не предусмотрели кольцевых сдвигов (хотя они есть практически на всех процессорах и часто нужны, например в расчёте CRC) и длинных сдвигов, что вынуждает городить C код с проверками битов и временными переменными (или условными операторами что ещё больший вред уже лет 40).

 
 
 
 Re: Инверсия переменной boolean в С/С++
Сообщение10.03.2020, 18:02 
Это всё из-за отсутствия foreach и смежных концепций. Rust - где foreach есть - избавился от этих монстров (++ и --).

 
 
 
 Re: Инверсия переменной boolean в С/С++
Сообщение10.03.2020, 18:31 
Я бы сказал, что частота использования ++ — не совсем аргумент. Люди используют их как минимум потому что они есть, без них писали бы += 1, а некоторые могут и по сей день думать, что ++ «быстрее» или ещё по какой-то кроме длины кода причине «лучше». Постинкремент/декремент так не сделаешь, но частота его необходимости не такая уж большая — люди пишут на языках без них и сильно не страдают.

Кроме того само действие может быть доступно в языке, но не с синтаксисом операции. Как инкремента/декремента (вон в паскале, по крайней мере традиционном, есть Inc и Dec), так и обращения знака значения переменной, например (не видел, но кто ж мешает?), так и циклического сдвига значения. Выдумывать особый синтаксис не нужно и называть трудность этого причиной не вводить штуку тоже странно.

 
 
 
 Re: Инверсия переменной boolean в С/С++
Сообщение10.03.2020, 21:05 
В таком случае никто не мешает доопределить Not() и Neg() и сдвиги — ровно так же как и Inc()/Dec() в паскале. Речь ведь не про это.
А в С++ наверное можно и унарную операцию как-то доопределить для своих типов данных с желаемым синтаксисом.

 
 
 
 Re: Инверсия переменной boolean в С/С++
Сообщение10.03.2020, 21:14 
Dmitriy40 в сообщении #1444134 писал(а):
В таком случае никто не мешает доопределить Not() и Neg() и сдвиги — ровно так же как и Inc()/Dec() в паскале. Речь ведь не про это.
Ну в C и C++ есть препроцессорные макросы, так что можно что-то такое написать, когда знаешь все платформы, под которые код будут компилировать, и ассемблер каждой из них, чтобы написать подходящий макрос. Но ведь как раз хотелось не делать ничего такого, а чтобы это входило уже в сам язык. :-)

Dmitriy40 в сообщении #1444134 писал(а):
А в С++ наверное можно и унарную операцию как-то доопределить для своих типов данных с желаемым синтаксисом.
Очень удивлюсь если это там когда-нибудь появится. Определение произвольных бинарных операций — это рискованная фича (намного рискованнее, чем перегрузка функций/методов, например, или некоторых из операций, которые изначально определены для языка), на неё решаются единичные языки, а уж операций с произвольным синтаксисом — оо, ещё меньше.

 
 
 
 Re: Инверсия переменной boolean в С/С++
Сообщение10.03.2020, 21:33 
arseniiv
В Форте можно определить операцию/функцию/процедуру (они там не различаются) почти произвольного синтаксиса. Правда и никакого контроля типов нет.

 
 
 
 Re: Инверсия переменной boolean в С/С++
Сообщение10.03.2020, 22:30 
Dmitriy40
Ну нет, в форте и синтаксис не алголоподобный с самого начала. (Как и в произвольном языке, который уместно назвать конкатенативным, это как раз синтаксическое свойство, что «в основном» можно взять два любых корректных куска кода и сложить их в один кусок, который будет (в большей части случаев) делать сначала то, что делает первый, а потом то, что делает второй.) И кстати там тоже вроде предполагается, чтобы обычные функции выглядели просто как одинарное слово, а не как изощрённая синтаксическая конструкция, что требует оснований.

 
 
 [ Сообщений: 32 ]  На страницу 1, 2, 3  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group