Обсуждение Программирование на C/C++

Занятие 5. Класс vector

Последовательности

Используя объекты элементарного типа, можно выполнять только простую работу. Для выполнения более сложных заданий, непосильных для одного объекта, простые объекты объединяют в сложные. Самый простой способ соединения объектов - это последовательность, группа объектов одного типа, предназначеная для выполнения одинаковых действий. Например, чтобы выкопать канаву, отправляют не одного солдата, а целый взвод.

К отдельным элементам последовательности нужно обращаться по номеру, а не по имени ("3-ий, выйти из строя"). Такой способ обращения позволяет записать действия, производимые над всеми объектами последовательности, с помощью цикла, а не с помощью набора почти одинаковых операторов.

В языке C++ нумерация объектов в последовательности всегда ведется с 0, что не совсем обычно.

Цитата:
Программист с женой отправились в супермаркет.
Сделав все необходимые закупки, они вышли на улицу, и жена сказала:
- Стой здесь и смотри в оба за этими десятью сумками, пока я схожу и разыщу такси.
Когда жена вернулась, то увидела обалдевшего мужа, переставляющего сумки с места на место.
Программист:
- Ты сказала, что здесь десять сумок, а я насчитал только 9!
Жена:
- Но их было десять!
Программист:
- Нет, давай вместе считать: 0, 1, 2, 3...



Одним из способов представления последовательности в C++ является класс vector. Название не имеет отношения к векторам в пространстве. Разве что в n-мерном пространстве.

Создание объектов

Класс vector определен в заголовочном файле vector (очень легко запомнить ). Подлючаем его с помощью команды #include <vector>

Для создания объектов типа vector используется оператор объявления. Сначала указывается слово vector, затем в угловых скобках тип элементов последовательности, затем перечисляются через запятую имена создаваемых объектов-векторов. После имени объекта можно написать в круглых скобках количество элементов в последовательности и начальное значение, которое нужно присвоить каждому элементу. По умолчанию начальное значение и количество равны 0.

Код:
vector<int> v1; // последовательность из нуля объектов типа int 
vector<double> v2(100); // последовательность из 100 объектов типа double, во всех элементах сначала 0
vector<int> v3(10,1); // последовательность из 10 объектов типа int, во всех элементах сначала число 1

Изменение размера

Размер последовательности можно легко изменить с помощью метода .resize
Код:
v3.resize(25); // количество элементов в последовательности стало 20, новым элементам будет присвоено значение 0
v3.resize(50,2); // количество элементов в последовательности стало 50, новым элементам будет присвоено значение 2
// теперь в последовательности v3 сначала десять 1, затем пятнадцать 0, затем двадцать пять 2
v3.resize(10); // количество элементов в последовательности уменьшилось до 10, остались только первые десять элементов

Операции над vector

Объекты типа vector, элементы которых имеют одинаковый тип, можно присваивать друг другу, так же как простые объекты. Старое содержимое объекта при этом исчезает, а новое становится равным присвоенному значению.
Код:
v1=v3;
Нельзя v1=v2; так как тип элементов не совпадает

Объекты типа vector можно сравнивать на равенство ( == ), неравенство ( != ). Последовательности считаются одинаковыми, если у них совпадает количество элементов и равны все элементы на соответствующих позициях.
Код:
if(v1==v2) cout<<"одинаковые";
else cout<<"разные";

Операции >, <, >=, <= позволяют упорядочивать объекты типа vector. A<B, если 0-ой элемент A меньше, чем 0-ой элемент B, если эти элементы равны, то сравниваются следующие и т.д. Похоже на расстановку слов по алфавиту.

Текущее количество элементов в последовательности можно узнать с помощью метода .size()
Код:
cout << "количество элементов=" << v1.size() << endl;

Обращение к элементу

Получить доступ к i-ому элементу последовательности можно с помощью метода .at(i)
Элементы последовательности имеют номера от 0 до size()-1
Код:
// Записать в последовательность числа от 1 до size()
for(int i(0); i<v3.size(); ++i) 
v3.at(i)=i+1; 
 
// поменять местами i-ый и j-ый элементы
int t;
t=v3.at(i);
v3.at(i)=v3.at(j);
v3.at(j)=t;
Если обратиться к несуществующему элементу с номером <0 или >=size(), то выполнение программы прекращается. Если запускать под C++ Builder, то появится сообщение об исключении out_of_range и после нажатия на кнопку OK можно посмотреть строчку, где произошла ошибка: View -> Debug Windows -> Call Stack (Ctrl-Alt-S), затем щелкнуть в стеке вызовов на функцию main.

Пример программы

Ввести последовательность, удалить из нее отрицательные элементы, вывести результат

Код:
#include <iostream>
#include <vector>
using namespace std;
int main()
{ int n,m,i;
  cout<<"Vvedi kol-vo elementov"<<endl;
  cin>>n;
  vector<int> v(n); // создаем последовательность
  cout<<"Vvedi elementy posledovatelnosti"<<endl;
  for(i=0; i<n; ++i)
    cin>>v.at(i); // вводим ее элементы
  // m - счетчик неотрицательных элементов и одновременно номер элемента
  for(m=0, i=0; i<v.size(); ++i)
    if(v.at(i)>=0) // неотрицательный
      v.at(m++)=v.at(i); // копируем и увеличиваем счетчик неотриц. элементов
  v.resize(m); // уменьшаем длину последовательности
  cout<<"Rezultat"<<endl;
  for(i=0; i<v.size(); ++i)
    cout<<" "<<v.at(i); // выводим ее элементы
  cout<<endl;
  char ch; 
  cin>>ch; // ждем нажатия буквы и Enter
  return 0;
}
(с)Shell
 

    MaR*DeR

    очки: 3
    Посиб
Frostbite, ещё раз повторяю, что исходные коды нужно обрамлять тэгами!!!

[url=http://city.is74.ru/forum/index.php?posts/1513124
 
кто нибудь знает, в какой библиотеке в MSVС++ находятся функции cout<< cin>> ?
 
мож кому пригодится, вот что эти кретины в 7ом MSVC придумали:


2.1: I'm trying to use a standard C++ library class (like cout, cin, or string) but the compiler gives an undeclared identifier error (C2065) on those names. Why? (top)
The STL (standard template library) classes are separated into the std namespace. When referring to classes and functions in that namespace, you must preface them with std:: For example:
std::string str = "Salut, tout le monde!";

std::cout << str.c_str() << std::endl;
Alternatively, you can put this line at the top of your .CPP file:
 

Shell

Ословед
Konung написал(а):
мож кому пригодится, вот что эти кретины в 7ом MSVC придумали:
Это не они придумали, а комитет по стандартизации C++
А кретины из Microsoft придумали C#
 
K

KremLiN

хм... я быстро привык.. к префиксу namespace std::
...так зато логичнее (имхо)
если так привык к старому всегда же можно:
Код:
using std::cout;
using std::cin;
using std::string;
 

Sprut

Ословед
вышел новый msvc? если есть скажите ссылку, и может ктонить поможет с таб контролом в библеотеках MFC
 

Mironov Ivan

Ословед
Хммммм... Народ, а вы вообще в курсе, что ВСЕ средства стандартной библиотеки C++ находятся в пространстве имён std? В том числе и cin/cout/cerr/clog. Вся стандартная библиотека идёт через заголовочники без расширения, например тот же "iostream". Для совместимость с C (не ++) есть старые хедеры с "*.h" примерно такого вида:
Код:
...
#include <iostream>
...
using std::cout;
using std::cin;
using std::cerr;
using std::clog;
...
Так что если стандартный сишный ввод/вывод нужен вне std, то юзайте iostream.h, иначе iostream. Последнее предпочтительней, так как не засоряет глобальное пространство имён, и вообще смешивать два языка - вроде как нехорошо =) =) =).
 

Shell

Ословед
Mironov Ivan написал(а):
Микрософт как обычно ЖЖОТ! В VC8 тоже этот заголовочник убрали =(.
При чем тут MS :innocent: ? Пока С++ не стандартизировали, этот заголовник был, а после 1999 года запретили :rip:
 

Mironov Ivan

Ословед
Shell написал(а):
При чем тут MS :innocent: ? Пока С++ не стандартизировали, этот заголовник был, а после 1999 года запретили :rip:
В гнутом компиляторе этот заголовочник как был, так и остался... Микрософт просто решил забить на обратную совместимость (которая как раз таки по стандарту вроде бы должна быть).
 

maximus_veliky

Ословед
Mironov Ivan написал(а):
В гнутом компиляторе этот заголовочник как был, так и остался... Микрософт просто решил забить на обратную совместимость (которая как раз таки по стандарту вроде бы должна быть).
Одна майкрософт знает, что она делает, но не всё выкладывает налюди.
Многое скрывают.
 
C

Crying Devil Dante

Парни подскажите неплохой компилятор с\с++ для обеих платформ, если есть такие и желательно ссылку в осле...
 

Shell

Ословед
Crying Devil Dante написал(а):
Парни подскажите неплохой компилятор с\с++ для обеих платформ, если есть такие и желательно ссылку в осле...
GNU C/C++ есть под Windows и Linux
и можно попробовать комбинацию Kylix 3/Builder C++ 6

Тебе оконное что-то делать?
 
C

Crying Devil Dante

Shell написал(а):
GNU C/C++ есть под Windows и Linux
и можно попробовать комбинацию Kylix 3/Builder C++ 6

Тебе оконное что-то делать?
Ну я только начал изучать с\с++, мне ченить чтоб и понятно и функционально... и желательно под обе платформы..
 

Shell

Ословед
Crying Devil Dante написал(а):
Ну я только начал изучать с\с++, мне ченить чтоб и понятно и функционально... и желательно под обе платформы..
Вот нашел в eMule
Borland C++ Builder X.mdf
Borland C++ Builder X.mds
На сайтах написано, что с одного диска ставится под Windows/Red Hat Linux/Solaris
 
Сверху