文档章节

【C++注意事项】7 Library vector Type

NoMasp
 NoMasp
发布于 2015/09/08 21:47
字数 1307
阅读 5
收藏 0

List Initializer or Element Count?

In a few cases, what initialization means depends upon whether we use curly braces or parentheses to pass the initializer(s). For example, when we initialize a vector< int > from a single int value, that value might represent the vector’s size or it might be an element value. Similarly, if we supply exactly two int values, those values could be a size and an initial value, or they could be values for a two-element vector. We specify which meaning we intend by whether we use curly braces or parentheses:

vector<int> v1(10);  // v1 has ten elements with value 0
vector<int> v2{10};  // v2 has one elements with value 10
vector<int> v3(10,1);  // v3 has tem elements with vlaue 1
vector<int> v4{10,1};  // v4 has two elements with values 10 and 1

When we use parentheses, we are saying that the values we supply are to be used to construct the object. Thus, v1 and v 3 use their initializers to determine the vector’s size, and its size and element values, respectively.

When we use curly braces, {…}, we’re saying that, if possible, we want to list initialize the object. That is, if there is a way to use the values inside the curly braces as a list of element initializers, the class will do so. Only if it is not possible to list initialize the object will the other ways to initialize the object be considered. The values we supply when we initialize v2 and v4 can be used as element values. These objects are list initialized; the resulting vectors have one and two elements, respectively.

On the other hand, if we use braces and there is no way to use the initializers to list initialize the object, then those values will be used to construct the object. For example, to list initialize a vector of strings, we must supply values that can be used as strings. In this case, there is no confusion about whether to list initialize the elements or constructs a vector of the given size:

vector<string> v5{"hi"};  // list initialization: v5 has one element
vector<string> v6("hi");  // error: can't construct a vector from a string literal
vector<string> v7{10};  // v7 has ten default-initialized elements
vector<string> v8{10,"hi"};  // v8 has tem elements with value "hi"

Although we used braces on all but one of these definitions, only v5 is list initialized. In order to list initialize the vector, the values inside braces must match the element type. We can’t use an int to initialize a string, so the initializers for v7 and v8 can’t be element initializers. If list initialization isn’t possible, the compiler looks for other ways to initialize the object from the given values.

Adding Elements to a vector

As one example, if we need a vector with values from 0 to 9, we can easily use list initialization. What if we wanted elements from 0 to 99 or 0 to 999 ? List initialization would be too unwieldy. In such cases, it is better to create an empty vector and use a vector member named push_back to add elements at run time.

The push_back operation takes a value and “pushes” that value as a new last element onto the “back” of the vector.

vector<int> v2;  // empty vector
for(int i=0; i!= 100; ++i)
    v2.push_back(i);  // append sequential integers to v2
// at end of loop v2 has 100 elements, values 0 ... 99

We use the same approach when we want to create a vector where we don’t know until run time how many elements the vector should have. For example, we might read the input, storing the values we read in the vector:

// read words from the standard input and store them as elements in a vector
string word;
vector<string> text;  // empty vector
while(cin>> word)
    text.push_back(word);  // append word to text

Again, we start with an initially empty vector. This time, we read and store an unknown number of values in text.

Starting with an empty vector and adding elements at run time is distinctly different from how we use built-in arrays in C and in most other languages. In particular, if you are accustomed to using C or Java, you might expect that it would be best to define the vector at its expected size. In fact, the contrary is usually the case.

Other vector Operations

In addition to push_back, vector provide only a few other operations, most of which are similar to the corresponding operations on strings.

Operations Notes
v.empty() Returns true if v is empty; otherwise returns false.
v.size() Returns the number of elements in v.
v.push_back(t) Adds an element with value t to end of v.
v[n] Returns a reference to the element at position n in v.
v1=v2 Replaces the elements in v1 with a copy of the elements in v2.
v1={a,b,c…} Replaces the elements in v1 with a copy of the elements in the comma-separated list.
v1==v2,v1!=v2 v1 and v2 are equal if they have the same number of elements and each element in v1 is equal to the corresponding element in v2.
<, <=, >, >= Have their normal meaning using dictionary ordering.

We access the elements of a vector the same way that we access the characters in a string: through their position in the vector. For example, we can use a range for to process all the elements in a vector:

vector<int> v{1,2,3,4,5,6,7,8,9};
for(auto &i: v)  // for each element is v (note: i is a reference)
    i*= i;  // square the element value
for(auto i: v)  // for each element in v
    cout<< i << " ";  // print the element
cout<<endl;

The output should be

1 4 9 16 25 36 49 64 81

To use size_type, we must name the type in which it is defined. A vector type always includes its element type:

vector<int>:: size_type  // ok
vector::size_type  // error

Subscripting Does Not Add Elements

Programmers new to C++ sometimes think that subscripting a vector adds elements; it does not. The following code intends to add tem elements to ivec:

vector<int> ivec;  // empty vector
for(decltype(ivec.size()) ix= 0; ix!= 10; ++ix)
    ivec[ix]= ix;  // disaster: ivec has no elements

However, it is in error: ivec is an empty vector; there are no elements to subscript! As we’ve seen, the right way to write this loop is to use push_back:

for(decltype(ivec.size()) ix= 0; ix!= 10; ++ix)
    ivec.push_back(ix);  // ok: adds a new element with value x

The subscript operator on vector (and string) fetches an existing element; it does not add an element.

Subscript Only Elements that are Known to Exist!

It is crucially important to understand that we may use the subscript operator (the [] operator) to fetch only elements that actually exist. For example,

vector<int> ivec;  // empty vector
cout<< ivec[10];  // error: ivec has no elements!
vector<int> ivec2(10);  // vector with ten elements
cout<< ivec2[10];  // error: ivec2 has elements 0...9

It is an error to subscript an element that doesn’t exist, but it is an error that the compiler is unlikely to detect. Instead, the value we get at run time is undefined.

Attempting to subscript elements that do not exist is, unfortunately, an extremely common and pernicious programming error. So-called buffer overflow errors are the result of subscripting elements that don’t exist. Such bugs are the most common cause of security problems in PC and other applications.

版权声明:本文为 NoMasp柯于旺 原创文章,未经许可严禁转载!欢迎访问我的博客:http://blog.csdn.net/nomasp

本文转载自:http://blog.csdn.net/nomasp/article/details/45920313

NoMasp
粉丝 7
博文 334
码字总数 0
作品 0
镇江
程序员
私信 提问
工程系列-CMakeLists.txt

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/googler_offer/article/details/86422237 1、cmakeminimumrequired(VERSION 2.8) cmake最低版本,如果CMake的...

googler_offer
01/13
0
0
Bjarne Stroustrup's C++ Style and Technique FAQ

Bjarne Stroustrup's C++ Style and Technique FAQ Modified October 4, 2009 Source: http://www2.research.att.com/~bs/bs_faq2.html#void-main ========================================......

长平狐
2013/01/06
194
0
STL vector 介绍连载1-2-3

STL简介: STL = Standard Template Library,标准模板库,惠普实验室开发的一系列软件的统称。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普实验室工作时所开发出来的。这可能是...

天远
2012/05/20
152
0
C++ Primer 学习笔记(第三章:字符串、向量和数组)

C++ Primer 学习笔记(第三章:字符串、向量和数组) [TOC] 3.1 命名空间的声明 声明语句可以一行放多条。 位于头文件的代码,一般来说不应该使用声明。因为其内容会拷贝到每个使用该头文件的...

ShawnLue
2015/08/20
152
0
Effective STL - 容器

STL(standard template library)提供了一组表示容器,迭代器,函数对象和算法的模板。容器是一个与数组类似的单元,可以存若干个值。 STL容器是同质的,即存储的值的类型相同;算法是完成特...

積木leayn
2013/10/07
148
0

没有更多内容

加载失败,请刷新页面

加载更多

川普给埃尔多安和内堪尼亚胡的信

任性 https://twitter.com/netanyahu/status/1186647558401253377 https://edition.cnn.com/2019/10/16/politics/trump-erdogan-letter/index.htm...

Iridium
18分钟前
9
0
golang-mysql-原生

db.go package mainimport ("database/sql""time"_ "github.com/go-sql-driver/mysql")var (db *sql.DBdsn = "root:123456@tcp(127.0.0.1:3306)/test?charset=u......

李琼涛
46分钟前
5
0
编程作业20191021092341

1编写一个程序,把用分钟表示的时间转换成用小时和分钟表示的时 间。使用#define或const创建一个表示60的符号常量或const变量。通过while 循环让用户重复输入值,直到用户输入小于或等于0的值...

1李嘉焘1
46分钟前
7
0
Netty整合Protobuffer

现在我们都知道,rpc的三要素:IO模型,线程模型,然后就是数据交互模型,即我们说的序列化和反序列化,现在我们来看一下压缩比率最大的二进制序列化方式——Protobuffer,而且该方式是可以跨...

算法之名
52分钟前
18
0
如何用C++实现栈

栈的定义 栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压...

BWH_Steven
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部