Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Помогите новичку
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
masterpc
Подскажите, что может быть:

Пишу вот так:

byte k;
while(k=0, k<9, k++) sens[0][k]=0xff;


Ничего в массив не пишется,
а если написать так:

sens[0][0]=0xff;
sens[0][1]=0xff;
sens[0][2]=0xff;
sens[0][3]=0xff;
sens[0][4]=0xff;
sens[0][5]=0xff;
sens[0][6]=0xff;
sens[0][7]=0xff;
sens[0][8]=0xff;
- то все ок.

на самом деле такого не нужно в проге, это я с глюком разобраться не могу.

Спасибо!
KRS
А как сам массив описан?
IAR особенно при включенной оптимизации, если массив больше не используется может выкинуть присавивание... помогает volatile
CSB
У меня в IAR 3.42A правильно работает так:
Код
int k;

k = 0;
while(k < 9)
{
    sens[0][k] = 0xff;
    k++;
};


Цитата
В цикле
while (выражение)
инструкция

вычисляется выражение. Если его значение отлично от нуля, то выполняется инструкция, и вычисление выражения повторяется. Этот цикл продолжается до тех пор, пока выражение не станет равным нулю, после чего вычисления продолжатся с точки, расположенной сразу за инструкцией.

Brian W. Kernighan, Dennis M. Ritchie
The C programming Language
VladimirYU
Цитата(masterpc @ Jan 17 2008, 12:24) *
Подскажите, что может быть:

Пишу вот так:

byte k;
while(k=0, k<9, k++) sens[0][k]=0xff;


Ничего в массив не пишется,


По смыслу должно быть
for ( k=0; k<9; k++) sens[0][k] = 0xff;
masterpc
Вот такая запись помогла:

byte k=0;
while(k<9){
sens[0][k]=0xff;
k++;
}


Видно это из-за двухмерного массива, потому как запись while (k=0, k<9, k++) инструкция; тоже верна, но для одной инструкции. По крайней мере с одномерным массивом все нормально.
Всем спасибо за помощь!!!!
KRS
Цитата(masterpc @ Jan 17 2008, 12:11) *
Вот такая запись помогла:

byte k=0;
while(k<9){
sens[0][k]=0xff;
k++;
}


Видно это из-за двухмерного массива, потому как запись while (k=0, k<9, k++) инструкция; тоже верна, но для одной инструкции. По крайней мере с одномерным массивом все нормально.
Всем спасибо за помощь!!!!

VladimirYU ПРАВ!
у вас , вместо ;
это очень грубая ошибка
masterpc
Цитата(KRS @ Jan 17 2008, 11:26) *
VladimirYU ПРАВ!
у вас , вместо ;
это очень грубая ошибка


С ";" компилятор ругается, но это уже не важно, главное, что работает , ведь самая правильная прога это та, которая работает smile.gif
CSB
С одномерным массивом Ваш вариант "while (k=0, k<9, k++) инструкция;" тоже не будет работать, не от размерности массива зависит условие выполняемости цикла.

Для while:
(k=0, k<9, k++) - это все 0, т.е. инструкция не выполнится
(k=0, k<9, ++k) - а это будет 1

Пишите нормальные конструкции и Вас все будет работать.
KRS
Цитата(masterpc @ Jan 17 2008, 12:32) *
С ";" компилятор ругается, но это уже не важно, главное, что работает , ведь самая правильная прога это та, которая работает smile.gif

Конечно ругается, потому что там еще и for должен быть.
andrew_b
Цитата(CSB @ Jan 17 2008, 12:35) *
(k=0, k<9, ++k) - а это будет 1
И в итоге бесконечный цикл...
CSB
>И в итоге бесконечный цикл...
Именно. Я же не сказал что эта конструкция рабочая, я просто показал что нужно для выполнения тела цикла.
Сергей Борщ
Цитата(KRS @ Jan 17 2008, 12:01) *
Конечно ругается, потому что там еще и for должен быть.
Зато совсем скоро мы сможем услышать, что циклы for() применять нельзя, потому что они "глючат", а надо while().
KRS
Когда я быстро просматривал текст строчки
Код
byte k;
while(k=0, k<9, k++) sens[0][k]=0xff;


мой глаз воспринял как
Код
byte k;
for(k=0; k<9; k++) sens[0][k]=0xff;

Что у меня и вызвало удивление, в IAR такая конструкция может не работать из-за оптимизации если значения не используются потом...

Судя по всему именно это и хотел сказать автор.
Baser
Цитата(masterpc @ Jan 17 2008, 11:32) *
С ";" компилятор ругается, но это уже не важно, главное, что работает , ведь самая правильная прога это та, которая работает smile.gif

Судя по всему автор так и не понял, какую он ахинею написал smile.gif
Попробую разъяснить еще раз, хотя уже вроде бы все написано.

while (k=0, k<9, k++) инструкция;
Такая конструкция вполне допустима исходя из синтаксиса языка Си, но она не имеет смысла.
Применение запятых в условии цикла while говорит о следующих друг за другом условиях.
Компилятор будет делать следующее:
1. присвоит значение k=0
2. проверит условие k<9, оно будет истинным - true
3. проверит значение k, оно будет ложным (k=0), и тело цикла не будет выполняться ни разу
4. увеличит значение k++, посколько постинкремент

А правильная конструкция, как уже написали:
for (k=0; k<9; k++) инструкция;
masterpc
Цитата(Baser @ Jan 17 2008, 13:20) *
А правильная конструкция, как уже написали:
for (k=0; k<9; k++) инструкция;


Виноват , сам уже потом понял. Я и раньше так писал, но забыл. Спасибо!
Сергей Борщ
Цитата(Baser @ Jan 17 2008, 13:20) *
Применение запятых в условии цикла while говорит о следующих друг за другом условиях.
Нет, совсем нет. Результатом этих следующих друг за другом выражений будет значение последнего выражения. Именно результат k++ будет проверяться в цикле. Остальные два с тем же успехом можно было вынести из скобок в тело цикла.
P.S. для меня конструкции с запятыми тоже нечто неестественное. ReAl их хорошо понимает и удачно использует.
CSB
>Именно результат k++ будет проверяться в цикле.
Возможно я не правильно понял что Вы имели ввиду под "результат k++", но в цикле будет проверятся k до инкрементирования и лишь потом будет увеличение на 1. Т.е. k до инкремента было нуль и поэтому условие не выполнилось. После выхода из цикла оно увеличится на 1.
Сергей Борщ
Цитата(CSB @ Jan 17 2008, 15:56) *
Возможно я не правильно понял что Вы имели ввиду под "результат k++",
То, что понимают под этим K&R и стандарт языка С. Результатом выражения "k++" является значение k до выполнения этого выражения. То, что после этого выражения k увеличится на 1 - всего лишь "побочный эффект" этого выражения. Также как результатом выражения a = b является значение b, а тот факт, что после выполнения этого выражения то же самое значение оказывается в a - "побочный эффект", как бы парадоксально это не было smile.gif

Вдруг подумалось - а как компилятор вообще пропустил конструкцию for(,,) и не выругался на отсутствие там ";"?
Baser
Цитата(Сергей Борщ @ Jan 17 2008, 16:42) *
Вдруг подумалось - а как компилятор вообще пропустил конструкцию for(,,) и не выругался на отсутствие там ";"?

Не волнуйся, Сергей, на for(,,) компилятор ругается троекратно smile.gif
а while(,,) в общем случае допустимая конструкция.
Сергей Борщ
Цитата(Baser @ Jan 17 2008, 19:25) *
Не волнуйся, Сергей, на for(,,) компилятор ругается троекратно smile.gif
Вот и я такое помню, а в корневом посте жалоба на "не пишется", а не на "не компилится". Где-то нас на... обманули wink.gif
KRS
Цитата(Сергей Борщ @ Jan 17 2008, 20:53) *
Вот и я такое помню, а в корневом посте жалоба на "не пишется", а не на "не компилится". Где-то нас на... обманули wink.gif

Это я ввел в заблуждение, мой глаз при быстром просмотре воспринял сстрочку
while(,,) как for(;;)

Но как признался автор, именно это он и хотел написать.
Цитата(masterpc @ Jan 17 2008, 14:29) *
Виноват , сам уже потом понял. Я и раньше так писал, но забыл. Спасибо!
VladimirYU
С запятыми в IAR AVR вообще интересная штука. Начиная с 4 версии в режиме С++ спокойно компилятором глотается запятая вместо классической точки запятой. Вопрос - это стандарт или особенность IAR. Оригинала стандарта под рукой нет.
Сергей Борщ
Цитата(VladimirYU @ Jan 18 2008, 07:58) *
Начиная с 4 версии в режиме С++ спокойно компилятором глотается запятая вместо классической точки запятой
Возможно вы просто не знали, что в С и С++ существует оператор "запятая". Вот что нам пишут о нем K&R в главе 3:
Цитата
Последней операцией языка "C" является запятая ",", которая чаще всегоиспользуется в операторе for. Два выражения, разделенные запятой,вычисляются слева направо, причем типом и значением результата являются тип и значение правого операнда. Таким образом, в различные части оператора for можно включить несколько выражений, например, для параллельного изменения двух индексов. Это иллюстрируется функцией reverse(s), которая располагает строку s в обратном порядке на том же месте.

Запятые, которые разделяют аргументы функций, переменные в описаниях и т.д., не имеют отношения к операции запятая и не обеспечивают вычисленийслева направо.
Оператор "запятая" может применяться и вне циклов. Не удержусь и приведу пример, который в 2002 ReAl выкладывал в ru.embedded. Я периодически медитирую над этим куском кода, но "почувствовать" его до конца пока не могу:
Цитата
У меня время от времени встречаются вещи типа
Код
   if(  ( func1(), condition1 )
     || ( func2(), condition2 )
     || ( func3(), condition3 )
   ) {
      some_error_processing;
   }
которые без запятой приходилось бы писать как
Код
   func1();
   if( condition1 ) {
      some_error_processing;
   } else {
      func2();
      if( condition2 ) {
         some_error_processing;
      } else {
         func3();
         if( condition3 ) {
           some_error_processing;
         }
      }
   }
Или как-то по другому, но все равно многоэтажная конструкция.
На _мой_ взгляд - через запятую это гораздо нагляднее и управляемее.
Я считаю, что такая запись как раз уменьшает размер глюкодрома, хотя
многие ругают С как раз за возможность такого рода записей :-)

IMHO и
Код
  while( small_code, condition) {
    code;
  }
выглядит лучше, чем
Код
  small_code;
  while( condition) {
    code;
    small_code;
  }
так как в первом варианте четче прослеживается связь между
small_code и проверкой условия, а также то, что small_code должен
выполняться перед code, что это не завершающие операции code, а
предшествующие проверке.


P.S. Надеюсь, ReAl не обидится на меня за цитирование без разрешения.
VladimirYU
А если вне циклов, найдите отличия:
Классика:
94 InputBuffer[0] = 0xab;
\ 0000002A EA0B LDI R16, 171
\ 0000002C 01FD MOVW R31:R30, R27:R26
\ 0000002E 8305 STD Z+5, R16
95 InputBuffer[1] = 0x55;
\ 00000030 E505 LDI R16, 85
\ 00000032 01FD MOVW R31:R30, R27:R26
\ 00000034 8306 STD Z+6, R16

Запятая:
94 InputBuffer[0] = 0xab,
95 InputBuffer[1] = 0x55;
\ 0000002A EA0B LDI R16, 171
\ 0000002C 01FD MOVW R31:R30, R27:R26
\ 0000002E 8305 STD Z+5, R16
\ 00000030 E505 LDI R16, 85
\ 00000032 01FD MOVW R31:R30, R27:R26
\ 00000034 8306 STD Z+6, R16

Я имел в виду именно такой случай.
Сергей Борщ
Цитата(VladimirYU @ Jan 18 2008, 11:25) *
А если вне циклов, найдите отличия:
Я имел в виду именно такой случай.
Не вижу криминала. Использование оператора "запятая" в этом месте допустимо. Ваша запись представляет собой два выражения. В первом случае они разделены точками последовательности (sequence points), во втором случае - объединены оператором "запятая". В обоих случаях результаты этих выражений не используются, поэтому имеем идентичный сгенерированный код вычисления этих выражений.
ReAl
Цитата(VladimirYU @ Jan 18 2008, 11:25) *
А если вне циклов, найдите отличия:
Классика:
InputBuffer[0] = 0xab; InputBuffer[1] = 0x55;
Запятая:
InputBuffer[0] = 0xab, InputBuffer[1] = 0x55;
smile.gif
Я и так могу написать, и код будет абсолютно такой же
Код
    switch( InputBuffer[0] = 0xab)   {
    default:
        InputBuffer[1] = 0x55;
    }
ну и что с того?
Да, некоторые конструкции в некоторых случаях железно "ничего не делают".
Это не означает, что их стоит в этих случаях применять.
Оператор запятая свой левый операнд вычисляет, но результат отбрасывает. Реально выполняются только побочные эффекты вычисления.
Собственно,
Код
InputBuffer[1] = 0x55;
делает то же самое - выполняется побочное дейстиве вычисления присваивающего выражения (занесение результата в левый операнд), а его результат в данной строке отбрасывается. Только поэтому в данном месте эффект от запятой и от точки с запятой одинаковый.

Вот в switch( InputBuffer[1] = 0x55 ) результат присваивающего выражения анализируется, а не только побочный эффект работает.
А в этом выражении
Код
a + b;
и результат отбрасывается, и побочных действий нет (если a и b не квалифицированы как volatile-объекты), поэтому в итоге код вообще не генерируется.


Цитата(VladimirYU @ Jan 18 2008, 11:25) *
Я имел в виду именно такой случай.

Этот?
Цитата(VladimirYU @ Jan 18 2008, 07:58) *
С запятыми в IAR AVR вообще интересная штука. Начиная с 4 версии в режиме С++ спокойно компилятором глотается запятая вместо классической точки запятой.
Как уже написал Сергей - "запятая" столь же "классическая" в С, как и "точка с запятой"
Если IAR более ранних версий указанные выше два примера (названных как "классика" и "запятая") компилировал в разный по действию код или ругался, то он был просто очень не прав. Так как эти варианты обязаны давать одинаковые действия и компилировались одинаково любым С-компилятором под "Электронику-60" много лет назад.
Запятая - интересный и иногда очень удобный оператор, но писать его где попало из понту или "а чтобы была только одна ';' на строке" - это... Даже слов не нахожу.
VladimirYU
Цитата(ReAl @ Jan 18 2008, 14:49) *
Запятая - интересный и иногда очень удобный оператор, но писать его где попало из понту или "а чтобы была только одна ';' на строке" - это... Даже слов не нахожу.


Спасибо за разъяснения.
Freeze Anti
я извиняюсь... прочитал тут дискуссию и не понял одного... вы тут говорите о запятых и точках с запятыми... но... разве в выражении (если бы цикл и выполнялся)

while(k=0, k<9, k++) sens[0][k]=0xff;

не происходило бы постоянное присваивание k=0?.. ведь даже если мы сделаем

while(k=0, k++, k<9) sens[0][k]=0xff;

у нас все равно не должно произойти заполнения массива... мы просто получили бесконечный цикл... или я не прав?
CSB
Цитата
(k=0, k<9, k++) - это все 0, т.е. инструкция не выполнится
(k=0, k<9, ++k) - а это будет 1

во втором случае бесконечный цикл.

Цитата
while(k=0, k++, k<9) sens[0][k]=0xff;
- это тоже вечный цикл
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.