Что делает ! в С?

User avatar
perasperaadastra
Уже с Приветом
Posts: 20128
Joined: 21 Feb 2009 22:55
Location: Лох Онтарио

Что делает ! в С?

Post by perasperaadastra »

Есть 1 байт, в котором нас интересует только последний бит. Я сделал while цикл, в котором использовал ~byte, думая, что это полностью аналогично !. Но оно не работало. То есть ! не переворачивает все биты, а делает что-то другое. Вопрос — что именно?
User avatar
Ion Tichy
Уже с Приветом
Posts: 13339
Joined: 07 Dec 2004 04:00
Location: Москва->CO

Re: Что делает ! в С?

Post by Ion Tichy »

perasperaadastra wrote: 18 May 2017 05:25 Есть 1 байт, в котором нас интересует только последний бит. Я сделал while цикл, в котором использовал ~byte, думая, что это полностью аналогично !. Но оно не работало. То есть ! не переворачивает все биты, а делает что-то другое. Вопрос — что именно?
Ну это как бы все знают:
Called Logical NOT Operator. It is used to reverse the logical state of its operand. If a condition is true, then Logical NOT operator will make it false.
Надеюсь не надо напоминать что 0 - фолс, а все что не 0 - тру? А уж как там ! внутри сделан - побитово, похренитово - это детали имплементации, спеки-стандарты такой ерундой не заморачиваются. "Не царское это дело в 3,14... ковыряться" (с) старый анек.
Как же это вы без гравицаппы пепелац выкатываете из гаража? Это непорядок...
User avatar
Ion Tichy
Уже с Приветом
Posts: 13339
Joined: 07 Dec 2004 04:00
Location: Москва->CO

Re: Что делает ! в С?

Post by Ion Tichy »

partner_ca wrote: 18 May 2017 05:49 Для инверсии битов можно использовать bitwise complement оператор ~
...и замаскировать все биты кроме последнего -если последний нужен- &1
Как же это вы без гравицаппы пепелац выкатываете из гаража? Это непорядок...
User avatar
Ion Tichy
Уже с Приветом
Posts: 13339
Joined: 07 Dec 2004 04:00
Location: Москва->CO

Re: Что делает ! в С?

Post by Ion Tichy »

partner_ca wrote: 18 May 2017 06:00
Ion Tichy wrote: 18 May 2017 05:54 ...и замаскировать все биты кроме последнего -если последний нужен- &1
Смотря который считать последним :-)
Для меня последний 0x80, а 0x01 - первый.
Еврей что ли или араб? Справа налево читаете?
Как же это вы без гравицаппы пепелац выкатываете из гаража? Это непорядок...
User avatar
perasperaadastra
Уже с Приветом
Posts: 20128
Joined: 21 Feb 2009 22:55
Location: Лох Онтарио

Re: Что делает ! в С?

Post by perasperaadastra »

Аааа! До меня наконец-то дошло! Когда я сделал

Code: Select all

while (~b) 
условие проваливалось из-за того, что флаг 0x01 (ИСТИНА) превращался в 0xFE (тоже ИСТИНА) вместо 0х00. Надо было маскировать последний бит, чтобы заработало:

Code: Select all

while ((~b)&0x01) 
while (!b) наверняка в это и компилируется на моем микроконтроллере.

Спасибо, пан Тихий за вправление мозгов! :fr:
User avatar
thinker
Уже с Приветом
Posts: 26871
Joined: 29 Aug 2000 09:01

Re: Что делает ! в С?

Post by thinker »

Что-то я не пойму если последний (младший) бит нужен, то почему нельзя сделать:
while(b&1)
All rights reserved, all wrongs revenged.
User avatar
perasperaadastra
Уже с Приветом
Posts: 20128
Joined: 21 Feb 2009 22:55
Location: Лох Онтарио

Re: Что делает ! в С?

Post by perasperaadastra »

К микроконтроллеру подключено устройство, которое рапортует байт. Когда байт "свежий", в нем выставляется флаг готовности. Поэтому нужна петля, в которой этот байт считывается до тех пор, пока флаг не становится TRUE

Code: Select all

do  {
     // считываем байт b
} while (!b);                        // выходим из петли если флаг 1
User avatar
thinker
Уже с Приветом
Posts: 26871
Joined: 29 Aug 2000 09:01

Re: Что делает ! в С?

Post by thinker »

while (!b) будет работать только если остальные биты в байте всегда нули.

Если же остальные биты могут быть не нулями то нужно while (!(b&1))

Так?
All rights reserved, all wrongs revenged.
User avatar
perasperaadastra
Уже с Приветом
Posts: 20128
Joined: 21 Feb 2009 22:55
Location: Лох Онтарио

Re: Что делает ! в С?

Post by perasperaadastra »

Вы абсолютно правы. Я несколько упростил детали. На самом деле в моем случае флаг находится в старшем бите, и вместо b стоит b>>7, что позволяет опускать маску при исползовании !
User avatar
thinker
Уже с Приветом
Posts: 26871
Joined: 29 Aug 2000 09:01

Re: Что делает ! в С?

Post by thinker »

ок, ясно.
Если без использования побитного шифта >>, тогда: while (!(b&0x80))
All rights reserved, all wrongs revenged.
User avatar
thinker
Уже с Приветом
Posts: 26871
Joined: 29 Aug 2000 09:01

Re: Что делает ! в С?

Post by thinker »

perasperaadastra wrote: 18 May 2017 17:21 К микроконтроллеру подключено устройство, которое рапортует байт. Когда байт "свежий", в нем выставляется флаг готовности. Поэтому нужна петля, в которой этот байт считывается до тех пор, пока флаг не становится TRUE

Code: Select all

do  {
     // считываем байт b
} while (!b);                        // выходим из петли если флаг 1
Кстати, тут b должна быть определена как volatile. А иначе компилятор может оптимизировать код так, что b будет прочитана только один раз, и ваша программа зависнет в бесконечном цикле.
All rights reserved, all wrongs revenged.

Return to “Вопросы и новости IT”