Страница 1 из 1
MikroC и его баги
Добавлено: Сб авг 10, 2013 15:10:27
dens
Вот кусочек кода от моей POV на p629
Код: Выделить всё
#define sh_cp GP0_bit
#define st_cp GP4_bit
#define ds GP1_bit
volatile char i, L1, L2, line_2, line_1;
volatile int T1;
volatile int period;
Воооот, так вот T1 и period у меня почему-то от -32767 до 32767, а должон быть от 0 до 65535. Кто сталкивался? Я 3 часа убил чтоб найти почему у меня не работает прога.
Re: MikroC и его баги
Добавлено: Сб авг 10, 2013 15:37:44
blackx
Не знаком с microc, но, может, нужно как в обычном ANSI C объявить переменные с модификатором unsigned?
Re: MikroC и его баги
Добавлено: Сб авг 10, 2013 15:51:34
dens
пробовал и unsigned int та же хрень, но заменил T1 на cnt так все встало на свои места
И я честно говоря так и не понял что это за косяк в mikroc, а может я туплю?
А в этом примере уже не прокатывает unsigned vrem определяется как signed int vrem
Код: Выделить всё
#define TSOP_pin GP2_bit
volatile char command, inv_command;
volatile long temp=0;
volatile char startusl=0, firstint=0;
volatile char bitcount=0; //
unsigned vrem; //
Re: MikroC и его баги
Добавлено: Сб авг 10, 2013 18:13:42
blackx
А как вы узнали, что ваша переменная определилась как знаковая? Ваш компилятор выдает предупреждение при занесении в переменную значения большего чем 32768?
Самый простой способ проверить - сравнением значения переменной с константой:
unsigned int vrem = 33000;
if( vrem > 32999 ) {
// тут зажигаем диодик
}
Если условие выполнится, значит переменная точно имеет беззнаковый тип.
Ну, или, чуть более сложный, но надежный способ - почитать ассемблерный код вашей программы и проверить какое именно значение константы заносится в память.
Re: MikroC и его баги
Добавлено: Сб авг 10, 2013 23:14:20
Аlex
а должон быть от 0 до 65535
А кто Вам это сказал ? Ссылку дайте на это утверждение.
Re: MikroC и его баги
Добавлено: Вс авг 11, 2013 07:31:58
oleg110592
корявый перевод документации:
Модификаторы signed и unsigned может быть применен как char и int . В отсутствие unsigned префикс, signed автоматически предполагается, для целых типов. Единственным исключением является char , который unsigned по умолчанию. Ключевые слова signed и unsigned , если они используются сами по себе, означает signed int и unsigned int соответственно.
http://www.mikroe.com/download/eng/docu ... _types.htm
Неправильное использование беззнаковых целых может приводить к неочевидным ошибкам из-за возникающего переполнения. В приведённом ниже примере использование беззнаковых целых в цикле в C и C++ превращает этот цикл в бесконечный:
Код: Выделить всё
char ar[N];
for (unsigned int i = N-1; i >= 0; --i)
ar[i] = i;
http://ru.wikipedia.org/wiki/%D0%A6%D0% ... B%D1%85%29
Re: MikroC и его баги
Добавлено: Вт авг 13, 2013 06:49:36
pcb432
Есть справка по микроси на русском.
Чио-то не вкладывается, наверное великоват.
Но можно найти в инете.
Re: MikroC и его баги
Добавлено: Ср мар 22, 2017 14:42:37
dens
Более менее ясно,а как тут быть?
long vrem;
char i = 2;
vrem = 65535*i;
Переменная vrem не становится равной 131070,но написав
vrem=65535*2 тогда становится.
Вот как это понимать?
Re: MikroC и его баги
Добавлено: Ср мар 22, 2017 15:16:25
ARV
dens писал(а):Вот как это понимать?
это понимать так: срочно скачивайте книжку по языку Си и читайте ее внимательно до полного просветления!
65535*i - здесь 65535 - это unsigned int, а i - char. по правилам Си оба операнда должны быть одного типа, причем наибольшего из них (а еще интересно, что два char
всегда приводится к двум int). то есть i приводится к unsigned int. по тем же правилам результат будет равен типу операнда, т.е. unsigned int. в таком типе не может помещаться больше, чем 65535.
65535*2 - это произведение констант. такие произведения вычисляются препроцессором ДО начала компиляции. при вычислениях скорее всего используется разрядность компьютерных Int-ов, поэтому получается константа 131070, которая уже законно имеет тип long и отлично помещается в переменную.
чтобы не было проблем с вычислениями вроде вашего 65535*i, используйте принудительное указание типа операнда больше, чем вам надо, например так:
65535 * (long)i. в этом случае переменная i вашими усилиями превратится в long, а потом 65535 тоже превратится в long, а потом произведение их тоже будет long, все в строгом соответствии с правилами Си.
но проще указать тип константы при помощи суффикса UL:
65535UL * i - в этом случае все будет то же самое, т.к. UL обозначает unsigned long
Re: MikroC и его баги
Добавлено: Ср мар 22, 2017 15:32:46
dens
Я догадывался, но вы расставили точки над i. Спасибо вам огромное. Век живи,век учись