Container: std::vectorTrail Index | Containers | Container Vector Vector is a numerically, sequentially indexed container, that can be expanded or shrunk. If you are a physicist, please note that It offers fast direct access, but somewhat slower insertion, appending and deletion.
If you need to modify the stored data frequently, you should consider using other containers like Basic std::vectorThe first examples with a simple vector of doubles. /* * Containers: Basic std::vector */ #include <iostream> #include <vector> // new header for vector int main() { using std::cout; using std::endl; /* * note the syntax: std::vector<type> variableName * This is an example of something called "template" */ std::vector<double> values; cout<< "vector size: "<<values.size() <<endl; for (int i=0;i<13;i++) { // append an element at the end values.push_back(3.1*i); } cout<< "vector size: "<<values.size() <<endl; // note: < not <= !! for (int i=0;i<values.size();i++) { /* * vector<>::operator[] is the "accessor" * that returns the element with the requested index. * Valid indexes are from 0 to size()-1 included */ cout<< "values element "<<i<<") "<< values[i] <<endl; } /* * copy the vector */ std::vector<double> values2=values; /* * the copy is a "deep copy", * fully independent, as you can check modifying * an element */ values[2]=5.; cout<< "values element "<<2<<") "<< values[2] <<endl; cout<< "values2 element "<<2<<") "<< values2[2] <<endl; /* * clear the vector */ cout<< "* empty the vector\n"; values.clear(); cout<< "vector size: "<<values.size() <<endl; cout<< "vector copy size: "<<values2.size() <<endl; return 0; } Objects in std::vectorUsage of vectors with objects is not any different; just note that for certain container operations object must provide a default constructor (either the implicit one that exists when no constructor is defined, or an explicit one) /* * Containers: Objects in std::vector */ #include <iostream> #include <vector> // new header for vector #include <cmath> /* * A simple container for x,y,error */ struct DataPoint { double x,y,e; DataPoint(double _x, double _y, double _e): x(_x),y(_y),e(_e) {} }; int main() { using std::cout; using std::endl; std::vector<DataPoint> values; cout<< "vector size: "<<values.size() <<endl; for (int i=0;i<13;i++) { const double x=4+.2*i; const double y=3.1*x*x; const double e=sqrt(y); /* * construct the object on the fly, and put (a copy of) it in the vector */ values.push_back(DataPoint(x,y,e)); } cout<< "vector size: "<<values.size() <<endl; for (int i=0;i<values.size();i++) { DataPoint& p = values[i]; cout<< "vector element "<<i<<") "<< p.x <<", "<< p.y <<", "<< p.e <<endl; } return 0; } Advanced use of std::vectortoo advanced here ? /** * Containers: std::vector iterator and other advanced items. * Here be dragons - you can skip this at first reading */ #include <iostream> #include <cmath> #include <vector> // new header for vector struct DataPoint { double x,y,e; DataPoint(double _x, double _y, double _e): x(_x),y(_y),e(_e) {} /* * note that I now have to provide a * default constructor (no arguments) */ DataPoint():x(0),y(0),e(0) {} }; /* * Some more operator "magic". * Define how to output DataPoint to an output stream * (like cout) */ std::ostream& operator<< (std::ostream& os,const DataPoint& p) { return os<<"("<<p.x<<","<<p.y<<","<<p.e<<")"; } int main() { using std::cout; using std::endl; /* * set initial size. * this needs the default constructor for the class. */ std::vector<DataPoint> values(3); cout<< "vector size: "<<values.size() <<endl; for (int i=0;i<6;i++) { const double x=4+.2*i; const double y=3.1*x*x; const double e=sqrt(y); values.push_back(DataPoint(x,y,e)); } cout<< "vector size: "<<values.size() <<endl; // use the operator<< cout<< "vector element 2) "<< values[2] <<endl; { /* * This is good (and actually faster, because it does not * recalculate size() at each iteration) but * only if you don't modify the container * inside the loop. Otherwise its size may change!! */ int n=values.size(); for (int i=0;i<n;i++) { DataPoint& p = values[i]; cout<< "vector element "<<i<<") "<< p <<endl; } } /** * All STL containers support iterators. * * An iterator is not an object instance, but a "pointer" to it. * - values.begin() is a pointer to the first element * - p++ steps to the next element * - values.end() is an invalid value, that signals * "gone bejond last element" * - never p<v.end() , but p != v.end() * * This does not require checking size() at each loop, * is available and fast also for non-indexed containers like lists * But the sintax is awkward. */ for (std::vector<DataPoint>::const_iterator p=values.begin();p!=values.end();p++) { /* * "*p" "dereferences" the iterator into an object instance; * "p->e" is a shorthand for (*p).e */ cout<< "vector element "<< *p << " error: "<< p->e <<endl; } cout<< "vector size: "<<values.size() <<endl; cout<< "vector element 2)"<< values[2] <<endl; cout<< "* remove an element in the middle\n"; values.erase(values.begin()+2); cout<< "vector size: "<<values.size() <<endl; cout<< "vector element 2)"<< values[2] <<endl; cout<< "* insert an element in the middle\n"; values.insert(values.begin()+3,DataPoint(2,2,2)); cout<< "vector size: "<<values.size() <<endl; cout<< "vector element 2)"<< values[2] <<endl; cout<< "* empty the vector\n"; values.clear(); cout<< "vector size: "<<values.size() <<endl; /* * vector<>::at() is a controlled accessor for an element; * it throws an exception if the index is out of range; * Exceptions can be "catched" and managed in the code. */ // cout<< "vector element 100)"<< values.at(100) <<endl; /* * the common vector<>::operator[] accessor instead * would give a hard error, like a segmentation fault, * abruptly terminating the program. */ // cout<< "vector element 100)"<< values.[100] <<endl; return 0; } < Containers | Trail Index | Container String > |