web-dev-qa-db-ja.com

Arduinoのベクター

Arduinoで「ウェイポイント」のベクターを作成しています。各ウェイポイントはオブジェクトです。 Arduinoは明らかに、ウェイポイントナビゲーションのために複数のウェイポイントを保存する必要があります。ただし、これらのウェイポイントを事前にプログラムされた標準の配列に保存する代わりに、ユーザーはウェイポイントを追加、削除、移動する必要があります。残念ながら、Arduinoは組み込みライブラリとしてベクタータイプを提供していません。

現在、次の2つのオプションを検討しています。

  1. C++ 'vector'のようなオブジェクトのコンテナ?で、誰かが汎用ライブラリを投稿しました。インデックスの削除や移動操作は含まれません。ただし、いくつかのメモリ管理戦略が含まれています。

  2. 私はmalloc、dealloc、calloc過去。しかし、特にクラスでは、このオプションはまったく好きではありません。しかし、これは私のシナリオではより良いオプションですか?

どちらがダウンするのに適したパスですか?

48
jakebird451

Arduinoの標準C++ はオプションかもしれません。で [〜#〜] stl [〜#〜]vectorを使用できますArduino。

54
Sibster

単純なリンクリストを実装したいように思えます。リンクリストを使用すると、C++ベクトルに関連するオーバーヘッドなしでオブジェクト(場合によってはウェイポイント)を移動できます。

以下に実装を示します GitHubで

4
augustzf

Arduinoのメモリは限られているため、許可するウェイポイントの数を知る必要があります。この場合、割り当てられたウェイポイントのメモリポインター(アドレス)を保持する単純な配列は、必要なシーケンス/順序を提供します。作業領域として1つのアレイスロットを空けておくと、ウェイポイントを移動(再配列)できます。

2
Visual Micro

このLinkedListテンプレートクラスを記述して、必要な場所に呼び出すだけです。

#ifndef LinkedList_hpp
#define LinkedList_hpp


template <class T>
class ListNode {
  public:
    T element;
    ListNode* next;
    ListNode* prev;

    ListNode(T element, ListNode* prev, ListNode* next) : element(element)
    {
      this->next = next;
      this->prev = prev;
    };
};

template <class T>
class LinkedList  {
  private:
    int length;
    ListNode<T>* head;
    ListNode<T>* tail;
    ListNode<T>* curr;
  public:
    LinkedList();
    LinkedList(const LinkedList<T>&);
    ~LinkedList();
    T& getCurrent();
    T& First() const;
    T& Last() const;
    int getLength();
    void Append(T);
    void DeleteLast();
    void DeleteFirst();
    void DeleteCurrent();
    bool next();
    bool moveToStart();
    bool prev();
    void Delete(T&);
    bool Search(T);
    void Clear();
    void PutFirstToLast();
    void Update(T elem);
    LinkedList& operator = (const LinkedList<T>&);
};

template <class T>
LinkedList<T>::LinkedList() {
    length = 0;
    head = nullptr;
    tail = nullptr;
    curr = nullptr;
}

template <class T>
LinkedList<T>::LinkedList(const LinkedList<T> & list) {
    length = 0;
    head = nullptr;
    tail = nullptr;
    curr = nullptr;

    ListNode<T> * temp = list.head;

    while(temp != nullptr)
    {
        Append(temp->element);
        temp = temp->next;
    }
}

template <class T>
LinkedList<T> & LinkedList<T>::operator=(const LinkedList<T> & list)
{
    Clear();

    ListNode<T> * temp = list.head;

    while(temp != nullptr)
    {
        Append(temp->element);
        temp = temp->next;
    }

    return *this;
}

template <class T>
LinkedList<T>::~LinkedList() {
    Clear();
}

template<class T>
T& LinkedList<T>::getCurrent()
{
  return curr->element;
}

template<class T>
T& LinkedList<T>::First() const
{
  return head->element;
}

template<class T>
T& LinkedList<T>::Last() const
{
  return tail->element;
}

template<class T>
int LinkedList<T>::getLength()
{
  return length;
}

template <class T>
void LinkedList<T>::Append(T element)
{
    ListNode<T> * node = new ListNode<T>(element, tail, nullptr);

    if(length == 0)
        curr = tail = head = node;
    else {
        tail->next = node;
        tail = node;
    }

    length++;

}

template <class T>
void LinkedList<T>::DeleteLast()
{
    if(length == 0)
      return;
    curr = tail;
    DeleteCurrent();
}

template <class T>
void LinkedList<T>::DeleteFirst()
{
    if(length == 0)
      return;
    curr = head;
    DeleteCurrent();
}

template <class T>
bool LinkedList<T>::next()
{
    if(length == 0)
        return false;

    if(curr->next == nullptr)
        return false;

    curr = curr->next;
    return true;
}

template <class T>
bool LinkedList<T>::moveToStart()
{
    curr = head;
    return length != 0;
}

template<class T>
bool LinkedList<T>::prev()
{
    if(length == 0)
        return false;

    if(curr->prev != nullptr)
        return false;

    curr = curr->prev;
    return true;
}

template <class T>
void LinkedList<T>::Delete(T & elem)
{
    if(Search(elem))
        DeleteCurrent();
}

template <class T>
void LinkedList<T>::DeleteCurrent()
{
    if(length == 0)
        return;
    length--;
    ListNode<T> * temp = curr;

    if(temp->prev != nullptr)
        temp->prev->next = temp->next;
    if(temp->next != nullptr)
        temp->next->prev = temp->prev;

    if(length == 0)
        head = curr = tail = nullptr;
    else if(curr == head)
        curr = head = head->next;
    else if(curr == tail)
        curr = tail = tail->prev;
    else
        curr = curr->prev;

     delete temp;
}

template <class T>
bool LinkedList<T>::Search(T elem)
{
    if(length == 0)
        return false;
    if(moveToStart())
        do {
            if(curr->element == elem)
                return true;
        } while (next());
    return false;
}

template <class T>
void LinkedList<T>::PutFirstToLast()
{
  if(length < 2)
    return;
  ListNode<T>* temp = head->next;
  head->next->prev = nullptr;
  head->next = nullptr;
  head->prev = tail;
  tail->next = head;
  tail = head;
  head = temp;
}

template <class T>
void LinkedList<T>::Update(T elem)
{
    if(Search(elem))
        curr->element = elem;
}

template <class T>
void LinkedList<T>::Clear()
{
    if(length == 0)
        return;
    ListNode<T> * temp = head;

    while(temp != nullptr)
    {
        head = head->next;
        delete temp;
        temp = head;
    }

    head = curr = tail = nullptr;

}


#endif

このクラスを次のように使用します。

LinkedList<int> list;

list.Append(1);
list.Append(2);
list.Append(3);
list.Append(4);

int my_integer;

if(list.moveToStart())
    do{
        my_integer = list.getCurrent();
    }while(list.next());
1
MrT

また、ウェイポイント構造体の固定配列を使用し、ウェイポイントが使用中かどうかに応じて構造体に変数を含めることもできます。ウェイポイントを追加するとき、使用されていない構造が見つかるまで配列をループする必要があります。

0
Jake