詳解C++中的vector容器及用迭代器拜訪vector的辦法。本站提示廣大學習愛好者:(詳解C++中的vector容器及用迭代器拜訪vector的辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解C++中的vector容器及用迭代器拜訪vector的辦法正文
vector
vector是雷同類型對象的聚集。聚集中的每一個對象有個對應的索引。vector常被稱為容器(container)。
為了應用vector,須要:
#include <vector> using std::vector;
vector是一個類模版(class template)。C++有函數模版和類模版。模版自己不是函數或類,必需經由過程指定 類型讓編譯器去實例化(instantiation)它。好比vector<int> ivec。
vector是模版,不是類型。從vector獲得的類型要包括元素的類型。
晚期C++界說vector的元素是vector是,最初一個閉括號前必需有一個空格,如vector<vector<int> >。然則C++ 11不請求如許。
界說和初始化vectors
最常有的界說vectors的辦法以下:
辦法
說明
vector
須要留意的是,最經常使用應用vector的辦法就是界說一個起先為空的vector,即vector<T> v,在運轉時指定元素。
vector的列表初始化(list initializing)
下面應用花括號(curly brace)的辦法是列表初始化,是C++ 11引入的。
好比,
vector<string> articles = {"an", "a", "the"};
我們看到C++有許多初始化的方法,許多情形下它們是可以交換的,但有些時刻初始化的情勢是不克不及換的:
當應用拷貝初始化情勢(即便用=),只能供給單個初始化器
當供給in-class初始化,只能是拷貝初始化或許花括號
列表初始化只能應用花括號,不克不及是圓括號
有關value-initialized
後面提到vector<int> ivec(10)這類只指定元素個數的初始化辦法,每一個元素是value-initialized。即:
對內置類型,值為0
對類類型,應用默許初始化
花括號,圓括號
vector<int> v1(10); // 10個元素,都是0 vector<int> v1{10}; // 1個元素,是10 vector<int> v1{10, 1}; // 2個元素,分離是10, 1 vector<int> v1(10, 1); // 10個元素,都是1
須要留意的是,應用{}其實不必定就是列表初始化;它表現: 假如能夠的話,應用列表初始化。
vector<string> v5{"hi"}; // ok, list initialization vector<string> v6("hi"); // error: cann't construct vector from string lieral vector<string> v7{10}; // has ten default-initialized value.
下面的v7就應用花括號指定個數,而不是列表初始化。
向vector添加元素
應用push_back辦法。
主要概念:vector高效增加:
尺度請求vector的完成可以或許在運轉時高效添加。假如在界說vector時指定了年夜小,就顯得沒需要,乃至招致 差的機能。總之,普通直接開端界說一個空的vector。
別的,我們要確保即便輪回轉變了vector的年夜小,輪回也是准確的。是以,不克不及在range for外面向vector添加元素。
其它的vector操作
最經常使用的操作有:
辦法
v.empty()
v.size()
v.push_back(t)
v[n]
==, !=, <, <=, >, >=
相似的,v.size()前往的類型也是size_type的。須要留意的是,模版類的類型一直是包含元素類型的,
vector<int>::size_type // ok vector::size_type // error
關於下標拜訪,它只能拜訪曾經存在的元素,不會添加。
vector<int> ivec; cout << ivec[0]; // error for (decltype(ivev.size()) ix = 0; ix != 10; ix++) ivec[ix] = ix; // disaster: has no element
迭代器
雖然我們可使用下標來拜訪字符串中的字符或vector的元素,但更普通的機制是應用迭代器(iterator)。
一切的容器都支撐迭代器,但僅多數幾個支撐下標操作。
正當的迭代器:
應用begin和end成員函數。
// b 指導第一個元素;e 指導最初一個元素的下一個地位 auto b = v.begin(), e = v.end();
普通我們不用關懷迭代器的精確類型,所以直接應用auto。
end前往的迭代器普通被稱為off-the-end迭代器,或許縮寫為end迭代器。
明顯,假如一個容器為空,begin前往的和end前往的雷同。
迭代器的操作
| 辦法 | 說明 | | iter | 前往指導元素的援用 | | iter->mem | 解援用iter,並獲得名字為mem的成員,等價於 (iter).mem | | ++iter | 增長iter,指導下一個 | | --iter | 減小iter,指導前一個 | | == , != | 比擬 |
上面是把碰到空白字符前的字符轉成年夜寫。
for(auto it = s.begin(); it != s.end() && !isspace(*it); ++it) *it = toupper(*it);
熟習C或許Java說話的人能夠須要習氣C++外面for輪回普通都是應用!=停止,而不是應用<。 這是由於,一切的容器的迭代器都界說了!=和==辦法;而絕年夜部分迭代器沒有<辦法。經由過程應用!=,我們可以不用 關懷處置容器的精確類型。
迭代器的類型
就像我們不曉得vector或string的size_type的精確類型,我們普通也不曉得迭代器的精確類型。
庫類型的迭代器界說了iterator和const_iterator兩品種型。
vector<int>::iterator it; // 可讀,可寫 vector<int>::iterator it2; // 可讀,可寫 vector<int>::const_iterator it3; // 可讀,不克不及寫
const_iterator的行動相似一個const指針。就像const指針,const_iterator不克不及修正所指導的元素。假如 一個vector或許字符串是const的,那末只能應用const_iterator。
假如對象是const的,那末begin和end前往的就是const_iterator;假如對象不是const的,前往的就是iterator。 但這類行動有時不是我們想要的,即針對非const對象,我們也願望獲得const_iterator。C++ 11引入了兩個新的函數, cbegin和cend處理了這一成績。
auto it3 = v.cbegin();
解援用和拜訪成員
當對迭代器解援用時,獲得的是其指導的對象。假如該對象是個類類型的,我們能夠要拜訪其的成員。舉個例子,一個字符串的vector能夠想曉得 給定元素能否為空,可使用(*it).empty()。
須要留意的是,(*it).empty()這個括號是必需的。不然,點操作符直接感化於it。是以,*it.empty()是毛病的。
為了簡化這類表現,說話界說了箭頭操作符(->),它把解援用和成員拜訪組合為一個符號,即it->empty()。
迭代器的算術
自增與自減是一切迭代器都支撐的操作。
而關於string和vector的迭代器,還支撐額定的算術操作。
| 辦法 | | iter + n | | iter - n | | iter1 += n | | iter2 -= n | | iter1 - iter2 | | >, >=, <, <= |
好比,盤算vector中央地位,
auto mid = vi.begin() + vi.size() / 2;
須要留意的是,迭代器的相加是不正當的。