Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как один массив поместить в другой с помощью указателя  (Прочитано 12154 раз)
0 Пользователей и 1 Гость смотрят эту тему.
biletsky
Гость
« : 18-04-2008 12:11 » new

Я принимаю данные с последовательного порта, функция возвращает указатель на строку (массив из char’ов). Я хочу создать большой массив в которой будут записываться последовательно эти маленькие массивы, которые возвращает последовательный порт. Я уже заделал чтоб это копирование происходило побайтно, но это, как мне кажется, происходит долго. Нельзя ли последовательно вставлять массивы в один большой массив с помощью указателя. И как?   Да-да Код побайтного копирования (s[і ] - маленький массив длиною в in_b )
Код:
for (i=0;i<in_b;i++)
         {
           data[j] = s [і] ;
           j++;
           if (j==25000) j=0;         
         }

 Скромно так...
« Последнее редактирование: 18-04-2008 13:51 от Алексей1153++ » Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 18-04-2008 12:18 » 

Я принимаю данные с последовательного порта, функция возвращает указатель на строку (массив из char’ов).
Функция сама выделяет память под массив, или (что, имхо, логичнее) ей нужно передать буфер и его размер?
Если второе - то можно передавать ей указатели на разные позиции в массиве, и тогда твои "маленькие массивы" будут реально располагаться в одном большом.
Другой вопрос, зачем это нужно Улыбаюсь
Offtopic:
А какое отношение это имеет конкретно к Borland C++ ?
Поставлю в угол.
« Последнее редактирование: 18-04-2008 12:21 от Вад » Записан
Sands
Помогающий

ua
Offline Offline

« Ответ #2 : 18-04-2008 12:20 » 

По идее можно сделать так:
Код:
pTmp = data;
memncpy(pTmp,s,in_b);
pTmp += in_b;
Если есть необходимость сделать большой массив циклическим буффером - тогда придется ввести дополнительную переменную, которая будет отслеживать количество уже записанной информации и добавить код, который в случае переполнения, будет производить переход в начало массива.
Или как правильно подметил Вад, просто сразу передавать в функцию указательна нужный участок большого массива
Записан
biletsky
Гость
« Ответ #3 : 18-04-2008 13:29 » 

На последовательный порт приходят данные в формате типа char, но двумя символами -  в 16 представлении (0хFF), физически это два байта. В Борланде я перевожу это в формат int, и потом анализирую эти данные (макс, мін, график данных). Функция, которая считывает с последовательного порта, возвращает массивы с разной длинной (как кратной  так и некратной), поэтому мои данные могут легко сместится на один байт(скажем прейдет 240 байт, а потом 243, 243, 246 - второй пакет "съест" половинку моего "16-представленного char'а", а третий пакет начнётся криво). Если можно, пожалуйста, выложите код, который бы додавал *s в массив data. Как инициализировать data и указатель на него. Извините, но я еще не научился работать с указателями.
Код:
void __fastcall TForm1::CommPortDataReceived(TObject *Sender, DWORD Count)
{
      if( CommPort->InBuffUsed == 0 )  return;

      int in_b = 0;
      in_b = CommPort->InBuffUsed;
      char *s = new char[in_b + 1];

      in_b = CommPort->GetBlock( s, in_b );
      s[in_b] = 0;     

      for (i=0;i<in_b;i++)
         {
           data[j] = s[i];
           j++;
           if (j==25000) j=0;
         }   
     delete s;
}

P.S. Как можно вывести быстро график данных, когда нужна критическая скорость (в реальном времени). Спасибо за быстрые ответы.
« Последнее редактирование: 18-04-2008 13:52 от Алексей1153++ » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #4 : 18-04-2008 13:52 » 

Ещё раз.

1. Если нужна скорость - про циклы забудь навсегда. memncpy - решение всех твоих проблем

2. >> возвращает массивы с разной длинной (как кратной  так и некратной),
Выравнивай!!! Это ж просто ты начальный ноль не получаешь. Вот и всё. А ещё лучше сразу конверти стрку байта в байт и работай только с байтами. Изменения надо сделать в GetBlock.

3. Указатель в твоём случае работает очень просто. Представь себе адрес  некого блока - его начало это s.
s+5 означает смещение на 5 байт. И тд

4. Вот тут у тебя вобще чушь - код не рабочий, тк  j не инициаллизирована

  for (i=0;i<in_b;i++)
         {
           data[j] = s;
           j++;
           if (j==25000) j=0;
         }   
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
v2
Помогающий

ua
Offline Offline

« Ответ #5 : 18-04-2008 20:39 » 

Цитата
P.S. Как можно вывести быстро график данных, когда нужна критическая скорость

Складываешь все последовательно в один буфер (что ты и пытаешься сделать), а потом (раз в секунду) рисуешь.

Код:
//Global
...
DWORD j=0;
char  data=[25000];
...

//Get
...
      for (i=0;i<in_b;i++)
         {
           data[j] = s[i];
           j++;
           if (j==25000) j=0;
         }
...

Модифицируй так:

Код:
//Global
...
DWORD j=0;
DWORD printed_j=0;
char  *data= new char[cMAX_1MB_LEN];
...

//Print
...
  printed_j=x; //x=Количество обработанных байт
...

//Get
...
  if (j+in_b<cMAX_1MB_LEN) memncpy(&data[j],s,in_b);
    else { j=j%2;
           memncpy(&data[j],s,in_b); }

  j+=in_b;

  if (printed_j!=0) {
    j-=printed_j;
    memncpy(data,&data[printed_j],j);
    printed_j=0;}
...

Цитата
(в реальном времени).
Это как? Улыбаюсь
« Последнее редактирование: 18-04-2008 20:53 от v2 » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 19-04-2008 03:16 » 

совсем в реальном времени, конечно, не получится, но раз, скажем, в пол секунды можно попробовать:
Код:
for(;;)
{
   1) читаем из порта N байт
   2) отдаём модулю-плоттеру данные
}

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

Чтение из порта, это, конечно, в другом потоке
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #7 : 21-04-2008 04:56 » 

а чем на устраивают
vector + std::copy
можете сказать что std::copy медленный, НО
Код:
void foo(const char * new_data, size_t size)
{
std::vector<char> all_data;
all_data.reserve(all_data.size() + size);
std::copy(new_data, new_data + size, std::back_inserter(all_data)); // тут действительно копирование в цикле по одному элементу
}

void foo2(const char * new_data, size_t size)
{
std::vector<char> all_data;
size_t old_size = all_data.size();
all_data.resize(old_size + size);
std::copy(new_data, new_data + size, &all_data[old_size]); // а вот тут будет вызван memmove
}

int _tmain(int argc, _TCHAR* argv[])
{
foo("TESTTESTTEST", 10);
foo2("TESTTESTTEST", 10);
return 0;
}
Записан

Странно всё это....
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines