реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Множественный выбор, оператор switch, язык С
Aneg
сообщение Dec 21 2010, 17:26
Сообщение #1





Группа: Новичок
Сообщений: 5
Регистрация: 19-12-09
Пользователь №: 54 346



Программирую на С для микроконтроллеров AVR.
Насколько большим может быть этот множественный выбор у оператора switch? Сделал пробный вариант программы на 20 вариантов выбора - работает, а вот на 256 - нет не работает. А нужно сделать выбор для 1024 вариантов. А как поступить в этом случае?
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Dec 21 2010, 17:57
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Упаси вас и сохрани от таких программ! Подумайте, зачем вам это надо. Почти всегда можно придумать что-то взамен.
Go to the top of the page
 
+Quote Post
_dem
сообщение Dec 21 2010, 18:10
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



Switch реализуется через near jump, то есть ограничен +- 127 байт (поправьте, если забыл sm.gif ).

А чем таблица функций не угодила ?
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 21 2010, 18:15
Сообщение #4


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Aneg @ Dec 22 2010, 00:26) *
а вот на 256 - нет не работает. А нужно сделать выбор для 1024 вариантов.

Вы забыли рассказать, что за компилер и что за целевой камень, и что значит "не работает"
Цитата(sergeeff @ Dec 22 2010, 00:57) *
Упаси вас и сохрани от таких программ! Подумайте, зачем вам это надо. Почти всегда можно придумать что-то взамен.

Protothreads не в счет? biggrin.gif
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Dec 21 2010, 18:27
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Ну и где там switch на 256 case?
Go to the top of the page
 
+Quote Post
Aneg
сообщение Dec 21 2010, 18:31
Сообщение #6





Группа: Новичок
Сообщений: 5
Регистрация: 19-12-09
Пользователь №: 54 346



Компилятор: ICCV7 for AVR (http://www.imagecraft.com/), целевой камень ATmega16.
С помощью АЦП оцифровываю напряжение, пока ограничился на 256 уровнях (8 бит). Далее это значение передается по COM порту в виде 3-х байт ASCII кода. Выбор на switch применяю для перехода от 1-байтового значения к 3-м байт ASCII кода.

Сообщение отредактировал Aneg - Dec 21 2010, 18:35
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Dec 21 2010, 18:44
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



С ума сойти можно.

Код
char buf[4];

char inp;             // значение из АЦП
itoa(inp, buf, 10); // библиотечная функция, см. http://ru.wikipedia.org/wiki/Itoa_%28%D0%A1%D0%B8%29
send_to_port(buf, strlen(buf));


Все!!! Никаких switch/case.

или если надо точно 3 байта ASCII

Код
int n = sprintf(buf, "%03d", inp);
send_to_port(buf, n);
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 21 2010, 19:25
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (sergeeff @ Dec 21 2010, 23:44) *
или если надо точно 3 байта ASCII
А у него через switch() быстрее было! wink.gif


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 21 2010, 22:09
Сообщение #9


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(sergeeff @ Dec 22 2010, 00:27) *
Ну и где там switch на 256 case?

bb-offtopic.gif это уж зависит от сложности реализуемого алгоритма. Можно и на 1024 и больше sm.gif если психануть.
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Dec 22 2010, 01:49
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



Если в switch больше 10...20 вариантов (в зависимости от обрабатываемых значений), то я преобразую выбор через таблицу (даже вызов функций). Табличный метод выбора из большого числа значений гораздо выгоднее и по количеству используемой памяти, и по скорости выбора вырианта (всегда одинаковое фиксированное время выбора варианта)
Go to the top of the page
 
+Quote Post
_dem
сообщение Dec 22 2010, 03:13
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



Продолжим фантазировать sm.gif
Цикл опущен специально .

unsigned char ADCValue = ADC_Read(xxx);

USART_Send( ADCValue / 100 );

ADCValue = ADCValue % 100;
USART_Send( ADCValue / 10 );

ADCValue = ADCValue % 10;
USART_Send( ADCValue );
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Dec 22 2010, 03:46
Сообщение #12


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Код
const char ascii_value_table[3][256] = {
"000","001", ... "256"
}

Как-то так...
Если не так, поправьте, пожалуйста, некогда думать, да и лень


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 22 2010, 03:50
Сообщение #13


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(_dem @ Dec 22 2010, 10:13) *
Продолжим фантазировать sm.gif

Скачайте хоть какую-нить мудрую книжку себе типа такого прежде чем смешить новизной подхода.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Dec 22 2010, 03:50
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(Сергей Борщ @ Dec 22 2010, 02:25) *
А у него через switch() быстрее было! wink.gif


Я привел пару примеров только для того, чтобы человек не зацикливался на switch/case. Ясно, что его задачу можно решить еще десятком разных вариантов с разным соотношением скорость/объем кода.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 22 2010, 03:51
Сообщение #15


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(MrYuran @ Dec 22 2010, 10:46) *
Как-то так...
Если не так, поправьте, пожалуйста, некогда думать, да и лень

... и еще и быстрее будет, чем switch() lol.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 22 2010, 04:08
Сообщение #16


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (MrYuran @ Dec 22 2010, 08:46) *
CODE
const char ascii_value_table[3][256] = {
"000","001", ... "256"
}

Как-то так...
const char ascii_value_table[4][256]. И действительно быстрее. И компактнее. Аплодисменты!


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
_dem
сообщение Dec 22 2010, 04:11
Сообщение #17


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



Цитата(_Pasha @ Dec 22 2010, 09:50) *
Скачайте хоть какую-нить мудрую книжку себе типа такого прежде чем смешить новизной подхода.


Почитайте какую-нибудь мудрую инструкцию типа этой , прежде чем открывать эти ваши Интернеты sm.gif
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Dec 22 2010, 04:14
Сообщение #18


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Автору эти три байта через com-порт наружу передавать и зачем там супер скорость преобразования char->ascii? А 1К под таблицу это не накладно ли будет?
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 22 2010, 04:18
Сообщение #19


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(_dem @ Dec 22 2010, 10:11) *

Ну вот, Вы - хамить, а я Вам -про преобразование в десятичный код методом сдвига... не помню страницу. Досвидоз!
Go to the top of the page
 
+Quote Post
ReAl
сообщение Dec 22 2010, 04:41
Сообщение #20


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



И компактнее :-D — строки всё равно место занимают, а кода меньше даже при табличной реализации switch :-)

_dem
По поводу операций / % — «если уж так по́шло», то тогда через div_t div(value, 100), практически в два раза быстрее.
В смысле стандартную библиотеку языка хотя бы глянуь стоит.

Цитата(Сергей Борщ @ Dec 22 2010, 09:08) *
const char ascii_value_table[4][256]. И действительно быстрее. И компактнее. Аплодисменты!
можно и [3] — если выводить посимвольно или с форматом "%3.3s", оно тогда до отсутствующего терминатора и не дойдёт.
Можно даже "%4.3s", пробельчик перед числом добавить.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Dec 22 2010, 04:47
Сообщение #21


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(sergeeff @ Dec 22 2010, 10:14) *
Автору эти три байта через com-порт наружу передавать и зачем там супер скорость преобразования char->ascii? А 1К под таблицу это не накладно ли будет?

Ну это уж автору виднее - что ему дороже, объём или скорость.
Если у меня свободно 30к флеши из 60 и 1к ОЗУ из 2-х, то я не парясь встраиваю функции, размещаю таблицы и щедро развешиваю в памяти хендлы на периферию и виртуальные таймеры с оверхедом в 3-4 раза.
1к в флеши - совершенный пустяк, на мой взгляд. В ОЗУ - да, может быть серьёзно (для AVR), а может быть тоже ерунда (для ARM с 512к ОЗУ)


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 22 2010, 04:54
Сообщение #22


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (ReAl @ Dec 22 2010, 09:41) *
можно и [3] — если выводить посимвольно или с форматом

CODE
char const TTT[][3] =
{
        "123",
        "123"
};
QUOTE
error: initializer-string for array of chars is too long
И все попутали порядок задания размерностей.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Dec 22 2010, 05:03
Сообщение #23


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(MrYuran @ Dec 22 2010, 11:47) *
Ну это уж автору виднее - что ему дороже, объём или скорость.


Автор как-то ушел в тень. Видимо от избытка чувств.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Dec 22 2010, 05:26
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(sergeeff @ Dec 22 2010, 11:03) *
Автор как-то ушел в тень. Видимо от избытка чувств.

Он узнал, что кроме switch в языке Си, как не странно, существуют и другие операторы. lol.gif
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Dec 22 2010, 05:27
Сообщение #25


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(Сергей Борщ @ Dec 22 2010, 10:54) *
И все попутали порядок задания размерностей.

Ну я ж писал - думать лень sm.gif


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
_dem
сообщение Dec 22 2010, 05:41
Сообщение #26


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



ReAL
По поводу операций / % — «если уж так по́шло», то тогда через div_t div(value, 100), практически в два раза быстрее.
В смысле стандартную библиотеку языка хотя бы глянуь стоит.
[/quote]
Угу, а можно еще цикл поставить.
А еще вместо процедуры отправки поставить макрос, что в данном случае на AVR сэкономит, если склероз не подводит, 1 такт по скорости.
А еще сделать таблицу в флеше с инструкциями на каждый случай (т.е. не таблицу адресов функций, а таблицу с кодами ) Это будет ну вообще быстро.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 22 2010, 05:56
Сообщение #27


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Таких перлов я ещё не встречал!
Запас бодрости на весь оставшийся день! Похлеще чем salmari.gif будет:-)
Браво!


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
singlskv
сообщение Dec 22 2010, 09:07
Сообщение #28


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



для байта на авр можно так:
Код
void itoa_byte(unsigned char n, unsigned char *s)
{
  unsigned char ch = 0;

  if ((n >= 100) && (++ch))
  {
    n -= 100;
    if ((n >= 100) && (++ch)) n -= 100;
  }

  *s++ = ch + 0x30;

  ch = (n * 157U + (n << 8)) >> 12;
  *s++ = ch + 0x30;

  ch <<= 1;
  n -= ch;
  ch <<= 2;
  n -=ch;
  *s++ = n + 0x30;
}
достаточно быстро и компактно

а лучше так:
Код
void itoa_byte(unsigned char n, unsigned char *s)
{
  unsigned char ch = 0x30;

  if ((n >= 100) && (++ch) && ((n -= 100) >= 100) && (++ch)) n -= 100;
  *s++ = ch;

  ch = (n * 157U + (n << 8)) >> 12;
  *s++ = ch + 0x30;

  ch <<= 1;
  n -= ch;
  ch <<= 2;
  n -=ch;
  *s++ = n + 0x30;
}


не, лучше всего так:
Код
void itoa_byte(unsigned char n, unsigned char *s)
{
  unsigned char ch = 0x30;

  if ((n >= 100) && (++ch) && ((n -= 100) >= 100) && (++ch)) n -= 100;
  *s++ = ch;

  ch = n * 157U >> 8;
  ch += n;
  ch >>= 4;
  *s++ = ch + 0x30;

  ch <<= 1;
  n -= ch;
  ch <<= 2;
  n -=ch;
  *s++ = n + 0x30;
}

Go to the top of the page
 
+Quote Post
777777
сообщение Dec 22 2010, 14:48
Сообщение #29


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(Aneg @ Dec 22 2010, 00:31) *
С помощью АЦП оцифровываю напряжение, пока ограничился на 256 уровнях (8 бит). Далее это значение передается по COM порту в виде 3-х байт ASCII кода. Выбор на switch применяю для перехода от 1-байтового значения к 3-м байт ASCII кода.

А если понадобится 16-разрядный АЦП?
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Dec 22 2010, 16:05
Сообщение #30


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(777777 @ Dec 22 2010, 21:48) *
А если понадобится 16-разрядный АЦП?


Вы ветку прочитали бы.
Go to the top of the page
 
+Quote Post
777777
сообщение Dec 22 2010, 16:18
Сообщение #31


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(sergeeff @ Dec 22 2010, 22:05) *
Вы ветку прочитали бы.

Что, там кто-то уже высказал такую шутку?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 24 2010, 07:03
Сообщение #32


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



А еще... а еще можно передать байт, как есть. А преобразовывать в цифры уже на том конце. sm.gif
Любопытно, если массив объявлен const char DDD[256][3], а заносятся строки "000" и т.д., что будет отброшено - нуль, заканчивающий строку, или старшая цифра?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 24 2010, 08:34
Сообщение #33


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(ViKo @ Dec 24 2010, 13:03) *
Любопытно, если массив объявлен const char DDD[256][3], а заносятся строки "000" и т.д., что будет отброшено - нуль, заканчивающий строку, или старшая цифра?

нуль, заканчивающий строку, естественно.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 27 2010, 05:44
Сообщение #34


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (demiurg_spb @ Dec 24 2010, 13:34) *
нуль, заканчивающий строку, естественно.
А у меня компилятор ругается (см. сообщение 22).


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 27 2010, 06:37
Сообщение #35


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Сергей Борщ @ Dec 27 2010, 10:44) *
А у меня компилятор ругается (см. сообщение 22).

А Keil для STM32 скушал без вопросов
Код
const char DDD[2][3] = {"123", "456"};
for (uint32_t i=6; i!=0; i--) USART3->DR = DDD[i/3][i%3];
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 27 2010, 10:54
Сообщение #36


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Сергей Борщ @ Dec 27 2010, 11:44) *
А у меня компилятор ругается (см. сообщение 22).
Ничего не могу добавить к уже сказанному:-)


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
singlskv
сообщение Dec 27 2010, 11:08
Сообщение #37


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(Сергей Борщ @ Dec 22 2010, 10:54) *
Код
char const TTT[][3] =
{
        "123",
        "123"
};

error: initializer-string for array of chars is too long
А Вы ему тогда так скажите:
Код
char const TTT[][3] =
{
        {'1','2','3'},
        {'1','2','3'}
};

Он просто обязан такое сжевать.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 27 2010, 19:11
Сообщение #38


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (singlskv @ Dec 27 2010, 16:08) *
Он просто обязан такое сжевать.
Да как сказать понятно. Видимо это еще одно отличие C и C++. Я проверял на плюсах.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
singlskv
сообщение Dec 27 2010, 20:26
Сообщение #39


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(Сергей Борщ @ Dec 28 2010, 01:11) *
Да как сказать понятно. Видимо это еще одно отличие C и C++. Я проверял на плюсах.
Здесь скорее не отличие С и С++ как стандартов а просто сложившаяся практика применения.
По K&R запись "xyz" эквивалентна {'x','y','z','\0'} то есть массиву из 4 символов,
при этом при инициализации char arr[3]="xyz" компилятор (по K&R) обязан выдавать как минимум предупреждение
о том что количество инициализаторов > размера данных, но видимо программисты никак не хотели сдаваться
и упорно писали такую инициализацию в огромном количестве кода, ну хотя бы просто для экономии памяти...
Вот в итоге и получилось что, де-факто, C компиляторы такое жуют легко, а в С++ просто решили
эту вакханалию прикрыть т.к. он более продвинутый язык по контролю над программистом... sm.gif
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 5th August 2025 - 23:08
Рейтинг@Mail.ru


Страница сгенерированна за 0.04384 секунд с 7
ELECTRONIX ©2004-2016