Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> об STL простыми словами 
:(
    Опции темы
Wowa
Дата 28.3.2005, 03:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
Group Icon


Профиль
Группа: Админ
Сообщений: 15017
Регистрация: 14.9.2000
Где: Винград

Репутация: нет
Всего: 290



Содержание:
- Что такое STL и с чем его едят ?
- Каковы основные понятия STL ? С чего начинать ?
- Как организовать динамический массив ?
- Как организовать список значений ?
- Как удалить элемент из массива или списка ?
- Как вставить элемент в середину списка или массива ?
- Как хранить объекты в списке / динамическом массиве
- Как организовать список списков, массив списков и т.п. ?

====================================================

- Что такое STL и с чем его едят ?
Standard Templates Library, библиотека стандартных шаблонов, это часть стандарта C++, впервые предложена Hewlett-Packard Company, на данный момент для С++ не существует более быстрого, удобного и простого решения по организации хранения данных в виде списков, динамических массивов, карт (ассоциативных списков), стека и др.  STL- кроссплатформенный продукт, его можно использовать в приложениях под WinAPI, Linux, и Mac.


- Каковы основные понятия STL ? С чего начинать ?
Предполагается знание основ C++, и владение понятием "шаблон" (template). Далее, из пяти предлагаемых в различной литературе понятий на начальном этапе достаточно знать всего три:

контейнер - шаблон класса, служащий для хранения данных. Простыми словами: контейнер нужен нам как "обёртка" вокруг наших данных, чтобы хранить их, например, в списке. Такой список можно организовать из чисел float, из строк string, из объектов созданного нами класса, и т.д.

итератор - специальный тип, служащий аналогом Си-шного указателя, используется для прохода по списку, массиву, поиска элемента в ассоциативном списке, и т.д. Это настоящий аналог указателя, к нему можно применять операции ++ и -- , "звездочку" или -> для получения значения. Операция ++ сдвигает итератор к следующему элементу динамического массива, списка, очереди и т.п. Можно сравнивать два итератора. Вместо NULL, признаком выхода за пределы допустимых значений служит специальный итератор, получаемый из контейнера с помощью функции end() (об этом позже).

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


- Как организовать динамический массив ?
Динамический массив в STL называется "vector". Простой пример:
Код
#include < vector>      // подключение библиотеки STL
using namespace std;  // используем пространство имён STL

void main()
{
      // организуем динамический массив float-ов
      vector < float>  arr;
       
      // добавим два элемента в массив
      arr.push_back(1.34f);
      arr.push_back(-299);

      // пройдём по массиву в цикле
      for(int j = 0; j < arr.size(); j++)
      {
           float  value = arr[j];
      }

      // увеличим размер массива до 100 элементов, значение каждого -0.23
      arr.resize(100, -0.23f);
}

Пояснения:
- в треугольных скобках указывается тип значений, хранимых в vector-е
- чтобы память не выделялась повторно каждый раз, когда динамический массив изменяет размер (растёт или уменьшается), есть специальная функция arr.reserve(N), заранее резервирующая память под N элементов. Того же результата можно добиться при создании vector-а: vector < float> arr(N), где N - произвольная переменная или константа.


- Как организовать список значений ?
Код
#include < list>      // подключение библиотеки STL
using namespace std;  // используем пространство имён STL

void main()
{
      // организуем список float-ов
      list < float>  thelist;
       
      // добавим два элемента в хвост списка
      thelist.push_back(1.34f);
      thelist.push_back(-299);
      // добавим один элемент в голову списка
      thelist.push_front(-0.25f);
      // удалим все элементы из списка
      thelist.clear();
      // заполним список тремя числами из обычного массива:
      float  values[] = {0.23f, -4.56f, 7.89f};
      thelist.resize(3);
      copy(thelist.begin(), thelist.end(), values);

      // пройдём по списку в цикле
      for(list< float>::iterator  i = thelist.begin();  i != thelist.end(); i++)
      {
           float  value =  *i;
      }
}

Пояснения:
- создание списка и добавление элементов - по аналогии с vector-ом
- функции resize(), push_front(), clear(), begin() и другие - имеются в каждом контейнере (в vector-е в том числе).
- copy(A, B, C) - алгоритм, копирующий все элементы из контейнера или массива, на который указывает итератор или указатель C, в контейнер или массив, на который указывают итераторы или указатели A и B, причём A указывает на первый элемент, B указывает на элемент, находящийся после последнего элемента массива или контейнера. Для любого контейнера, В можно получить с помощью функции end(), для массива - можно прибавить размер массива к указателю на первый элемент (например, values + 3).
- итератор ("псевдоуказатель") для каждого контейнера, создаваемого нами, имеет свой отличный тип. Для того, чтобы объявить итератор i из контейнера list< float>, используется выражение list< float> ::iterator  i.
Такие, подчас "сложные", выражения, лучше заменять на typedef-ы: 
Цитата
typedef   list< float>  ListOfFloats;
ListOfFloats  thelist;
for(ListOfFloats::iterator  i = thelist.begin();    ...[/color]

- как уже говорилось, для получения значения, на которое указывает итератор итератор, используется звёздочка: *i. Для перемещения по списку мы просто сдвигаем итератор операцией  ++.


- Как удалить элемент из массива или списка ?
Для того, чтобы удалить элемент из "головы" или "хвоста" - используется пара функций pop_front(), pop_back(). Для удаления произвольного элемента используется функция erase(i), где i - это итератор, указывающий на элемент.


- Как вставить элемент в середину списка или массива ?
Используя функцию insert(i, v), где v - это вставляемое значение, i - итератор, указывающий на элемент, перед которым нужно вставить значение.


- Как хранить объекты в списке / динамическом массиве
Точно так же, как обычные float-ы:
Код
#include < list>
#include < vector>
using namespace std;

struct  MyStruct
{
     int      A;
     float   B;
     char   C[50];
}

void main()
{
     vector < MyStruct>  arr;
     
     MyStruct   obj;
     arr.push_back(obj);
     arr[0].A = 123;

     list  < MyStruct>  thelist;
     thelist.push_back(obj);
     thelist.push_back(obj);
     thelist.push_back(obj);
     for(list< MyStruct>::iterator   i = thelist.begin(); i != thelist.end(); i++)
     {
            // можно обратиться к структуре так:
            (*i).A = 123;

            // а можно получить ссылку и работать с ней:
            MyStruct   &thestruct  =  *i;
            thestruct.B = -0.234;
            strcpy(thestruct.C, "Some text");
     }
}



- Как организовать список списков, массив массивов и т.п. ?
В любом контейнере можно хранить вложенный контейнер. Для простоты записи, можно использовать typedef-ы:
Код
#include < list>
#include < vector>
using namespace std;

// отключаем предупр-ния из-за слишком длинных имён типов
#pragma warning(disable: 4786)   

void main()
{
      typedef   list< float>   ListOfFloat;    // список float-ов
      typedef   list< ListOfFloat>  ListOfListOfFloat; // список списков float-ов

      // как можно работать со списком списков:
      ListOfListOfFloat  thelist;
      // добавляем 2 элемента в список списков:
      thelist.resize(2);
      // а можно и так:
      ListOfFloat  thelistinside;
      thelistinside.push_back(-0.34f);
      thelistinside.push_back(3.45f);
      thelist.push_back(thelistinside);
      // или вот так:
      thelist.push_back(ListOfFloat());

      // проходим в цикле по спискам - внешнему и вложенному
      for(ListOfListOfFloat::iterator  i1 = thelist.begin(); i1 != thelist.end(); i1++)
      {
            // для удобства, получаем ссылку на вложенный список
            ListOfFloat  &thelistinside = *i1;
            // проходим по вложенному списку
            for(ListOfFloat::iterator  i2 = thelistinside.begin(); i2 != thelistinside.end(); i2++)
            {
                  float  value = *i2;
            }
       }
}

PM WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0733 ]   [ Использовано запросов: 23 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.