Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Вопросы по С/С++ (СИ)

Сообщение FreshMan »

ut1wpr писал(а):у меня уже березка на горизонте...

а что это значит ? :))
ut1wpr писал(а):Вот один из результатов помощи дядьки Гугла.

СПАСИБО...................., только вот английский мой пока храмает :oops:
Tell Me The Truth
Реклама
ut1wpr
Вымогатель припоя
Сообщения: 581
Зарегистрирован: Ср янв 05, 2011 10:03:18

Re: Вопросы по С/С++ (СИ)

Сообщение ut1wpr »

FreshMan писал(а):а что это значит ? :))
Слава Богу, что вы этого не знаете. Значит рано еще. Подольше бы вам не знать.. :)
СПАСИБО...................., только вот английский мой пока храмает :oops:
А вот это плохо. Совсем плохо. Значит, вам кроме преподавателей еще и переводчики потребуются.
Учитывая, что про березку вы не знаете (времени в запасе еще много), рекомендую немедленно приступить к чтению даташитов-первоисточников. Я английский по ним, да по чужим листингам с каментами изучал... :) :)
На этом хочу оффтоп со своей стороны прекратить. Удачи и успехов.
С уважением,
Виктор.
Реклама
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение DX168B »

ut1wpr писал(а):Си нас ни в чем не ограничивает. Можно определить новый тип данных:
Спойлер

Код: Выделить всё

typedef enum{
  CAN_IDLE,
  CAN_SENDING,
  CAN_WAIT_RX,
  CAN_PROCESS
} state;

struct g_sCAN{
    [skip]
    state eState;
};

int main (){
    [skip]
    // Set the initial state to idle.
    g_sCAN.eState = CAN_IDLE;
}

Тоже будет работать, т.к. определение перечисляемого типа сделано вне описания структуры.
В этом случае с программиста снимается забота о соответствии типов данных и их ширины.

Можно и так, я чего-то не догадался. :beer:
FreshMan писал(а):почему ?

Спросите у Atmel. Видать, мозгов\места на камне\щедрости (нужное подчеркнуть) не хватило у них. :)))
По этому приходится извращаться методом вычитания \ сдвига в цикле.
I am DX168B and this is my favourite forum on internet!
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Вопросы по С/С++ (СИ)

Сообщение FreshMan »

в примерах часто вижу вот такую запись
PORTD &=~((1<<1)(1<<0));

а можна ли так писать ?
PORTD &= ((0<<1)(0<<0));
Tell Me The Truth
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
IfoR
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение IfoR »

Обе записи вызовут ошибку. Вероятно пропущен оператор побитового ИЛИ (|).
Ну а уж запись 0<<1 порадовала. :))
Смотри сам: у нас есть число 0 в двоичной системе для наглядности: 0b00000000. Теперь мы делаем с ним операцию побитового сдвига влево на 1 разряд. Сдвигаем. Получилось: 0b00000000. Где логика?
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Реклама
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Вопросы по С/С++ (СИ)

Сообщение FreshMan »

а разве эта команда производит сдвиг ? :wink:
насколтько я в курсе то это установка соответствующих битов порта С.......
PORTD &= ((0<<1)|(0<<0));
Tell Me The Truth
Реклама
Аватара пользователя
SubDia
Держит паяльник хвостом
Сообщения: 995
Зарегистрирован: Сб апр 02, 2011 17:59:22
Откуда: Город-герой Севастополь

Re: Вопросы по С/С++ (СИ)

Сообщение SubDia »

А тут не одна команда, тут набор операций (кстати, то, что Вы написали, ни к какой установке битов порта D не приведет).
1. Команда << служит для сдвига первого операнда на количество бит, определяемое вторым операндом. Таким образом, если бы у нас строка имела вид:

Код: Выделить всё

PORTD &= (1<<3)|(1<<5);

то мы имели бы:
0b00000001<<3 = 0b00001000 (в первой скобке) и 0b00000001<<5= 0b00100000 (во второй скобке).
2. Операция "|" (побитное ИЛИ) сравнивает каждый бит первого операнда с соответствующим битом второго операнда. Если любой из битов равен 1, то в результате получаем 1, если оба 0, то в результате 0. То есть, имеем:
(0b00001000)|(0b00000001) = 0b00101000.
А теперь - самое интересное.
3. Операция побитного логического И с присваиванием (&=) сравнивает соответствующие биты двух чисел, и там где в маске (так называют второй операнд) стоят нули, биты исходного числа также принимают нулевые значения. Где же в маске стоят единицы, там биты остаются неизменными.
А теперь, допустим, состояние порта D было равным 0b00000000. Нулевым то есть. И куда мы тут ни тули свои числа, биты порта не установятся. Для установки используют операцию "|=". При использовании данной операции в тех местах, где биты маски=1, соответствующие биты результирующего числа устанавливаются в 1, а там где нули, результат не меняется.
Таким образом, если используем эту операцию (и для установки битов действительно обычно используется операция "|="), получим в результате:
0b00000000 |= 0b00101000;
или PORTD = 0b00101000;
И таким образом мы установили 3-й и 5-й биты порта D.
FreshMan, Вы таки прислушайтесь к советам ut1wpr. Человек умудрен опытом, ерунды не посоветует..
pavel_cydenov: Вобще я праAVRославный человек. Но и про ислARM слышал много хорошего )
MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )
Изображение
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Вопросы по С/С++ (СИ)

Сообщение FreshMan »

SubDia писал(а):Если любой из битов равен 1, то в результате получаем 1, если оба 0, то в результате 0. То есть, имеем:(0b00001000)|(0b00000001) = 0b00101000.

простите, может сдесь результат будет равен не 0b00101000 а 0b00001001 ???
Tell Me The Truth
Аватара пользователя
SubDia
Держит паяльник хвостом
Сообщения: 995
Зарегистрирован: Сб апр 02, 2011 17:59:22
Откуда: Город-герой Севастополь

Re: Вопросы по С/С++ (СИ)

Сообщение SubDia »

Естественно! Это моя ошибка, прошу прощения - не произвел операцию сдвига на 5 битов. В таком виде, как есть - да, будет 0b00001001.
Но если исправиться и все же произвести сдвиг на 5 влево, то получим (0b00001000)|(0b00100000) = 0b00101000.
pavel_cydenov: Вобще я праAVRославный человек. Но и про ислARM слышал много хорошего )
MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )
Изображение
Tolmi
Говорящий с текстолитом
Сообщения: 1658
Зарегистрирован: Вс дек 11, 2011 05:25:04
Откуда: Киев, Украина
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Tolmi »

PORTD &=~((1<<1)(1<<0));

Если всё же посчитать, что пропущен оператор битового ИЛИ и выражение должно как

Код: Выделить всё

PORTD &=~((1<<1)|(1<<0));

то это выражение имеет вполне логичный смысл, хотя и запутывает поначалу. Любители "магических констант" написали бы просто PORTD&=0xFC;
1<<1 - сдвинуть влево на один разряд единицу, = 2
1<<0 - сдвигать влево но ноль разрядов, т.е. всегда равно самому себе = 1
2|1 побитовое сложение, = 3
~3 побитовая инверсия, в зависимости от типа данных инверсное число будет разным, если речь о байте, то это 11111100 или 0xFC в шестнадцатиричном виде.
Операция &= применит побитовую операцию И к левому операнду и результат возвратит туда-же. Вернее, скорее будет использована атомарная инструкция очистки тех битов, для которых в правой части оператора, числа-маски, будут равны 0. Т.е. в результате в регистре PORTD будут очищены два младших бита. Процитированное выражение более человеко-читаемое. (Хотя тут есть нюансы :) )
А теперь попробуйте разобрать аналогично то, что сами написали ;)
In theory, theory and practice are the same. In practice, they're not.
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Вопросы по С/С++ (СИ)

Сообщение FreshMan »

ага кажись понял................, команду PORTD &=~((1<<1)|(1<<0)); можна расшифровать как:
1)PORTD = 0b00000011
2)PORTD = 0b11111100
3)0b11111100 - это число побитно умножаем на то что было записано в порт D до всей этой катовасии ............, я правильно понял ? :))
Tell Me The Truth
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение vitalik_1984 »

FreshMan писал(а): я правильно понял ? :))

Почти,только
команду PORTD &=~((1<<1)|(1<<0)); можна расшифровать как:

1)Reg_temp = 0b00000011
2)Reg_temp = 0b11111100
3)PORTD=PORTD&Reg_temp - это число побитно умножаем на то что было записано в порт D до всей этой катовасии
В поисках истины человек развивается.
Tolmi
Говорящий с текстолитом
Сообщения: 1658
Зарегистрирован: Вс дек 11, 2011 05:25:04
Откуда: Киев, Украина
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Tolmi »

Нужно учитывать ещё, что компиллятор умеет сам подсчитывать и упрощать выражения в программе, и если они приводимы к константам, он их и приведет к константе. т.е результатом компилляции этого выражения будет что-то типа

Код: Выделить всё

CBI PORTD,0b00000011
In theory, theory and practice are the same. In practice, they're not.
Аватара пользователя
Chip115
Сверлит текстолит когтями
Сообщения: 1132
Зарегистрирован: Пт фев 16, 2007 14:18:20
Откуда: Новосибирск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Chip115 »

ut1wpr писал(а):
DX168B писал(а):Си нас ни в чем не ограничивает. Можно определить новый тип данных:

Код: Выделить всё

typedef enum{
  CAN_IDLE,
  CAN_SENDING,
  CAN_WAIT_RX,
  CAN_PROCESS
} state;

struct g_sCAN{
    [skip]
    state eState;
};

int main (){
    [skip]
    // Set the initial state to idle.
    g_sCAN.eState = CAN_IDLE;
}

Тоже будет работать, т.к. определение перечисляемого типа сделано вне описания структуры.
В этом случае с программиста снимается забота о соответствии типов данных и их ширины.

Спасибо всем! Сделал дефайнами. Но просто интересно, почему в другом алгоритме подобная схема работает :(
Теория — это когда все известно, но ничего не работает. Практика — это когда все работает, но никто не знает почему. Мы же объединяем теорию и практику: ничего не работает… и никто не знает почему!
© Альберт Эйнштейн
ut1wpr
Вымогатель припоя
Сообщения: 581
Зарегистрирован: Ср янв 05, 2011 10:03:18

Re: Вопросы по С/С++ (СИ)

Сообщение ut1wpr »

Chip115 писал(а):Спасибо всем! Сделал дефайнами. Но просто интересно, почему в другом алгоритме подобная схема работает :(
Скорее всего, это интересно уже только вам. Разроете - будет ваша маленькая победа, еще один шажок на пути к полному пониманию.
Если все-таки не ограничитесь праздным любопытством, типа "просто интересно", рекомендую определить тип компилятора, наличие посторонних, внебиблиотечных инклюдов, и вообще, внимательно пройтись по полному тексту программы. Возможно, что-то и где-то оказалось вне поля вашего зрения.
С уважением,
Виктор.
Аватара пользователя
wellcom
Нашел транзистор. Понюхал.
Сообщения: 190
Зарегистрирован: Чт фев 24, 2011 13:00:49

Re: Вопросы по С/С++ (СИ)

Сообщение wellcom »

есть такое выражение, как оно будет выполнятся согласно приоритетности С?

Код: Выделить всё

if((Buffer[Bit/8]>>(Bit%8))&0x01)

0. Вычислить индекс массива Bit/8
1. Вычислить остаток (Bit%8)
2. Прочитанные данные по вычисленному индексу
3. Сдвинуть данные вправо на число-остаток
4. обнулить кроме первого бита

т.е. (([2]>3>(1))&4)
Правильно ли я думаю? :roll:
:solder: 32-х ядерный процессор из П213В
Аватара пользователя
IfoR
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение IfoR »

Ну собственно, другого варианта быть не может, ведь всё жестко определено скобками.
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение vitalik_1984 »

Вычислит то вы числит, а что это за алгоритм такой?
Похоже на последовательный вывод значения регистра на ногу контроллера
В поисках истины человек развивается.
Аватара пользователя
wellcom
Нашел транзистор. Понюхал.
Сообщения: 190
Зарегистрирован: Чт фев 24, 2011 13:00:49

Re: Вопросы по С/С++ (СИ)

Сообщение wellcom »

vitalik_1984 писал(а):Вычислит то вы числит, а что это за алгоритм такой?
Похоже на последовательный вывод значения регистра на ногу контроллера

Так и есть! :)
:solder: 32-х ядерный процессор из П213В
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение vitalik_1984 »

А что за сложный алгоритм?
Зачем делить на что то?
Это что на дисплей выход?По четыре бита двигать?
Не похоже.Или это через сдвиговый регистр вывод в дисплей?

Я делал так:

Код: Выделить всё

#define OUT_PORT PORTB
 #define OUT_PIN 1
void data_shift(unsigned char DATA){
for (i=0;i<7;i++){
       if (DATA&0x01) setbit(OUT_PORT,OUT_PIN);
       else clearbit(OUTPORT,OUT_PIN);
       DATA=DATA>>1;
}}
 
Последний раз редактировалось vitalik_1984 Вт мар 13, 2012 17:00:54, всего редактировалось 4 раза.
В поисках истины человек развивается.
Ответить

Вернуться в «Разные вопросы по МК»