Большой Воронежский Форум
» Программирование>С standart: как создать "вывернутый" массив перед компиляцией....
pt200___dr.ON 13:36 07.06.2012
т.е. задача избавиться от такого кода на этапе компиляции

CONST_ - расчитываются препроцессором
Код:
int a[ 100];

memset( a, 0xFF, sizeof( a));
a[ CONST0] = 0;
a[ CONST1] = 1;
a[ CONST2] = 2;
a[ CONST3] = 3;
...
a[ CONST9] = 9;
и получить на входе компилятора
Код:
const int a[ 100] = { ....}
исходная задача. такой код
Код:
const int _a[ 10] = { CONST0, CONST1, CONST2, CONST3,.... CONST9}

int convert( int in_data)
{
  int res = -1;
  for( int q = 0; q < ( sizeof( _a) / sizeof( _a[ 0])); q++)
    if( _a[ q] == in_data)
    {
      res = q;
      break;
    }
  return res;
}
привести к такому:
Код:
const int a[ 100] = {......}

int convert( int in_data)
{
  return a[ in_data];
}
Если использовать скриптовые языки, то надо както будет "подтягивать" сишные ашки с определениями констант и тд.
P.S. Цель. оптимизация
Spectator 14:59 07.06.2012
Не очень понял, но попой чую что тебе нужен std::map
http://ru.wikipedia.org/wiki/%C0%F1%...E0%F1%F1%E8%E2

или тебе нужно на чистом С? без плюсов.
pt200___dr.ON 15:23 07.06.2012

Сообщение от Spectator:
Не очень понял, но попой чую что тебе нужен std::map
http://ru.wikipedia.org/wiki/%C0%F1%...E0%F1%F1%E8%E2

Да. чистый С.

P.S. Блин, даже незнаю как еще подробнее задачу сформулировать( генерация данных для табличного преобразования одного в другое).
Код:
const int a[ 10] = { CONST0, CONST1, CONST2, CONST3,.... CONST9}; // CONST < 100

int coder( int in_data) // in_data < 10
{
  return a[ in_data]; // Out < 100
}

const int b[ 100] = { ...};
int decoder( int in_data)
{
  return b[ in_data];
}
CONST_ - расчитываются препроцессором, а потом еще и компилятором
Код:
#define SEGMENT_A  0x10
#define SEGMENT_B  0x08
#define SEGMENT_C  0x00
#define SEGMENT_D  0x00
#define SEGMENT_E  0x04

#define CONST0  (SEGMENT_A|SEGMENT_B|SEGMENT_C|SEGMENT_D|SEGMENT_E|SEGMENT_F)
Как автоматически перед компиляцией( желательно с помощью препроцессора) получить массив b ????

P.S. Получается надо типа интерпрератора С
Spectator 16:45 07.06.2012
Ну как вариант я в одной фирме видел программу, которая на основании определенных параметров генерировала CPP/H классы. В твоем случае на входе нужно будет подавать число, а на выходе получать C файл со строкой
const int a[N] = {0, 1, 2, 3,.... N-1};
И его присоединить отдельным файлом в проект, а из других CPP файлов массив просто объявить.


Посмотри, там обсуждение как раз по твоему вопросу.
http://bytes.com/topic/c/answers/637...rocessing-loop

Конкретно вот это кажется мне интересным
http://bytes.com/topic/c/answers/637...oop#post242273
pt200___dr.ON 17:36 07.06.2012
Чтото не очень похоже.
Как мне кажется препроцессор с такой задачей не справиться, т.к. он не занимается вычислениями( т.е. 1+2+3 он не заменит на 6).

т.е. самое простое это компилить тулзу( на тех же С)( которая используя нужные ашки и массив, генерит на выходе требуеммый массив)
Spectator 11:56 08.06.2012

Сообщение от pt200___dr.ON:
Чтото не очень похоже.
Как мне кажется препроцессор с такой задачей не справиться, т.к. он не занимается вычислениями( т.е. 1+2+3 он не заменит на 6).

т.е. самое простое это компилить тулзу( на тех же С)( которая используя нужные ашки и массив, генерит на выходе требуеммый массив)

я это и имею в виду. это самый лучший вариант.
aerin 19:14 08.06.2012
pt200___dr.ON, а можно с самого начала задачу, откуда берется код с define-ами? Если вы его пишите сами, то что мешает оформить его в виде макроса, который определит оба массива или развернет переданные параметры, или вообще создать это все в рантайме вызовом функции? Если вы его чем-то генерите, то может надо там пошаманить?

Сообщение от pt200___dr.ON:
Как автоматически перед компиляцией( желательно с помощью препроцессора) получить массив b ????

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

Сообщение от pt200___dr.ON:
Как мне кажется препроцессор с такой задачей не справиться, т.к. он не занимается вычислениями( т.е. 1+2+3 он не заменит на 6).

Не занимается. 1+2+3 так и останется 1+2+3, а вот из
SEGMENT_A|SEGMENT_B|SEGMENT_C|SEGMENT_D|SEGMENT_E
он сделает
0x10|0x08|0x00|0x00|0x04

Сообщение от pt200___dr.ON:
т.е. самое простое это компилить тулзу( на тех же С)( которая используя нужные ашки и массив, генерит на выходе требуеммый массив)

Все-таки я бы начал плясать от задачи, #define - страшная глобальная штука, сродни дубинке. И ее использование для задач, отличных от определения включаемых в сборку областей кода, как правило ведет к большим проблемам в отладке.
pt200___dr.ON 21:15 08.06.2012
Исходная задача( микроконтроллеры) данный код оптимизировать по скорости, экономя ресурсы( особенно RAM)
Код:
#define SEGMENT_A  0x10
#define SEGMENT_B  0x08
#define SEGMENT_C  0x40
#define SEGMENT_D  0x20
#define SEGMENT_E  0x04
#define SEGMENT_F  0x02
#define SEGMENT_G  0x01

const unsigned char symbols[] = 
{
  SEGMENT_A|SEGMENT_B|SEGMENT_C|SEGMENT_D|SEGMENT_E|SEGMENT_F,
  SEGMENT_B|SEGMENT_C,
  SEGMENT_A|SEGMENT_B|SEGMENT_D|SEGMENT_E|SEGMENT_G,
  SEGMENT_A|SEGMENT_B|SEGMENT_C|SEGMENT_D|SEGMENT_G,
  SEGMENT_B|SEGMENT_C|SEGMENT_F|SEGMENT_G,
  SEGMENT_A|SEGMENT_C|SEGMENT_D|SEGMENT_F|SEGMENT_G,
  SEGMENT_A|SEGMENT_C|SEGMENT_D|SEGMENT_E|SEGMENT_F|SEGMENT_G,
  SEGMENT_A|SEGMENT_B|SEGMENT_C,
  SEGMENT_A|SEGMENT_B|SEGMENT_C|SEGMENT_D|SEGMENT_E|SEGMENT_F|SEGMENT_G,
  SEGMENT_A|SEGMENT_B|SEGMENT_C|SEGMENT_D|SEGMENT_F|SEGMENT_G,
  0,

  SEGMENT_A|SEGMENT_D|SEGMENT_E|SEGMENT_F,            // C
  SEGMENT_B|SEGMENT_C|SEGMENT_E|SEGMENT_F|SEGMENT_G,  //H

  SEGMENT_E|SEGMENT_G,                                //r
};

int get_symbol( unsigned char in_data)
{
  for( int q = 0; q < ( sizeof( symbols) / sizeof( symbols[ 0])); q++)
    if( symbols[ q] == in_data)
    {
      return q;
      break;
    }
  return -1;
}
Spectator 21:37 08.06.2012
может поиск делением пополам поможет отцу русской демократии?
http://ru.wikipedia.org/wiki/%C4%E2%...EF%EE%E8%F1%EA
он одновременно простой и крайне эффективный. единственный недостаток - данные должны быть отсортированы.
aerin 22:34 08.06.2012
pt200___dr.ON, массив symbols такой всегда или меняется?
Возможно ли изменение порядка следования элементов?
ЗЫ. Да и вообще, насколько я понимаю, там максимум половина таблицы, т.е. даже если тупо создать еще один массив, то это всего лишь 127 байт.
Hopkroft 22:54 08.06.2012

Сообщение от Spectator:
может поиск делением пополам поможет отцу русской демократии?
http://ru.wikipedia.org/wiki/%C4%E2%...EF%EE%E8%F1%EA
он одновременно простой и крайне эффективный. единственный недостаток - данные должны быть отсортированы.

ну или хеш функция. но это опять же код, который тоже будет занимать память.
но если смотреть на таблицу, я не понимаю почему нельзя тупо написать код который будет генерировать эти значения, и создать файл, из которого копи-пастом выдрать код.
pt200___dr.ON
Ты больше времени потратишь на оптимизацию чем на пользу от работы программы Если будет часто нужно - напишешь оптимизированный вариант.
P.S. оптимизированный вариант программы генератора, а не кода. т.к. иначе совет противоречил бы твоему т.з.
pt200___dr.ON 23:19 08.06.2012

Сообщение от aerin:
pt200___dr.ON, массив symbols такой всегда или меняется?

Всегда


Сообщение от aerin:
Возможно ли изменение порядка следования элементов?

Можно что угодно. Если только

Код:
get_symbol( SEGMENT_A|SEGMENT_B|SEGMENT_C|SEGMENT_D|SEGMENT_E|SEGMENT_F) == 0 
get_symbol( SEGMENT_B|SEGMENT_C) == 1
.....
Но отптимальнее этого помоему ничего не существует:
Код:
const int b[ 100] = { ...};
int get_symbol( unsigned char in_data)
{
  return b[ in_data];
}
Поэтому и вопрос: какими максимально стандартными средствами/методами можно его получить

Сообщение от aerin:
ЗЫ. Да и вообще, насколько я понимаю, там максимум половина таблицы, т.е. даже если тупо создать еще один массив, то это всего лишь 127 байт.

Так точно( только 128).
Основной вопрос, где этот массив будет лежать в const/FLASH( что устраивает) или в RAM( слишком жирно).
brk 21:36 10.06.2012

Сообщение от pt200___dr.ON:
т.е. задача избавиться от такого кода на этапе компиляции

CONST_ - расчитываются препроцессором

Код:
int a[ 100];

memset( a, 0xFF, sizeof( a));
a[ CONST0] = 0;
a[ CONST1] = 1;
a[ CONST2] = 2;
a[ CONST3] = 3;
...
a[ CONST9] = 9;
и получить на входе компилятора
Код:
const int a[ 100] = { ....}
исходная задача. такой код
Код:
const int _a[ 10] = { CONST0, CONST1, CONST2, CONST3,.... CONST9}

int convert( int in_data)
{
  int res = -1;
  for( int q = 0; q < ( sizeof( _a) / sizeof( _a[ 0])); q++)
    if( _a[ q] == in_data)
    {
      res = q;
      break;
    }
  return res;
}
привести к такому:
Код:
const int a[ 100] = {......}

int convert( int in_data)
{
  return a[ in_data];
}
Если использовать скриптовые языки, то надо както будет "подтягивать" сишные ашки с определениями констант и тд.
P.S. Цель. оптимизация

а причем тут вообще чистый с или нет. нужна отдельная утилита. Пофиг на чём. И чтоб из одного текстового вида делала другой. соответсвенно после образования кривого кода запускается утиля и образуется нужный вам код.
пишется достаточно быро под свои нужды на чём удобно. В чем трабл не понимаю. Так же как и причем тут оптимизация под однокристалки? и вообще если однокристалки и оптимизация - то причем тут си? пишите на ассемблере.
Spectator 00:23 11.06.2012
в общем, если автор ВНЯТНО не объяснит - что ему нужно, тема будет закрыта.
silly 00:57 11.06.2012

Сообщение от pt200___dr.ON:
Но отптимальнее этого помоему ничего не существует:

Код:
const int b[ 100] = { ...};
int get_symbol( unsigned char in_data)
{
  return b[ in_data];
}

Я тут немного не в теме, но насколько тупой switch внутри get_symbol будет реально медленнее?
Hopkroft 01:43 11.06.2012

Сообщение от silly:
Я тут немного не в теме, но насколько тупой switch внутри get_symbol будет реально медленнее?

Ему нужно что-бы программа была не только шустрой но и в памяти весила немного. Добавление Switch влечёт за собой увеличение кода, а это противоречит его т.з.
вообщем задача о проектирование сферического коня в вакууме
pt200___dr.ON 09:08 11.06.2012
silly, производительность switch зависит от компилятора( его настроек), самих индексов( на 0, 1, 2, 3...) может работать значительно быстрее, чем на каше( + разное время выполнения в зависимости от индекса).

Про размер кода я ничего не говорил.

Но вообщето стоял вопрос не в оптимизации, а в способах генерации массива
Hopkroft 18:53 11.06.2012

Сообщение от pt200___dr.ON:
Но вообщето стоял вопрос не в оптимизации, а в способах генерации массива

Тебе 100 раз говорили что это делает спец утилита.
Которую придётся писать самому. Уже давно бы написал.
aerin 19:18 11.06.2012
Hopkroft, ну или тупо один раз написать прям в этой программе(массив-то никогда не меняется):
Код:
...
int _b[sizeof( _a) / sizeof( _a[ 0])];
memset(_b,-1,sizeof(_a));
for(int i = 0; i < sizeof( _a) / sizeof( _a[ 0]); i++ )
    _b[_a[i]] = i;
printf( "_b[] = { %d", _b[0]);
for(int i = 1; i < sizeof( _a) / sizeof( _a[ 0]); i++ )
   printf( ", %d", _b[i]);
printf(" };");
...
А потом вставить полученный вывод в исходник
Hopkroft 22:34 11.06.2012

Сообщение от aerin:
А потом вставить полученный вывод в исходник

Об этом уже 1000 раз говорили, но мне кажется ему хочется волшебства по типу кода из книги Алгоритмические трюки для программистов.
pt200___dr.ON 23:12 11.06.2012
Hopkroft, Задача уже давно так и решена

Просто хочется надеяться, что есть более правильное решение задачи
Hopkroft 23:52 11.06.2012

Сообщение от pt200___dr.ON:
Hopkroft, Задача уже давно так и решена

Просто хочется надеяться, что есть более правильное решение задачи

Я не думаю что тут можно было что-то заоптимизировать. Но как показывает практика оптимально решение или нет покажет только использование ПО и последующая модернизация кода. Вот тут и могут всплыть различные косяки.
Spectator 00:37 13.06.2012

Сообщение от Spectator:
в общем, если автор ВНЯТНО не объяснит - что ему нужно, тема будет закрыта.

просто поговорить - это в Болталку. если есть возражения - это в личку.
А пока - закрыто.
Вверх