The use of container vectors in C + +

Source: Internet
Author: User

Refer to C + + primer.

Vectors are a collection of objects of the same type, each with a corresponding integer index value. As with string objects, the standard library is responsible for managing the associated memory of the storage element. We refer to the vector as a container because it can contain other objects. All objects in a container must be of the same type. We will introduce the container in more detail in the 9th chapter.

before using vectors, you must include the appropriate header files. The example given in this book is the assumption that a corresponding using declaration has been made:


#include <vector>using std::vector;


       A vector is a class template. Templates allow programmers to write a single class or function definition that can be used on different data types. Therefore, we can define a vector that holds a string object, or a vector that holds an int value, or a vector that holds a custom class type object, such as a Sales_item object. The 16th chapter describes how to define a programmer's own class template. Fortunately, when using a class template, you simply need to understand how the class template is defined.


       Declaring a type of object produced from a class template requires additional information, depending on the template. Vector, for example, must describe what type of object the vector holds, specifying the type by placing the type in angle brackets following the name of the class template:


Vector<int> Ivec;                 Ivec holds objects of type intvector<sales_item> Sales_vec;  Holds Sales_items


       As with other variable definitions, define a vector object to specify a type and a list of variables. The first definition above, the type is vector<int>, which is a vector containing several types of int objects, the variable named Ivec. The second defined variable name is Sales_vec, and the element it holds is an object of type Sales_item.


       Vector is not a data type, but just a class template that can be used to define any number of data types. Each of the vector types specifies the type of the element it holds. Therefore, both vector<int> and vector <string> are data types.


3.3.1 the definition and initialization of vector objects


       The vector class defines several kinds of constructors (2. 3. Section 3), which defines and initializes the vector object. These constructors are listed below:

Several ways to initialize vector objects vector <t >  v1; vector holds objects of type T. The default constructor v1 is empty. Vector < T > v2 (v1); V2 is a copy of v1. Vector < T > v3 (n, i); V3 contains n elements with a value of I. Vector < T > v4 (n); V4 contains n copies of elements initialized by values.

1. Create an element with a certain number

       To create a non-empty vector object, you must give the value of the initialization element. When a vector object is copied to another vector object, each element in the newly copied vector is initialized to a copy of the corresponding element in the original vector. However, these two vector objects must hold the same type of element:

Vector<int> IVEC1;                IVEC1 holds objects of type intvector<int> ivec2 (IVEC1);       Ok:copy elements of IVEC1 into ivec2vector<string> Svec (IVEC1);    Error:svec holds strings, not ints

       The vector object can be initialized with the number of elements and the element value. The constructor uses the number of elements to determine the number of elements the vector object holds, and the element value specifies the initial value of each element:

Vector<int> Ivec4 (Ten,-1);     Ten elements, each initialized to-1vector<string> Svec ("hi!"); strings, each initialized to "hi!"

Key concepts: Dynamic growth of vector objects

The important attribute of vector objects (and other standard library container objects) is the ability to add elements efficiently at run time. Because vectors increase in efficiency, it is better to add elements dynamically when the element value is known.


as the 4th chapter will describe, this growth pattern differs from the built-in data types in C and the data types in most other programming languages. In particular, if the reader is accustomed to the C or Java style, as vector elements are stored continuously, it may be desirable to allocate the appropriate space beforehand. But in fact, in order to achieve continuity, C + + practice is the opposite, the specific reasons will be discussed in the 9th chapter.


While it is possible to pre-allocate memory for a vector object of a given number of elements, it is more efficient to initialize an empty vector object and then dynamically increment the element (we will then learn how to do so).



2. Value initialization


If the element's initialization is not given, then the standard library will provide a value-initialized (value initialized) element initializer. The initial value generated by the library is used to initialize each element in the container. The value of an element initializer depends on the data type of the element stored in the vector.


If the vector holds elements of a built-in type (such as int), the standard library creates an element initialization value with a value of 0:

Vector<string> Fvec (10); Ten elements, each initialized to 0

       If a vector holds an element of a class type (such as a string), the standard library creates the element's initial value with the default constructor for that type:


Vector<string> Svec (10); Ten elements, each of an empty string
       The 12th chapter introduces some classes with custom constructors but no default constructors, and when initializing this type of Vector object, the programmer cannot provide only the number of elements, but also the initial value of the element.


       There is a third possibility: the element type may be a class type that does not have any constructors defined. In this case, the standard library still produces an object with an initial value, and each member of the object is initialized with a value.


Exercise 3.11   which vectors are not defined correctly?   (a) vector < vector < int > > Ivec;   (b) Vector < string > Svec = Ivec;   (c) Vector < string > Svec ("null");


Answer: (b) not correct. Because SVEC is defined as a vector object that holds a string object, and Ivec is a vector object that holds the vector <int> object (that is, Ivec is a vector of vectors), the element types are different, so it cannot be initialized with Ivec. Svec.



Exercise 3.12 What   is the number of elements in each of the following vector objects? What are the values of each element?   (a) vector<int> ivec1;   (b) vector<int> ivec2 (ten);   (c) vector<int> ivec3 (10,42);   (d) vector<string> svec1;   (e) vector<string> svec2 (ten);   (f) vector<string> svec3 ("Hello");


Answer:   (a) The number of elements is 0.    (b) The number of elements is 10, and the values of each element are 0.    (c) The number of elements is 10, and the values of each element are 42.    (d) The number of elements is 0.    (e) The number of elements is 10, and the value of each element is an empty string.    

Operation of the 3.3.2 vector


The Vector Standard library provides many operations similar to string objects, and the following table lists some of the most important vector operations.

C.assign (beg,end) c.assign (N,elem) Assigns the data in the [beg; end] Interval to C. Assigns a copy of n elem to C.
c.at (IDX) Returns the index IDX refers to the data, if the IDX is out of bounds, throws Out_of_range.
C.back () Returns the last data without checking to see if the data exists.
C.begin ()
C.end ()
Returns the first data address in an iterator.
Points to the next end element in the iterator, pointing to a nonexistent element.
C.capacity () Returns the number of data in the container.
C.max_size ()
C.size ()
Returns the maximum number of data in a container.
Returns the number of actual data in the container.
C.empty () Determines whether the container is empty.


C.erase (POS)
C.erase (Beg,end)
C.clear ()

Deletes data from the POS location and returns the location of the next data.
Delete the data from the [Beg,end] interval and return to the location of the next data.
Removes all data from the container.
C.front () Returns the first data.
Get_allocator Use the constructor to return a copy.
C.insert (Pos,elem)
C.insert (Pos,n,elem)
C.insert (Pos,beg,end)
Inserts a elem copy at the POS location and returns the new data location.
Inserts n elem data at the POS location. no return value.
Inserts the data in the [Beg,end] interval at the POS location. no return value.


C.pop_back () Delete the last data.
C.push_back (Elem) Add a data to the trailer.
C.rbegin () Returns the first data for a reverse queue.
C.rend () Returns the next position of the last data in a reverse queue.
C.resize (num) Re-specify the length of the queue.
C.reserve () Keep the appropriate capacity.
C1.swap (C2)
Swap (C1,C2)
Swaps the C1 and C2 elements. The same operation.
Vector
Cvector C1 (C2)
Vector C (n)
Ector C (n, Elem)
Vector C (beg,end)

Create an empty vector.
Copy a vector.
Create a vector that contains n data, and the data is constructed by default.
Create a vector containing n elem copies.
Create a vector with an interval of [beg;end].

c.~ Vector () Destroys all data and frees up memory.
Operator[] Returns a reference to the specified position in the container.
Table vector Operations

1. Size of the Vector object

       The empty and size operations are similar to the related operation of type string (3. 2. Section 3). The member function size returns the value of the size_type defined by the corresponding vector class.

       When you use the Size_type type, you must indicate where the type is defined. The vector type always includes the element type of the vector:


Vector<int>::size_type        //Okvector::size_type          //Error


2. Adding elements to vectors

       The push_back () operation takes an element value and adds it to the back of the vector object as a new element, that is, "insert (push)" to the "back" of the vector object:

Read words from the standard input and store them as elements in a vectorstring word;vector<string> text;        Empty vectorwhile (cin >> Word) {    text.push_back (word);  Append Word to Text}


       The loop reads a series of string objects from the standard input, appending them to the back of the vector object. First, define an empty vector object text. A new element is added to the vector object once per loop, and the word value read from the input is assigned to the element. When the loop ends, the text contains all the elements that are read in.


3. Vector subscript operation


       Objects in the vector are not named and can be accessed by the position of the objects in the vector. You typically use the subscript operator to get an element. The subscript operation of a vector is similar to a string-type subscript operation (3.2.3 knots).


       The vector's subscript operator takes a value and returns the element at that corresponding position in the vector. The position of the vector element starts from 0. The following example uses a For loop to reset each element value in the vector to 0:


Reset the elements in the vector to Zerofor (vector<int>::size_type IX = 0; IX! = Ivec.size (); ++ix)    Ivec[ix] = 0;


       Like the string subscript operator, the vector subscript operation results in an lvalue, so the write can be implemented as it did in the loop body. In addition, similar to the subscript operation of a String object, the Size_type type is used as the type of vector subscript.


       In the example above, the for loop will execute correctly even if Ivec is empty. Ivec is empty, call size returns 0, and the test in for is compared with IX and 0. When the first loop occurs, the condition test fails and the For loop body does not execute once because IX itself is 0.


Key concepts: secure Generic programming


       C + + programmers who are accustomed to C or Java programming may find it difficult to understand that the for loop judgment condition uses! = instead of < to test whether the vector subscript value is out of bounds. C programmers are hard to understand also, the previous example did not call the size member function and save its return value before the for loop, but instead called the size member function in the For statement header.


C + + programmers are accustomed to using! = rather than < to write loop-judging conditions. In the above example, there is no particular reason for choosing or not to use an operator. After learning the generic programming of the second part of this book, you will understand the rationality of this habit.
Calling the size member function without saving the value it returns is also not required in this example, but it reflects a good programming habit. In C + +, some data structures, such as vectors, can grow dynamically. In the example above, the loop only needs to read the elements without adding new elements. However, the loop can easily add new elements, and if you do add new elements, then it is problematic to test the saved size value as the end condition of the loop because the newly added element is not counted. So we tend to test the current value of size in each loop instead of storing a copy of the size value when entering the loop.


We will learn in the 7th chapter that some functions in C + + can be declared as inline (inline) functions. Instead of making actual function calls, the compiler expands the code directly when it encounters an inline function. A small library function like size is almost defined as an inline function, so the cost of invoking it at the time of each loop is relatively small.



4. Subscript operation does not add elements


Novice C + + programmers may think that vector subscript operation can add elements, not actually:


Vector<int> Ivec;   Empty vectorfor (Vector<int>::size_type ix = 0; IX! = ten; ++ix)     Ivec[ix] = IX;//Disaster:ivec has no eleme Nts


       The above program attempts to insert 10 new elements into the Ivec, with the element values sequentially from 0 to 9 integers. However, here Ivec is an empty vector object, and the subscript can only be used to get an existing element.


       The correct notation for this loop should be:


for (Vector<int>::size_type IX = 0; IX! =, ++ix)     Ivec.push_back (ix);  Ok:adds new element with value IX

Must be an existing element to be indexed with the subscript operator. When you assign a value by using the subscript operation, no element is added.


       Warning: Subscript can only be done for elements that are known to exist


       It is important to use the subscript operator ([] operator) to extract only elements that do exist, such as:

Vector<int> Ivec;      Empty vectorcout << ivec[0];        Error:ivec has no elements! Vector<int> IVEC2 (10); Vector with ten elementscout << ivec[10];      Error:ivec has elements 0...9


       Attempting to get an element that does not exist inevitably produces a run-time error. As with most similar errors, there is no guarantee that the execution process can catch such errors, and the result of running the program is indeterminate. Because the result of a non-existent element is undefined, different implementations result in different results, but the program will almost certainly fail in some interesting way when it runs.
       This warning applies to any use of subscript operations, such as the subscript operation of type String, and the subscript operation of the built-in array that will be briefly described.
Unfortunately, trying to subscript non-existent elements is a serious mistake that is often made during programming. The so-called "buffer Overflow" error is the result of subscript operations on non-existent elements. Such defects often lead to the most common security issues in PCs and other applications.

Exercise 3.13  read a set of integers to the vector object, calculating and outputting each pair of adjacent elements. If the number of elements being read is odd, the user is prompted that the last element is not summed and its value is output. Then modify the program: Kinsoku element 22 pairing (first and last, second and penultimate, and so on), computes the and output of each pair of elements.

#include <iostream> #include <string> #include <vector>using namespace Std;int main () {    vector <int> Vec;    int n;    while (cin>>n)        vec.push_back (n);    if (!vec.size ()) {        cout<< "no numbers!") <<endl;        return-1;    }    for (Vector<int>::size_type i=0; I<vec.size ()-1; i+=2) {        cout<<vec[i]+vec[i+1]<< "\ t";        if ((i+1)%6==0) cout<<endl;    }    if (Vec.size ()%2!=0)        cout<<endl<< "Last number is:" <<vec[vec.size () -1]<<endl;    System ("PAUSE");    return 0;}

Exercise 3.14  reads a text into a vector object, and each word is stored as an element in the vector. Converts each word in the vector object to uppercase. Outputs the converted elements in the vector object, with each eight words being one line of output.

#include <iostream> #include <vector>using namespace Std;int main () {    cout<< "Enter a text (Ctrl + Z end):" <<endl;    Vector<string> Vecstr;    string Word;    while (Cin>>word)    {        vecstr.push_back (word);    }    if (vecstr.size () = = 0)    {        cout<< "no input string" <<endl;        return-1;    }    for (Vector<string>::size_type i = 0; i < vecstr.size (), i++)    {for        (String::size_type j = 0; J < ve Cstr[i].size (); J + +)        {            Vecstr[i][j] = ToUpper (Vecstr[i][j]);        }        cout<<vecstr[i]<< "";                if ((i+1)% 8 = = 0)        {            cout<<endl;        }    }    return 0;}


Exercise 3.15 is the  following procedure legal? If it's not legal, how do I correct it?   vector <int > Ivec;   Ivec [0] = 42;


Solution: not valid. Because Ivec is an empty vector object that contains no elements, the subscript operation can only be used to get an existing element. Correction: Change the assignment statement to statement Ivec.push_back (42);.

Exercise 3.16   lists three ways to define a vector object, given 10 elements, each with a value of 42. Indicate if there is a better way to implement it and why.

Solution: Method One: Vector<int> Ivec (10, 42); Method Two: Vector<int> Ivec (10); for (ix = 0; IX < ++IX) Ivec[ix] = 42; Method Three: Vector<int> Ivec (10); for (Vector<int>::iterator iter = Ivec.begin (); ITER! = Ivec.end (); ++iter) *iter = 42; Method four: Vector<int> Ivec; for (CNT = 1; CNT <=; ++cnt) Ivec.push_back (42); Method five: Vector<int> Ivec; Vector<int>::iterator iter = Ivec.end (); for (int i = 0; I! =) (++i) {Ivec.insert (iter); iter = Ivec.end (); The various methods can achieve the goal, perhaps the last two methods are better. They use container operations defined in the standard library to add elements to the container, eliminating the need to specify the size of the container when defining a vector object, which is more flexible and less prone to error.


Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

The use of container vectors in C + +

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.