ICC AVR и стpоки

27-Sep-03 04:07 Harry Zhurov wrote to Alexey Boyko:

HZ> extern int key; HZ> void f() HZ> { HZ> char buf[16]; HZ> long x = 5; HZ> ...

HZ> switch(key) { HZ> case 1: { HZ> ... // HZ> f1(); // функция, которая жрет много стека Какого из стеков? :-) HZ> } HZ> break; HZ> case 2: { HZ> int buf[32]; // буфер, который жрет много стека HZ> ... // HZ> } HZ> }

HZ> Сколько памяти нужно выделять? Если по твоей технологии, то нужно HZ> просмотреть всю функцию и выделить по максимуму: 16 + 1*4 + 32*2 = 84 Ну вот и пожалуйста, скомпили это свежим иаром. Так как 1.40 превосходно выделяет 80 байт на стеке в самом начале функции (long x селит в R7:R4). AVR кривой? Скомпили IAR/MSP430 (gcc/430 точно так же выделяет 80 байт в самом начале функции при помощи sub #80,r1). Аналогично поступает bcc32 от BC5.02, только число байт больше, так как int 4-байтный. Аналогично -- OpenWatcom/win32. Как это ни странно, но заморачиваться никто с таким не хочет (хотелось бы ошибиться), поэтому я давно стараюсь в таких случаях case 2: { f2(); // и пусть она жрёт стек, а тут будет сбалансировано } даже если эта f2() вызывается один раз отсюда и всё.

HZ> байта. В стеке. Но если поток управления пойдет по первой ветке, HZ> то выделять память под HZ> буфер во второй не нужно, и память эта может оказаться очень не лишней HZ> при HZ> вызове функции из первой ветки, которая (функция) тоже прилично хавает HZ> стека. Покажи мне, что это делает IAR на двух стеках (на Y как указателе стека, а не указателе кадра, это делается _очень_ легко) и я буду знать, что такой компилятор точно есть. Так как меня терзают сомнения -- я вроде бы видел компилятор, который модифицировал указатель стека по ходу заседания, но не помню какой и когда. А следил за этим строго :-), у меня очень частое явление даже без switch() foo() { uchar u; uchar buf[3]; ... { int i,j; ... } ... { uchar tmpbuf[5]; ... }

} именно для экономии стека.

Причём я уверенно помню, что _точно_ был компилятор, который для приведенного примера раcпределял не 9 байт на стеке (sizeof(int)==2), чего достаточно, так как i,j перекрываются с tmpbuf[], а все 13, просто сумму всех локальных переменных :-( Как бы это не DECUS C для PDP-11 (очень маленький и быстрый, но очень тупой и многого даже из K&R не умевший).

HZ> Понял, понял, но не могу признать это лучшим, чем использование Это не лучше, это просто "стандартно". Почему при портировании gcc на avr не попытались сделать два стека -- я не знаю. IMHO просилось. Возможно, это просто неудобно на нём.

HZ> стека для данных, как это сделано в ИАРе.

AB>> Если компилировать с опцией -mno-interrupt, тогда при сохранении SP, AB>> нет шаманства с SREG, а просто

HZ> Зато можно получить по полной программе в случае возникновения HZ> прерывания во время изменения SP. Надо быть полным идиотом, чтобы использовать -mno-interrupt в программе, в которой используются прерывания. За это НАДО получить, а не МОЖНО получить. Но, знаешь, как многие програмисты обходятся без C++, так же и многие программы обходятся без прерываний :-). Ну не нужны они там. Кроме того для AVR ещё есть -mtiny-stack, если даже на меге8 ручками разместить стек ниже 256-ого байта, то с этой опцией становится жить легче, установка нового заначения атомарна.

HZ> Будь он регистром, то просто обязан быть указателем. x86/16 Согласен, пример довольно кривой архитектуры, но как у него создаётся стековый кадр - тебе уже тут рассказывали. Если бы sp был указателем, то это было бы ненужным. Более того, на x86/32 по esp уже можно адресоваться, но по умолчанию часто делается стековый кадр на ebp (с сохранением старого ebp на стеке).

HZ>>> Причем тут 430-й? У него SP нормально сделан, он позволяет HZ>>> адресоваться любым штатным способом и косвенно, и со смещением, и HZ>>> адресная арифметика там работает, поэтому нет необходимости его HZ>>> значение куда-то копировать. Речь не [только] о том, надо копировать или нет, а о том, что его указательность _облегчает_ создание стекового кадра, не _не_устраняет_ необходимость этого действия. А то, что ты написал в прошлом письме с вопросом по AVR -- забыло о понятии стекового кадра.

HZ> А avr-gcc, вроде, позволяет заблокировать произвольное количество HZ> регистров от использования компилятором? А толку?

wbr, p.s. Как раз сегодня писал на ассемблере x86/32 процедуру (int64 * int64 + int64) / int64 с промежуточным результатами в int128. Как мало регистров у x86 :-( Особенно если нельзя ebp задействовать :-((

Reply to
Oleksandr Redchuk
Loading thread data ...

Alexey Boyko wrote to "Harry Zhurov" <Harry Zhurov on Sat, 27 Sep 2003 12:36:58

+0400:

HZ>> Будь А полноценным двумерным массивом - т.е. законченным, HZ>> целостным объектом, то выражение: HZ>> А + 1 HZ>> означало бы адрес следующего такого двумерного массива,

AB> Это эще почему? 'A' ведь не является указателем на объект, а есть сам AB> объект.

Да, наврал, прошу прощения?! Правильно объяснение такое: в операциях адресной арифметики имя массива неявно преобразовывается к указателю на первый элемент массива. Соответственно выражение:

А + 1

имеет семантику указателя на элемент массива и указывает на следующий элемент массива. Если, например, это простой массив целых, то указатель будет адресовать следующий после первого инт. В случае _двумерного_ массива непонятно, что такое "следующий элемент" - если в языке такие массивы поддерживаются, то должно быть четко специфицировано, что значит "следующий элемент", по какой координате его отсчитывать и т.д.

Но в любом случае С/С++ массив int A[n][m] ведет себя как:

typedef int [m] SubArray;

SubArray A[n];

AB> (Я не имею в виду, что в Си можно имя массива использовать как указатель)

В данном случае имя массива преобразовывается к указателю без чьего-либо согласия (по правилам языка), и вопрос возможности/невозможности использования не ставится.

HZ>> Hадеюсь, ты не будешь спорить с тем, что двумерный массив и массив HZ>> массивов - это разные вещи?

AB> Что то я в этом не уверен. Если массив разных массивов, тогда разница есть,

Массив - это агрегатный тип, состоящий из _одинаковых_ элементов. Соответственно, массивов с неодинаковыми элементами в С/С++ не бывает!

AB> но в Си нельзя без хаков объявить массив разных массивов.

Структура - это агрегатный тип, допускающий наличие разных элементов. Следовательно, "массив разных массивов" - это может быть структура. Но структура - _не_ массив!

HZ>> Вот теперь ты снова реши, в ту ли степь меня понесло или нет?! :)

AB> Тебя понесло в математическое философствование. Я же отношусь к массиву по AB> простому - по программистскому. ;)

Нет тут ни математики, ни философии - все одно только сплошное программирование в контексте С/С++, которые вполне четко определяют массивы. И детальное понимание таких вещей очень важно, иначе можно легко получить неожиданности.

AB>>> Вижу, ты очень сильно заплюсовался. Hикаких функций писать я не AB>>> предлагал. В массивах max, min, delta я предлагал хранить числа, а AB>>> не адреса функций. HZ>> Hу, тогда я вообще ничего не понял - как ты собираешься HZ>> реализовать ту функциональность, которая была приведена в том примере:

HZ>> // ---------------------------------- HZ>> ... HZ>> if( keySelect.IsClick() ) CurrentParameter++; HZ>> if( keyPlus.IsClick() ) CurrentParameter->Increase(); HZ>> if( keyMinus.IsClick() ) CurrentParameter->Decrease(); HZ>> ... HZ>> // ----------------------------------

HZ>> Как ты предлагаешь достичь того же без функций, а только с помощью HZ>> какого-то массива?

AB> дык я же вроде приводил кусочек кода.

AB> if (keySelect.IsClick()) // В данном случае я не рассматриваю опрос кнопок AB> CurrentParameter = (CurrentParameter+1) % ParameterCount; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | Крайне неэффективный способ по сравнению с обычной проверкой перехода через границу массива. Но тут писать явно код проверки - это еще более загромоздить этот фрагмент программы.

AB> if (keyPlus.IsClick()) { AB> if ((current[CurrentParameter] += delta[CurrentParameter]) >

AB> max[CurrentParameter]) { AB> current[CurrentParameter] = max[CurrentParameter]; AB> }

AB> if (keyMinus.isClick()) { AB> if ((current[CurrentParameter] -= delta[CurrentParameter]) < AB> min[CurrentParameter]) { AB> current[CurrentParameter] = min[CurrentParameter]; AB> } AB> }

Это код _совершенно_ функционально не эквивалентен варианту с функциями (не важно, на каком языке). Функция реально делает помимо увеличения/уменьшения еще кое-какую работу - например, для параметра "Температура" есть два источника данных - автоматическое измерение и ручной ввод. Автоматическое измерение используется до тех пор, пока оператор не ввел руками другое значение, после этого автоматическое измерение уже не используется. Вот там, если посмотреть, есть специальный флажок, который устанавливается в функциях TParamTemperature::Increase/TParamTemperature::Decrease, а при установленном флажке автоматически измеренные данные уже не записываются в значение параметра. У других параметров нет таких флажков, но могут быть свои внутренние дела, которые, помимо всего прочего, и реализуются соответствующей функцией.

Кроме того, функция Update почти для всех параметров используется для вывода значения на индикатор, но для последнего параметра (псевдопараметра) ParamSave, эта функция производит сохранение во флеш измененные значения параметров (чтобы зафиксировать изменения по окончании прохождения очереди).

Поэтому адекватную функциональность на С можно достичь только с помощью нескольких (по числу виртуальных функций) массивов указателей на функции, о чем и говорилось. Собственно, механизм виртуальных функций эту работу и делает, только все формализовано и автоматизировано, с контролем типов/ошибок.

И еще кстати - фрагменты кода (при том, что альтернативный вариант не реализует трубуемую фукнциональность) по читабельности просто несопоставимы!

AB> Я не предлагаю реализовывать функциональность С++ на Си. Просто на Си AB> принято по AB> другому писать.

AB> Видел GTK+? это реализация С++ функциональности на Си.

Зачем это, интересно, понадобилось добиваться этого.

AB> Жуткая штука.

Вот именно. Об этом я и твержу, что реализовать можно что угодно на любом языке, но без поддержки со стороны языка цена такой реализации часто оказывается слишком высокой!

AB> Hо работает.

Кто бы сомневался? Но как насчет развития/сопровождения?

...so long!

### С умным человеком приятно поговорить, но трудно работать.

Reply to
Harry Zhurov

Hello, Harry Zhurov !

Да элементарно. Или еще один массив с типами (если их не много) а потом switch по этому параметру, или switch прямо по индексу в массиве. И пиши себе в ветках обработку без всяких косвенных вызовов.

С уважением, Дима Орлов.

Reply to
Dima Orlov

Oleksandr Redchuk wrote to "Harry Zhurov" snipped-for-privacy@online.nsk.su> on Sat, 27 Sep 2003 18:54:32 +0000 (UTC):

HZ>> Сколько памяти нужно выделять? Если по твоей технологии, то нужно HZ>> просмотреть всю функцию и выделить по максимуму: 16 + 1*4 + 32*2 = 84 OR> Ну вот и пожалуйста, скомпили это свежим иаром. OR> Так как 1.40 превосходно выделяет 80 байт на стеке в самом начале функции OR> (long x селит в R7:R4). AVR кривой? OR> Скомпили IAR/MSP430 (gcc/430 точно так же выделяет 80 байт в самом начале OR> функции при помощи sub #80,r1).

Да, специально проверил, все они сразу выделяют. Хотя ничего не мешает оптимизировать - и в том, и в другом никаких противопоказаний для этого нет. Наверное это причина отписать кое-кому письмецо. :)

[...]

HZ>> А avr-gcc, вроде, позволяет заблокировать произвольное количество HZ>> регистров от использования компилятором? OR> А толку?

В реальном коде (я специально исследовал) половина регистров почти не используется, зато при переключении контекста таскать нужно все. Вот и смысл (я ведь не праздно интересуюсь :))!.

...so long!

### "Анна сошлась с Вронским совсем новым, неприемлемым для страны способом." (с) Из школьного сочинения.

Reply to
Harry Zhurov

Oleksandr Redchuk wrote to Alexey Boyko snipped-for-privacy@p4.f.n4624.z2.fidonet.org> on Sat, 27 Sep 2003 18:54:32 +0000 (UTC):

HZ>>> Как ты предлагаешь достичь того же без функций, а только с помощью HZ>>> какого-то массива?

AB>> дык я же вроде приводил кусочек кода.

AB>> if (keySelect.IsClick()) // В данном случае я не рассматриваю опрос

[...]

OR> Даже не так, а в таком духе (всё сложнее, это так, псевдокод).

OR> u08 key; OR> do {

[...]

OR> // и т.д.

OR> } while( key != KEY_ESC);

OR> На самом деле параметры описываются массивами структур во флеше, OR> массивами указателей на эти массивы и т.п. Всё инициализируется OR> статически, да, структура меню жёстко забита во флеше. OR> У каждого параметра в структуре описателя - его тип (int, byte, OR> string)

А что такое "увеличить/уменьшить" для строки? Я так понимаю, что имеется в виду обычная С-строка?

OR> , начальный адрес в EEPROM, длина (для строк), min и max значения (для OR> int/byte), после смены параметра по ещё одному небольшому switch() OR> вызывается нужная функция Edit() (и уже она делает GetKey() и разбирает OR> INC/DEC/CLR, по KEY_UP возвращается OR> на уровень перебора параметров). OR> Итого всё меню конфигурирования - это немножко кода OR> и таблицы констант, которые занимают _гораздо_ меньше места, чем OR> если бы это всё реализовывать в виде функций или кода по switch().

Экономия кода достигается исключительно за счет унификации модифицирования параметров. Это работает только когда параметры однокачественные (числа, например). Как только нужно кроме простого инкремента/декремента делать еще что-то разное для разных параметров, то и привет вашим массивам без функций.

OR> В некотором смысле машина состояний, заданная в виде таблиц переходов,

А чем принципиально отличается передача потока управления по таблице переходов от передачи оного по таблице указателей на функции? Таблицы указателей на функции, кстати, тоже один из способов реализации машины состояний (если кто-то очень любит машины состояний).

OR> И в итоге нет никаких многоэтажных switch, которые предлагается OR> заменить на виртуальные функции

И в итоге совсем не та функциональность, как и положено. Как где-то у Страуструпа было написано: "Чтобы оценить мощь указателей на функции, нужно попытаться сделать то, где они применяются, без них".

OR> и (всё равно!) массив указателей на экземпляры классов Parameter, по OR> которому ходит указатель CurrentParameter.

А чем оно тебе так не нравится? Уж по читабельности, понятности и логичности вариант с простым линейным массивом однокачественных объектов куда как лучше, чем даже тот кусок псевдокода (а уж что там за монстр в конечной реализации, можно только представить!)

Убежден, что ты все это знаешь лучше меня, и тем более не понятно, с чем ты тут споришь?

AB>> Просто на С принято по другому писать. OR> Вот именно. И, самое главное, это все не есть "попытка эмуляции ^^^^^^^^^^^^^ OR> средствами C поведения C++".

:)) Так это, оказывается, принципиальная позиция?! Хотя тут и нет ни попытки эмуляции, ни самой эмуляции - тут нет, самое главное, того же результата по функциональности, который дают самые обычные массивы указателей на функции. Т.ч. сравнивать просто нечего.

...so long!

### Чтобы был тонкий юмор, нужны толстые знания.

Reply to
Harry Zhurov

Harry Zhurov wrote to Alexey Boyko on Sun, 28 Sep 2003 06:00:59 +0000 (UTC):

HZ> Но в любом случае С/С++ массив int A[n][m] ведет себя как:

HZ> typedef int [m] SubArray;

Пардон, тут замкнуло, правильно, конечно, так:

typedef int SubArray[m];

HZ> SubArray A[n];

...so long!

### Состав сводной команды: бульдозер, компрессор, автокран...

Reply to
Harry Zhurov
28-Sep-03 11:02 Harry Zhurov wrote to Oleksandr Redchuk:

OR>> На самом деле параметры описываются массивами структур во флеше, OR>> массивами указателей на эти массивы и т.п. Всё инициализируется OR>> статически, да, структура меню жёстко забита во флеше. OR>> У каждого параметра в структуре описателя - его тип (int, byte, OR>> string)

HZ> А что такое "увеличить/уменьшить" для строки? Я так понимаю, что HZ> имеется в виду обычная С-строка? Ну я же сказал сразу, что это "так, наляпано", а на самом деле на этом уровне только навигация, редактирование вызывается отсюда:

OR>> , начальный адрес в EEPROM, длина (для строк), min и max значения (для OR>> int/byte), после смены параметра по ещё одному небольшому switch() OR>> вызывается нужная функция Edit() (и уже она делает GetKey() и разбирает OR>> INC/DEC/CLR, по KEY_UP возвращается OR>> на уровень перебора параметров). А inc/dec применяются не к строке, а к символу (а как ещё отредактировать текстовую строку пятью кнопками :-).

OR>> Итого всё меню конфигурирования - это немножко кода OR>> и таблицы констант, которые занимают _гораздо_ меньше места, чем OR>> если бы это всё реализовывать в виде функций или кода по switch().

HZ> Экономия кода достигается исключительно за счет унификации модифицирования HZ> параметров. Это работает только когда параметры однокачественные (числа, HZ> например). Ну, во первых,

18 Sep 03 21:46, you wrote to Dimmy Timchenko: HZ> // ---------------------------------- HZ> ... HZ> if( keySelect.IsClick() ) CurrentParameter++; HZ> if( keyPlus.IsClick() ) CurrentParameter->Increase(); HZ> if( keyMinus.IsClick() ) CurrentParameter->Decrease(); HZ> ... HZ> // ---------------------------------- в приведённом примере тоже как-то параметры могут только увеличиваться и уменьшаться, достаточно ограниченная модель. А когда тебе это написали на C, ты сразу "ну так это ограниченное решение!".

А во-вторых - ты не вчитался. Повторяю. Каждый параметр описывается структурой, в которой кроме его положения в EEPROM задан его тип. По типу мы можем вызвать нужную функцию редактирования. Экономия кода заключается в том, что сам вызов функций чтения и записи EEPROM при редактировании конфигурации имеется в одном единственном месте, т.е. не в каждой виртуальной функции каждого параметра (группы параметров с одинаковым редактированием).

Вместо

CurrentParameter->Load(); // косвенный вызов через vmt // у каждого параметра персонально SomeParameter::Load() { EEread( this, смещение, длина); }

имеем eeparam *parptr = &eep_table[parmano]; // ptr будет использован много раз ниже, при редактировании, // проверке и записи назад EEread( editbuf, parptr->offset, parptr->len); // editbuf - буфер в функции конфигурирования размером с самый // длинный параметр

Аналогично с вызовом редактирующей функции, аналогично с проверкой на min/max для целочисленных параметров -- этот код в единственном месте для всех таких параметров. Из структуры-описателя параметра берутся его min и max значения.

HZ> Как только нужно кроме простого инкремента/декремента делать HZ> еще HZ> что-то разное для разных параметров, то и привет вашим массивам без HZ> функций. Зависит от того, сколько вариантов этого "что-то разное". Будет или switch( parptr->type) { case PARAM_INT: case PARAM_STRING: или (param_editors[parptr->type])( )

OR>> В некотором смысле машина состояний, заданная в виде таблиц переходов,

HZ> А чем принципиально отличается передача потока управления по таблице HZ> переходов от передачи оного по таблице указателей на функции? Принципиальной разницы нет, ты назвал две вещи, которые практически одинаковы (переходы по индексам из массива и переходы по адресам из массива). И обе эти вещи не используются в такой организации меню вообще. В случае с несколькими страницами параметров по кучке параметров в каждом передачи потока управления не происходит. В данном случае "граф" переходов машины примитивен и реализуется на ++parampage

--parampage ++paramno --paramno. В массивы забиты не переходы, а действия в состояниях -- и то не все, действие EEread производится каждом, поэтому в массиве для этого действия хранится информаация "где и сколько".

HZ> И в итоге совсем не та функциональность, как и положено. По сравнению с чем? А то ты уже писал пример для Тимченко, тебе изобразили решение на массивах на C, а вышло "не та функциональность". Перечисли нужную функциональность _ДО_ того, как тебе напишут пример на C.

HZ> Как где-то у HZ> Страуструпа было написано: "Чтобы оценить мощь указателей на функции, А то я не знаю, какая это классная штука, особенно если она на процессоре легко реализуема.

HZ> нужно попытаться сделать то, где они применяются, без них". Знаешь, система меню редактрования параметров может обойтись без указателей на функции очень легко. Сейчас в однокристалках я "вспомнил" подход, который применял для построения многоуровневых иерархических меню в бытность на ДВК. На VT100. А когда в лаборатории появился "Невроз И9.66" и кто-то из не видевших до этого ничего студентов что-то ляпнул в сторону ДВК в духе "этот гроб" - я сел и переделал на ДВК это меню в "как у нортона", да в окошке график вывел, а там КЦГД был, а это 800 по горизонтали :-) Вот там в "активной" части указатели на функции были, а вот при редактировании параметров -- ну не нужны они. Без них код меньше был, несмотря на то, что на PDP работа с указателями превосходна. А мне это жгло, памяти-то 56КБ было на всех с операционкой.

HZ> А чем оно тебе так не нравится? Уж по читабельности, понятности и HZ> логичности вариант с простым линейным массивом однокачественных объектов HZ> куда как лучше, А вот тут я скажу "функциональность не та" :-) У меня там несколько страниц параметров, с разным числом параметров на странице :-))

HZ> чем даже тот кусок псевдокода (а уж что там за монстр в HZ> конечной реализации, можно только представить!) Программа, которая на ДВК вводила картинки с моего контроллера, легонько обрабатывала их (некоторое количество фильтров, гистограмма, яркость/контраст), вырезала куски, показывала на монохромном мониторе (с дизерингом) - вместе с движком меню и его содержимым была около 1100 строк. Правда, с малым довльно количеством комментариев и с форматированием if() { } else { } for(;;) { } и т.д. На 24 строках и при медленных матричниках с постоянным дефицитом бумаги делать if () { } else { } // внимание - пустая строка for() { } жаба давила.

Я тогда страшно гордился тем, какие большие программы я пишу :-)

HZ> Убежден, что ты все это знаешь лучше меня, и тем более не понятно, с HZ> чем ты тут споришь? Я, излагая своё видение, пытаюсь понять - о чём мы спорим :-) Первый момент кажется ясен: Ты считаешь, что C++ можно и НУЖНО применять всем и вплоть до самых мелких программ. Я считаю, что даже на средних программах его стоит применять только тем, кто и так "по жизни" без него не может обойтись, а уж на мелких задачах переходить на него только потому, что он имеет (длинный список) преимуществ на очень больших проектах -- смысла не вижу.

Вторая точка, похоже, сформулирована Алексеем. AB>>> Просто на С принято по другому писать. OR>> Вот именно. И, самое главное, это все не есть "попытка эмуляции HZ> ^^^^^^^^^^^^^ OR>> средствами C поведения C++". HZ> :)) Так это, оказывается, принципиальная позиция?! Ну раз ты обычное и стандартное от рождения языка C упрятывание от пользователя ненужных ему внутренних переменных и функций (а заодно уменьшение размера объектников и сокращение времени работы линкера) при помощи static обозвал "попыткой средствами С проэмулировать поведение C++" -- я считаю своим долгом этот момент особо отмечать :-)))

HZ> попытки эмуляции, ни самой эмуляции - тут нет, самое главное, того же HZ> результата по функциональности, который дают самые обычные массивы HZ> указателей на функции. Т.ч. сравнивать просто нечего. Ну уж не волнуйся. Там, где я считаю указатели на функции осмысленными -- я их применяю. А через период пихания их, очень мне понравивщихся, во все дыры - я прошёл довольно давно. Сейчас уже (mode ? func1 : func2) (param1, param2, param3); или (mode ? struct1 : struct2)->func(param1, param2, param3); не пишу :-) И могу оценить где они нужны, а где надо написать небольшой "движок" а его функциональность забить в массив структур или отдельные массивы. И движок обеспечит навигацию по сложному многоуровневому меню без указателей на функции (за исключенем тех мест, где вызывается действие). А задано всё меню будет при помощи статически инициализированных массивов структру, ссылающихся на другие массивы структур, отдельные структуры, строки и массивы строк. И увидеть на распечатке структуру получившегося меню гораздо проще, чем продираться сквозь menu1.addItem( new menuitem(..., ..., ..., ...) ) не говоря уже о гораздо более коротком коде. Это выходило что-то типа .rc-файла при программировании в винде. (только, чесслово, оно не пыталось его эмулировать :-))

wbr, p.s. кстати, о функциональности. awk, а тем более perl имеют ГОРАЗДО БОЛЬШИЕ возможности, чем sed. Но у меня на машине есть и awk, и sed (перла нет, нужды для себя пока не вижу). Но почему-то я в подавляющем большинстве случаев вызываю sed. Странно, ведь у awk-а то функциональность ого-го...

Reply to
Oleksandr Redchuk

Oleksandr Redchuk wrote to "Harry Zhurov" snipped-for-privacy@online.nsk.su> on Sun, 28 Sep 2003 18:00:52 +0000 (UTC):

[...]

OR> 18 Sep 03 21:46, you wrote to Dimmy Timchenko: HZ>> // ---------------------------------- HZ>> ... HZ>> if( keySelect.IsClick() ) CurrentParameter++; HZ>> if( keyPlus.IsClick() ) CurrentParameter->Increase(); HZ>> if( keyMinus.IsClick() ) CurrentParameter->Decrease(); HZ>> ... HZ>> // ---------------------------------- OR> в приведённом примере тоже как-то параметры могут только увеличиваться OR> и уменьшаться, достаточно ограниченная модель. А когда тебе это OR> написали на C, ты сразу "ну так это ограниченное решение!".

OR> А во-вторых - ты не вчитался. Повторяю. Каждый параметр описывается OR> структурой, в которой кроме его положения в EEPROM задан его тип. OR> По типу мы можем вызвать нужную функцию редактирования.

[...]

OR> Это выходило что-то типа .rc-файла при программировании в винде. OR> (только, чесслово, оно не пыталось его эмулировать :-))

Все, утомился я тут спорить - затрачиваемые на это силы и время не адекватны результату. Такие вещи надо очно выяснять, слишком много тут частностей, в переписке все не обсудишь, тем более, что есть чем заняться. (Подозреваю в этом моменте вздох облегчения с твоей стороны! :))

OR> wbr, OR> p.s. кстати, о функциональности. OR> awk, а тем более perl имеют ГОРАЗДО БОЛЬШИЕ возможности, чем sed. OR> Но у меня на машине есть и awk, и sed (перла нет, нужды для себя OR> пока не вижу). Но почему-то я в подавляющем большинстве случаев OR> вызываю sed. Странно, ведь у awk-а то функциональность ого-го...

А я вот перешел. Задачи-то те же, простенькие вполне, но реализовывать их на awk проще. Из однозначно полезного, что упрощает работу, это явно выраженные секции начала и окончания (BEGIN, END), "человеческие" операторы управления (if, for etc) и предварительный разбор строки на элементы, когда к ним можно обращаться как $n, где n - номер элемента в строке. Все это весьма упрощает работу, так почему бы не пользоваться? Из соображений, что "все это можно и на SED'е сделать?" :)))

...so long!

### Убегая от бандитов, милиционер Грищенко выстрелил три раза задом...

Reply to
Harry Zhurov

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.