Что делает ! в С?
-
- Уже с Приветом
- Posts: 20128
- Joined: 21 Feb 2009 22:55
- Location: Лох Онтарио
Что делает ! в С?
Есть 1 байт, в котором нас интересует только последний бит. Я сделал while цикл, в котором использовал ~byte, думая, что это полностью аналогично !. Но оно не работало. То есть ! не переворачивает все биты, а делает что-то другое. Вопрос — что именно?
-
- Уже с Приветом
- Posts: 13339
- Joined: 07 Dec 2004 04:00
- Location: Москва->CO
Re: Что делает ! в С?
Ну это как бы все знают: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... ковыряться" (с) старый анек.
Как же это вы без гравицаппы пепелац выкатываете из гаража? Это непорядок...
-
- Уже с Приветом
- Posts: 13339
- Joined: 07 Dec 2004 04:00
- Location: Москва->CO
Re: Что делает ! в С?
...и замаскировать все биты кроме последнего -если последний нужен- &1partner_ca wrote: ↑18 May 2017 05:49 Для инверсии битов можно использовать bitwise complement оператор ~
Как же это вы без гравицаппы пепелац выкатываете из гаража? Это непорядок...
-
- Уже с Приветом
- Posts: 13339
- Joined: 07 Dec 2004 04:00
- Location: Москва->CO
Re: Что делает ! в С?
Еврей что ли или араб? Справа налево читаете?partner_ca wrote: ↑18 May 2017 06:00Смотря который считать последним
Для меня последний 0x80, а 0x01 - первый.
Как же это вы без гравицаппы пепелац выкатываете из гаража? Это непорядок...
-
- Уже с Приветом
- Posts: 20128
- Joined: 21 Feb 2009 22:55
- Location: Лох Онтарио
Re: Что делает ! в С?
Аааа! До меня наконец-то дошло! Когда я сделал
условие проваливалось из-за того, что флаг 0x01 (ИСТИНА) превращался в 0xFE (тоже ИСТИНА) вместо 0х00. Надо было маскировать последний бит, чтобы заработало:
while (!b) наверняка в это и компилируется на моем микроконтроллере.
Спасибо, пан Тихий за вправление мозгов!
Code: Select all
while (~b)
Code: Select all
while ((~b)&0x01)
Спасибо, пан Тихий за вправление мозгов!
-
- Уже с Приветом
- Posts: 26871
- Joined: 29 Aug 2000 09:01
Re: Что делает ! в С?
Что-то я не пойму если последний (младший) бит нужен, то почему нельзя сделать:
while(b&1)
while(b&1)
All rights reserved, all wrongs revenged.
-
- Уже с Приветом
- Posts: 20128
- Joined: 21 Feb 2009 22:55
- Location: Лох Онтарио
Re: Что делает ! в С?
К микроконтроллеру подключено устройство, которое рапортует байт. Когда байт "свежий", в нем выставляется флаг готовности. Поэтому нужна петля, в которой этот байт считывается до тех пор, пока флаг не становится TRUE
Code: Select all
do {
// считываем байт b
} while (!b); // выходим из петли если флаг 1
-
- Уже с Приветом
- Posts: 26871
- Joined: 29 Aug 2000 09:01
Re: Что делает ! в С?
while (!b) будет работать только если остальные биты в байте всегда нули.
Если же остальные биты могут быть не нулями то нужно while (!(b&1))
Так?
Если же остальные биты могут быть не нулями то нужно while (!(b&1))
Так?
All rights reserved, all wrongs revenged.
-
- Уже с Приветом
- Posts: 20128
- Joined: 21 Feb 2009 22:55
- Location: Лох Онтарио
Re: Что делает ! в С?
Вы абсолютно правы. Я несколько упростил детали. На самом деле в моем случае флаг находится в старшем бите, и вместо b стоит b>>7, что позволяет опускать маску при исползовании !
-
- Уже с Приветом
- Posts: 26871
- Joined: 29 Aug 2000 09:01
Re: Что делает ! в С?
ок, ясно.
Если без использования побитного шифта >>, тогда: while (!(b&0x80))
Если без использования побитного шифта >>, тогда: while (!(b&0x80))
All rights reserved, all wrongs revenged.
-
- Уже с Приветом
- Posts: 26871
- Joined: 29 Aug 2000 09:01
Re: Что делает ! в С?
Кстати, тут b должна быть определена как volatile. А иначе компилятор может оптимизировать код так, что b будет прочитана только один раз, и ваша программа зависнет в бесконечном цикле.perasperaadastra wrote: ↑18 May 2017 17:21 К микроконтроллеру подключено устройство, которое рапортует байт. Когда байт "свежий", в нем выставляется флаг готовности. Поэтому нужна петля, в которой этот байт считывается до тех пор, пока флаг не становится TRUE
Code: Select all
do { // считываем байт b } while (!b); // выходим из петли если флаг 1
All rights reserved, all wrongs revenged.
-
- Уже с Приветом
- Posts: 3000
- Joined: 14 Apr 2004 01:11
- Location: SFBA (было: Минск, Беларусь)
Re: Что делает ! в С?
По определению, в языке С выражение '!x' эквивалентно выражению 'x == 0'.perasperaadastra wrote: ↑18 May 2017 05:25 То есть ! не переворачивает все биты, а делает что-то другое. Вопрос — что именно?
Нет, конечно. Оно компилируется в 'while (b == 0)', как и должно.perasperaadastra wrote: ↑18 May 2017 06:16 while (!b) наверняка в это и компилируется на моем микроконтроллере.
Last edited by AndreyT on 19 May 2017 00:06, edited 1 time in total.
Best regards,
Андрей
Андрей
-
- Уже с Приветом
- Posts: 13339
- Joined: 07 Dec 2004 04:00
- Location: Москва->CO
Re: Что делает ! в С?
Вы бредите.thinker wrote: ↑18 May 2017 21:57Кстати, тут b должна быть определена как volatile. А иначе компилятор может оптимизировать код так, что b будет прочитана только один раз, и ваша программа зависнет в бесконечном цикле.perasperaadastra wrote: ↑18 May 2017 17:21...Code: Select all
do { // считываем байт b } while (!b); // выходим из петли если флаг 1
Как же это вы без гравицаппы пепелац выкатываете из гаража? Это непорядок...
-
- Уже с Приветом
- Posts: 3000
- Joined: 14 Apr 2004 01:11
- Location: SFBA (было: Минск, Беларусь)
Re: Что делает ! в С?
Биты нумеруются от младших к старшим, с тем только замечанием, что нумерация традиционно ведется с нуля. Поэтому "первым" натуральнее назвать младший бит, а "последним" - старший. То есть именно 0x01 - "первый", а 0x80 - "последний".Ion Tichy wrote: ↑18 May 2017 06:05Еврей что ли или араб? Справа налево читаете?partner_ca wrote: ↑18 May 2017 06:00Смотря который считать последним
Для меня последний 0x80, а 0x01 - первый.
И да, нумерация разрядов в позиционной записи числа растет справа-налево. Для этого совсем не надо быть евреем или арабом.
Best regards,
Андрей
Андрей
-
- Уже с Приветом
- Posts: 20128
- Joined: 21 Feb 2009 22:55
- Location: Лох Онтарио
Re: Что делает ! в С?
Спасибо за объяснение. Сейчас глянул в ассембли вывод, и оказывается на данном микроконтроллере это очень удобно реализуется черезAndreyT wrote: ↑18 May 2017 23:34По определению, в языке С выражение '!x' эквивалентно выражению 'x == 0'.perasperaadastra wrote: ↑18 May 2017 05:25 То есть ! не переворачивает все биты, а делает что-то другое. Вопрос — что именно?
Нет, конечно. Оно компилируется в 'while (b == 0)', как и должно.perasperaadastra wrote: ↑18 May 2017 06:16 while (!b) наверняка в это и компилируется на моем микроконтроллере.
Code: Select all
sbrs (Skip if Bit in Register is Set)
rjmp (relative jump)
-
- Уже с Приветом
- Posts: 20128
- Joined: 21 Feb 2009 22:55
- Location: Лох Онтарио
Re: Что делает ! в С?
Thinker имеет аргумент:Ion Tichy wrote: ↑18 May 2017 23:36Вы бредите.thinker wrote: ↑18 May 2017 21:57Кстати, тут b должна быть определена как volatile. А иначе компилятор может оптимизировать код так, что b будет прочитана только один раз, и ваша программа зависнет в бесконечном цикле.perasperaadastra wrote: ↑18 May 2017 17:21...Code: Select all
do { // считываем байт b } while (!b); // выходим из петли если флаг 1
https://barrgroup.com/Embedded-Systems/ ... le-Keyword
Edit: или речь о другом?
Хотя в моем случае компилятор хранит эту переменную всегда только в регистре, поэтому нет опасности.
-
- Уже с Приветом
- Posts: 26871
- Joined: 29 Aug 2000 09:01
Re: Что делает ! в С?
Именно это.perasperaadastra wrote: ↑19 May 2017 01:06Thinker имеет аргумент:
https://barrgroup.com/Embedded-Systems/ ... le-Keyword
Edit: или речь о другом?
All rights reserved, all wrongs revenged.
-
- Уже с Приветом
- Posts: 18917
- Joined: 11 Jul 2003 01:00
Re: Что делает ! в С?
Судя по тому, что написал perasperaadastra, у него эта b как раз пишется-читается из нескольких потоков.partner_ca wrote: ↑19 May 2017 01:17volatatile - это в первую очередь про глобальные данныe, к которым возможен доступ из нескольких потоков.perasperaadastra wrote: ↑19 May 2017 01:06 Edit: или речь о другом?
Хотя в моем случае компилятор хранит эту переменную всегда только в регистре, поэтому нет опасности.
В данном случае совсем не в тему.