<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    PS,1880后程序員

    看不完的牙,寫不完的程序,跑不完的步。
    隨筆 - 97, 文章 - 34, 評(píng)論 - 10, 引用 - 0
    數(shù)據(jù)加載中……

    C++ Primer 之 讀書筆記 第九章

     

    順序容器 Sequential Containers

     

    類庫中定義了3種順序容器:vector, list, deque

    對(duì)應(yīng)3種適配器:stack, queue, priority_queue

    什么是適配器?

    每種適配器都會(huì)對(duì)應(yīng)一種容器,根據(jù)原始數(shù)據(jù)類型的操作重新定義了接口。

    9.1 定義順序容器

    容器初始化的方法有:

    1.      Intializing a Container as a Copy of Another Container

    將一個(gè)容器初始化為另一個(gè)容器的副本

    vector<int> ivec;

    vector<int> ivec2(ivec);   // ok: ivec is vector<int>

    2.      初始化為指定范圍的元素的副本

    這種方式和方式一的不同,就是不會(huì)限制容器的類型,只要元素element的類型能夠匹配或者能夠轉(zhuǎn)換就可以。因此可以把vector中的元素copylist

    下面這個(gè)例子把vector<char>拷貝給list<int>

    vector<char> cvec(10,'a');

    list<int> ilist(cvec.begin(), cvec.end() );

     

    // initialize slist with copy of each element of svec

    list<string> slist(svec.begin(), svec.end());

     

    // find midpoint in the vector

    vector<string>::iterator mid = svec.begin() + svec.size()/2;

     

    // initialize front with first half of svec: The elements up to but not including *mid

    deque<string> front(svec.begin(), mid);

    // initialize back with second half of svec: The elements *mid through end of svec

    deque<string> back(mid, svec.end());

    容器單元類型的限制條件

    1.      單元類型必須支持賦值assignment

    2.      單元類型必須可以拷貝

    根據(jù)這兩個(gè)限制條件得出:

    引用

    IO對(duì)象

    是不能作為單元類型的。

    但是單元類型也可以是容器。

    這和Java有些不一樣的地方:Java是不允許如int,double這樣的基本數(shù)據(jù)類型作為單元對(duì)象。

    9.2迭代器和迭代器范圍

    iterator的通用操作包括:

    *iter

    iter->mem

    ++iter iter++

    --iter iter--

    iter1 == iter2

    iter1 != iter2

    vectordeque支持額外的操作,包括:

    iter + n

    iter - n

    iter1 += iter2

    iter1 -= iter2

    iter1 - iter2

    >, >=, <, <=

    迭代器范圍

    迭代器范圍由一對(duì)迭代器來標(biāo)記。這兩個(gè)迭代器分別指向同一個(gè)容器中的兩個(gè)元素或超出末端的下一位置,通常將它們命名為 first last,或 beg end,用于標(biāo)記容器中的一段元素范圍。

    lastend的區(qū)別是last是指向迭代器范圍內(nèi)的最后一個(gè)元素,而end指向的是最后一個(gè)元素后的那個(gè)位置。

    l  [ first, last )

    這里所描述的迭代器范圍更多是用在例如erase,insert等容器的操作都會(huì)用到迭代器范圍的概念:

    void insert ( iterator position, InputIterator first, InputIterator last );

    iterator erase ( iterator first, iterator last );

    這些操作的迭代器范圍都是不包含last的。

    l  一些操作能夠使得迭代器失效,這類操作主要是添加和刪除操作,例如erase(),insert()

    9.3 Sequence Container Operations順序容器操作

    有四類:

    1.      Add elements to the container

    在容器中添加元素。

    2.      Delete elements from the container

    在容器中刪除元素。

    3.      Determine the size of the container

    設(shè)置容器大小。

    4.      Fetch the first and last elements from the container, if any

    (如果有的話)獲取容器內(nèi)的第一個(gè)和最后一個(gè)元素。

    Container Typedefs容器定義的類型別名

    每種容器都要定義一下的類型(type):

    size_type

    iterator

    const_iterator

    reverse_iterator

    const_reverse_iterator

    difference_type

    value_type

    reference

    const_reference

    咔咔,目前為止我不明白這些東東(value_typereferenceconst_reference是干嘛用的。大師說到16章就會(huì)豁然大悟的。期待

     

    在順序容器中添加元素

    iterator insert ( iterator position, const T& x );

    void insert ( iterator position, size_type n, const T& x );

    template <class InputIterator>

        void insert ( iterator position, InputIterator first, InputIterator last );

    container elements are copies.當(dāng)我們向一個(gè)容器中追加一個(gè)element時(shí),我們實(shí)際是把單元的值拷貝到容器里。這意味著后續(xù)的對(duì)容器內(nèi)的element改變是不會(huì)影響被拷貝的值的,反之亦然。

    這點(diǎn)就和Java有很大的不同,在Java中你可以把一個(gè)對(duì)象追加到Vector中,在后續(xù)的操作中修改Vector中每個(gè)element的值。也會(huì)導(dǎo)致最初被拷貝的對(duì)象值發(fā)生改變。

    以下是java代碼,

    {

      Vector a = new Vector();

      StringBuffer sb1= new StringBuffer();

      sb1.append("123");

      a.add(sb1);

      System.out.println( "<1> " + ((StringBuffer)a.elementAt(0)).toString());

      sb1.append("123");

      System.out.println( "<2> " + ((StringBuffer)a.elementAt(0)).toString());

    }

    輸出:

    <1> 123

    <2> 123123

    Java的容器中追加的應(yīng)該是對(duì)象的引用。

    任何的添加操作都會(huì)導(dǎo)致迭代器失效

    Relational Operators 關(guān)系操作符

    前提是相同的容器類型和相同的元素(element)類型要相同。

    容器的比較是使用和元素類型相同的關(guān)系操作符:就是說使用!=關(guān)系運(yùn)算符比較兩個(gè)容器,也就是使用!=關(guān)系運(yùn)算符比較元素類型。這樣如果元素類型并不支持這種比較操作,那么容器就不能進(jìn)行這樣的比較。

    C++ 語言只允許兩個(gè)容器做其元素類型定義的關(guān)系運(yùn)算。We can compare two containers only if the same relational operator defined for the element types.

    容器大小操作

    有四種關(guān)于大小的操作:

    size()

    empty()

    resize()

    max_size()

    resize()會(huì)導(dǎo)致迭代器失效(invalidate all iterators)。

    訪問元素

    4類操作,返回值是引用

    back()

    front()

    at         //如果越界,會(huì)拋出異常out_of_range exception

    operator[]  //只會(huì)產(chǎn)生run-time error

    不要和以下的操作混淆:

    begin()

    end()

    前一組操作返回的是引用,后一組beginend返回值是迭代器。但是二者還是有關(guān)系的:

    這組代碼真是簡(jiǎn)明扼要啊:(欣賞)

    // check that there are elements before dereferencing an iterator

    // or calling front or back

    if (!ilist.empty()) { //這個(gè)判斷絕對(duì)不能少哦

        // val and val2 refer to the same element

        list<int>::reference val = *ilist.begin(); //解引用

        list<int>::reference val2 = ilist.front();

     

        // last and last2 refer to the same element

        list<int>::reference last = *--ilist.end();

        list<int>::reference last2 = ilist.back();

    }

     

    刪除元素 Erasing Elements

    刪除操作有4類:

    erase()

    clear()

    pop_back()

    pop_front()

    注意:

    l  erase操作是不檢查參數(shù)的有效性的。因此要程序員來保證迭代器和迭代器范圍是有效的。As usual, the erase operations don't check their argument(s). It is up to the programmer to ensure that the iterator or iterator range is valid.

    l  刪除操作和添加操作一樣都會(huì)使得迭代器失效。

     

    賦值和交換 Assignment and swap

     

    9.5 決定使用哪種容器

    插入操作如何影響容器的選擇

    vectordeque提供快速的隨機(jī)訪問容器中元素,但是這是以在非結(jié)尾處添加或刪除元素開銷很大為代價(jià)的。而list恰好相反。

    list:當(dāng)追加或刪除元素時(shí),不需要移動(dòng)其它的元素。因此隨機(jī)訪問也就不支持。訪問一個(gè)元素需要遍歷所有的元素。

    vector:當(dāng)追加一個(gè)元素時(shí),這個(gè)元素右邊的所有元素都要移動(dòng)。因此在vector開始的位置插入或者刪除的開銷最大。

    deque:提供了vectorlist的特性。

    關(guān)于選擇使用哪一種容器的提示

    除非有其它更好的理由來使用其它的容器,否則vector是最好的選擇。

    容器選擇法則:

    1.      If the program requires random access to elements, use a vector or a deque.

    如果程序要求隨機(jī)訪問元素,則應(yīng)使用 vector deque 容器。

    2.      If the program needs to insert or delete elements in the middle of the container, use a list.

    如果程序必須在容器的中間位置插入或刪除元素,則應(yīng)采用 list 容器。

    3.      If the program needs to insert or delete elements at the front and the back, but not in the middle, of the container, use a deque.

    如果程序不是在容器的中間位置,而是在容器首部或尾部插入或刪除元素,則應(yīng)采用 deque 容器。

    4.      If we need to insert elements in the middle of the container only while reading input and then need random access to the elements, consider reading them into a list and then reordering the list as appropriate for subsequent access and copying the reordered list into a vector.

    如果只需在讀取輸入時(shí)在容器的中間位置插入元素,然后需要隨機(jī)訪問元素,則可考慮在輸入時(shí)將元素讀入到一個(gè) list 容器,接著對(duì)此容器重新排序,使其適合順序訪問,然后將排序后的 list 容器復(fù)制到一個(gè) vector 容器。

    起支配作用的操作決定容器的類型In general, the predominant operation of the application should determine the choice of container type.

     

    9.6 重新來看string string Revisited

    string看做容器

    string支持大多數(shù)的順序的容器操作。

    為什么要在這章里又單獨(dú)把string拎出來?因?yàn)?strong style="mso-bidi-font-weight: normal">可以把string看做是char的容器string只是不支持堆棧操作,例如:front, back, pop_back

    stringvector一樣,元素是按順序保存的。

    所以可以用迭代器來訪問一個(gè)string哦。

    string s("Hiya!");

    string::iterator iter = s.begin(); //這樣的代碼很奇特。

    while (iter != s.end())

        cout << *iter++ << endl; // postfix increment: print old value

    其它方式來創(chuàng)建string Other Ways to Construct strings

    繼承于vector的構(gòu)造函數(shù)

    string s1;           // s1 is the empty string

    string s2(5, 'a');   // s2 == "aaaaa"

    string s3(s2);       // s3 is a copy of s2

    string s4(s3.begin(), s3.begin() + s3.size() / 2); // s4 == "aa"

    string特有的構(gòu)造函數(shù):

    string s(cp, n)

    創(chuàng)建一個(gè) string 對(duì)象,它被初始化為 cp 所指向數(shù)組的前 n 個(gè)元素的副本

    string s(s2, pos2)

    創(chuàng)建一個(gè) string 對(duì)象,它被初始化為一個(gè)已存在的 string 對(duì)象 s2 中從下標(biāo) pos2 開始的字符的副本

    string s(s2, pos2, len2)

    創(chuàng)建一個(gè) string 對(duì)象,它被初始化為 s2 中從下標(biāo) pos2 開始的 len2 個(gè)字符的副本。

    Example:

    char *cp = "Hiya";            // null-terminated array

    char c_array[] = "World!!!!"; // null-terminated

    char no_null[] = {'H', 'i'};  // not null-terminated

     

    string s1(cp);             // s1 == "Hiya"

    string s2(c_array, 5);     // s2 == "World"

    string s3(c_array + 5, 4); // s3 == "!!!!"

    string s4(no_null);        // runtime error: no_null not null-terminated

    string s5(no_null, 2);     // ok: s5 == "Hi"

     

    其它方式來修改string

     

    string獨(dú)有的操作

     

     

    string的查找操作

     

     

     

    比較操作

     

     

     

    9.7 容器適配器

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    posted on 2009-06-04 11:21 amenglai 閱讀(347) 評(píng)論(0)  編輯  收藏 所屬分類: C++ Primer 之 讀書筆記

    主站蜘蛛池模板: 久久久精品2019免费观看| a毛片全部免费播放| 免费无码一区二区| 一区二区免费国产在线观看| 久久www免费人成看国产片| 曰批全过程免费视频在线观看无码| 国内永久免费crm系统z在线| 182tv免费观看在线视频| 女人18毛片水真多免费看| 亚洲А∨精品天堂在线| 亚洲gv猛男gv无码男同短文| 亚洲最新黄色网址| 亚洲精品人成网线在线播放va| 青娱乐在线免费观看视频| 国产免费拔擦拔擦8X高清在线人 | 亚洲国产精品日韩av不卡在线| 亚洲AV无码专区在线观看成人| 国产99久久久国产精免费| 91av视频免费在线观看| 好吊妞788免费视频播放| 亚洲色图综合在线| 亚洲成人黄色在线| 黄网站色成年片大免费高清| a毛片在线免费观看| 在线观看免费为成年视频| 亚洲中文字幕在线观看| 33333在线亚洲| 永久免费无码网站在线观看个| 99视频在线看观免费| 国产精品久免费的黄网站 | 亚洲AV无码久久精品狠狠爱浪潮| 亚洲av成人一区二区三区| 一级免费黄色毛片| 日本最新免费网站| 亚洲AV无码专区日韩| 亚洲黄网站wwwwww| 男女男精品网站免费观看| 久视频精品免费观看99| 国产一区二区三区免费视频| 亚洲综合日韩中文字幕v在线 | 男男gay做爽爽免费视频|