Страница 1 из 1

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

Добавлено: Пн фев 21, 2011 09:13:44
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. По какому правилу их надо сюда добавлять?

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

Добавлено: Пн фев 21, 2011 13:11:00
rustot
U - беззнаковое. L - длинное (что есть длинное и короткое зависит от конкретного компилятора). у вас по всей видимости без L все константы считаются 16-битными и соответственно 0x10000 == 0

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

Добавлено: Чт фев 24, 2011 13:23:45
YS
По-умолчанию все константы имеют тип signed int. Суффиксы служат как раз для того, чтобы указать компилятору, что константа имеет другой тип, дабы она была корректно обработана. В принципе, современные компиляторы достаточно продвинуты, чтобы определить тип константы самостоятельно, но бывают случаи, когда тип все же надо указывать принудительно.

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

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

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

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

N_pr=(N_pr2<<16) | (N_pr1<<8) | (N_pr0);
Это работает быстрее. :)

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

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

byte=(char)((long_variable & (0xFF<<номер_нужного_байта))>>номер_нужного_байта);