Хочу узнать правила применения типов констант. (L, UL и тп)

Здесь принимаются все самые невообразимые вопросы... Главное - не стесняйтесь. Поверьте, у нас поначалу вопросы были еще глупее :)
Ответить
Laksus
Родился
Сообщения: 5
Зарегистрирован: Пт окт 20, 2006 02:33:07
Откуда: Харьковская обл.

Хочу узнать правила применения типов констант. (L, UL и тп)

Сообщение Laksus »

Я знаю, что константы имеют определенный тип в зависимости от ее величины, или прицепленного суффикса.
Например частота кварца обозначается 4000000UL.
Но никак не могу понять когда и какие суффиксы надо цеплять, а когда можно обойтись без них. Какие на это есть правила?
__
Хотелось бы узнать общие правила.
Но на сейчас, чтобы конкретизировать, почему возник вопрос. Пытаюсь написать програмку для AVR ATmega32 в WinAVR. Хочу использовать число uint32_t N_pr, хранящееся "в разобранном виде" в трех байтах. При попытке собирать без суффиксов
N_pr= N_pr2*0x10000+ N_pr1*0x100+ N_pr0*0x1 получается не то, что хотел, с суффиксами - правильно
N_pr= N_pr2*0x10000UL+ N_pr1*0x100UL+ N_pr0*0x1UL. По какому правилу их надо сюда добавлять?
rustot
Поставщик валерьянки для Кота
Сообщения: 1929
Зарегистрирован: Пт окт 23, 2009 15:32:35
Откуда: Челябинск

Re: Хочу узнать правила применения типов констант. (L, UL и

Сообщение rustot »

U - беззнаковое. L - длинное (что есть длинное и короткое зависит от конкретного компилятора). у вас по всей видимости без L все константы считаются 16-битными и соответственно 0x10000 == 0
Аватара пользователя
YS
Друг Кота
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05
Контактная информация:

Re: Хочу узнать правила применения типов констант. (L, UL и

Сообщение YS »

По-умолчанию все константы имеют тип signed int. Суффиксы служат как раз для того, чтобы указать компилятору, что константа имеет другой тип, дабы она была корректно обработана. В принципе, современные компиляторы достаточно продвинуты, чтобы определить тип константы самостоятельно, но бывают случаи, когда тип все же надо указывать принудительно.

Рассмотрим Ваш случай:

Вы пишете: 0x1. Компилятор рассуждает: в int влазит, значит, это int. И обрабатывает это как int. Но потом-то Вы работаете с этой константой, как с long! И возникает ошибка. Потому в этом случае надо принудительно указать, что это именно long.

И кстати, хинт: для сборки числа из байтов лучше использовать битовые сдвиги. Т.е.:

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

N_pr=(N_pr2<<16) | (N_pr1<<8) | (N_pr0);


Это работает быстрее. :)

Аналогично, для выделения произвольного байта:

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

byte=(char)((long_variable & (0xFF<<номер_нужного_байта))>>номер_нужного_байта);
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Ответить

Вернуться в «Теория»