C 入門教程(八十五) 迭代器的簡單介紹

2021-08-18 17:40:26 字數 3359 閱讀 4346

小古銀的官方**(完整教程):

本部分教程將講解迭代器的使用,這樣就可以更靈活地使用c++的容器庫和演算法庫。設計迭代器將留到高階教程中講解。

在前面排序的教程中,曾經使用過迭代器,迭代器為演算法庫和容器庫之間的操作提供了通用的方案,使得我們使用它們的時候非常方便。

我們熟悉的字串類和std::vector都有很多成員函式需要或者返回迭代器。例如前面排序用到的成員函式begin()end()就是返回第乙個位置和最後乙個位置的迭代器,然後給std::sort()函式呼叫;還有就是std::vectorinsert()erase()都是必須以迭代器作為引數來操作。

如果指標儲存靜態陣列位址,那麼這個指標也算是乙個迭代器,例如下面的指標p

int array[10]{};

int *p = array + 4;

像上面的指標p儲存了array[4]的位址。因為指標儲存了這個陣列中某個元素的位址,我們知道靜態陣列中的位址是連續的,也就是說這個指標相當於儲存了這個陣列的某個元素的位置,然後可以通過*對位址代表的記憶體進行操作。

接著這個指標還可以通過++來移動到下個元素的位置,也可以通過--來移動到上個元素的位置。

int array[10]{};

int *p = array + 4;

++p; // 移動到下乙個元素, 就是array[5]的位置

++p; // 移動到下乙個元素, 就是array[6]的位置

++p; // 移動到下乙個元素, 就是array[7]的位置

--p; // 移動到上乙個元素, 就是array[6]的位置

*p = 666; // 給當前位置的元素賦值為666

像這樣,可以逐個元素按順序地移動指標就是迭代,這就是迭代器(英文:iterator)這個名稱的由來。

而我們使用的迭代器大部分都是類,這些迭代器類的用法,會盡量保持和指標一樣的操作,所以我們可以像指標那樣使用迭代器。更具體的用法在接下來的教程中慢慢講解,這裡不需要太深入了解,只要看了後面講解的使用方法,就會很容易明白迭代器是什麼了。

迭代器基本上都是專用的,如std::vector的迭代器不能用來儲存std::string的元素位置,如下,去掉最後兩行開頭注釋將會編譯報錯:

std::vector::iterator iter1; // std::vector的迭代器

std::vector::iterator iter2; // std::vector的迭代器

std::string::iterator iter3; // std::string的迭代器

// iter1 = iter2; // std::vector和std::vector不是同一種型別

// iter1 = iter3; // std::vector和std::string不是同一種型別

但是所有的迭代器都會統一操作,遮蔽了這些操作的細節,使得我們每次都可以用相同的方法操作迭代器。例如我們使用迭代器的時候使用++,就會使迭代器指向下乙個元素,但是迭代器類內部的**不一定是寫了++,有可能是其他。

因為迭代器統一了操作,所以演算法庫就可以很輕鬆地操作各種不同的容器了。

標準迭代器有五種:

程式經常會用到容器,而使用容器基本上離不開使用迭代器。只是使用迭代器的話,暫時不需要精通迭代器,但是基本的規則是要知道的。

std::list::iterator iter1; // std::list的迭代器是雙向迭代器

std::vector::iterator iter2; // std::vector的迭代器是隨機訪問迭代器

iter2 += 4; // 允許隨機訪問任何的元素, 這裡是直接跳到這個元素後的第四個元素的位置

++iter1; // 雙向迭代器只支援++和--操作

// iter1 += 4; // 雙向迭代器不支援隨機訪問, 也就是不能跳著訪問其他元素

容器std::vector使用的是隨機訪問迭代器,例如上面的iter2 += 4;就是從當前位置跳到它後面的第四個元素的位置上,也可以跳到其他位置,這就是隨機訪問。而std::list的迭代器是雙向迭代器,它只提供了++--操作,所以iter1 += 4;是會編譯報錯的,如果需要iter1移動到它後面的第四個元素的位置,只能使用四次的++iter1;

在說明文件中,都會說明容器的迭代器的種類。如果知道迭代器種類,但不知道這個種類的迭代器怎麼用就很尷尬了。以下列出所有迭代器種類對應的必須提供的操作(假設x是迭代器資料型別,ab是迭代器變數,n是整數,t是值,m是成員):

種類屬性

示例所有種類

可複製構造、可複製賦值並且可以析構

x b(a);

b = a;

可以遞增

++aa++

隨機訪問

雙向前向

輸入支援相等和不相等的比較操作

a == b

a != b

可以解引用成乙個右值

*aa->m

輸入可以解引用成乙個左值

(前提是允許修改內容的迭代器資料型別)

*a = t

*a++ = t

可以預設構造

x a;

x()無論是解引用還是自增,都不能影響解引用的行為

可以遞減

–aa–

*a–支援算術操作符 + 和 -

a + n

n + a

a - n

a - b

支援 < 、 > 、 <= 和 >= 這些比較操作

a < b

a > b

a <= b

a >= b

支援 += 和 -= 操作

a += n

a -= n

支援偏移解引用操作( )

a[n]

c 入門教程 十五

好久沒敲黑板了 前方高能預警 今天的內容可能有些繞,但是,蠻有用的。至少,好玩。前面我們說過,宣告乙個變數,相當於在記憶體中要了一塊空間。不同型別的變數要的空間的大小是不一樣的。既然有了空間,那麼,它就有個開始的位置 比如學校就有門牌號 我們用符號 來獲取乙個變數的位址。用法如下 要獲取首位址的變數...

C 入門教程(八十) 多重繼承

小古銀的官方 完整教程 多重繼承的呼叫順序 多重繼承的呼叫順序總結 多重繼承就是派生類繼承了多個基類。我們知道繼承可以將基類的所有成員都繼承下來作為自己的成員,重繼承也是一樣。include std cout std endl class base1 class base2 class derive...

C 入門教程(十五) 數字與進製

小古銀的官方 完整教程 補充知識 了解即可 鞏固練習 當你完成上一部分教程的全部練習後,相信你應該可以靈活地使用c 去解決大部分問題,尤其是數學問題。本部分教程將講解c 中必須知道的計算機基礎知識,知道這些知識可以避免不少的錯誤,還可以對程式 進一步優化。由於這部分教程只講解c 需要知道的計算機基礎...