Страница 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 так все встало на свои места

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

unsigned  p, 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. Спасибо вам огромное. Век живи,век учись