走近 STL

走近 STL
本文面向的讀者:學習過C++程序設計語言(也就是說學習過Template),但是還沒有接觸過STL的STL的初學者。這實際上是我學習STL的一篇筆記,老鳥就不用看了。

什麼是泛型程序設計
  我們可以簡單的理解爲:使用模板的程序設計就是泛型程序設計。就像我們我們可以簡單的理解面向對象程序設計就是使用虛函數的程序設計一樣。

STL是什麼
  作爲一個C++程序設計者,STL是一種不可忽視的技術。Sandard Template Library (STL):
標準模板庫,更準確的說是 C++ 程序設計語言標準模板庫。學習過MFC的人知道,MFC是微軟公司創建的 C++ 類庫。而與之類似的是 STL 是模板庫,只不過 STL 是 ANSI/ISO 標準的一部分,而 MFC 只不過是微軟的一個產品而已。也就是說STL是所有C++編譯器和所有操作系統平臺都支持的一種庫,說它是一種庫是因爲,雖然STL是一種標準,也就是說對所有的編譯器來說,提供給C++程序設計者的接口都是一樣的。也就是說同一段STL代碼在不同編譯器和操作系統平臺上運行的結果都是相同的,但是底層實現可以是不同的。 令人興奮的是,STL的使用者並不需要了解它的底層實現。 試想一下,如果我們有一把能打開所有鎖的鑰匙,那將是多麼令人瘋狂啊。嘎嘎。這個歪夢我做了20多年鳥。
  STL的目的是標準化組件,這樣你就不用重新開發它們了。你可以僅僅使用這些現成的組件。STL現在是C++的一部分,因此不用額外安裝什麼。它被內建在你的編譯器之內。

爲什麼我們需要學習STL
  • STL是 C++的ANSI/ISO 標準的一部分,可以用於所有C++語言編譯器和所有平臺(Windows/unix/linux..)。STL的同一版本在任意硬件配置下都是可用的;
  • STL 提供了大量的可複用軟件組織。例如,程序員再也不用自己設計排序,搜索算法了,這些都已經是STL的一部分了。嘎嘎,有意思吧;
  • 使用STL 的應用程序保證了得到的實現在處理速度和內存利用方面都是高效的,因爲STL設計者們已經爲我們考慮好了;
  • 使用STL編寫的代碼更容易修改和閱讀,這是當然的鳥。因爲代碼更短了,很多基礎工作代碼已經被組件化了;
  • 使用簡單,雖然內部實現很複雜;

  雖然,STL的優點甚多,但是STL的語法實在令初學者人頭疼,許多人望而卻步。可是STL是每個C++程序設計者遲早都要啃的一塊骨頭。因爲越來越多的C++代碼是用STL編寫的,看不懂麻煩就大鳥。越來越多的人在用STL,不懂就無法和別人一起合作了。好事多磨嘛,早點學習早點解脫。

下面讓我們來看幾段代碼吧:(你覺得頭疼就不要看了)


好懂吧,除了那個std有點讓人不舒服以外?這是一段普通的沒有使用STL的C++代碼。再看下面一段: 

  如果你真的沒有接觸過STL的話,你會問,呀,vector 是啥呀?我會告訴你,那是一排美女。嘎嘎。這可不是個比喻,表想歪鳥。這是一段純種的STL代碼,看到尖括號了吧,知道那是模板了吧。看到a.push_back(5),a.begin(),a.end()你不感覺奇怪麼?可是我們並沒有定義這些函數啊。 

  這一段你又看到了新東西了吧,iterator???不羅嗦了,等你看完這篇文章,回頭再看就簡單了。在正式介紹STL之前,我們需要花點時間來了解一下模板和命名空間。
  關於模板的其他細節,讀者可以參閱《C++ Templates 中文版》(有點費腦子哦)。在這裏,我只簡單的介紹一下模板類和函數模板的概念。
  模板是C++中實現代碼重用機制的一種工具,可以實現類型參數化,把類型定義爲參數。函數模板和類模板允許用戶構造模板函數和模板類。


圖1

下面我們來看一段函數模板的例子:

下面再看看,類模板: 

命名空間(名字空間)
  命名空間是C++的一種機制,用來把單個標識符下的大量有邏輯聯繫的程序實體組合到一起。此標識符作爲此組羣的名字。命名空間用關鍵字namespace 來定義:

  一個namespace是指一個具名的範圍(named scope)。namespace被用來將相關的聲明劃歸在一起,將不相關的代碼部分隔開。命名空間只是命名了一個特殊的作用域,當程序很大,而且需要多人合作的時候,命名空間就顯得特別的重要。比如2個程序員A,B 在同一個程序中定義了函數 pop(),如果沒有使用命名空間,則會出錯,而且這種錯誤難以檢測出來。爲了安全起見,他們可以定義不同的命名空間 A和B,在用的時候可以使用A::pop()和B::pop()來區分。
  在STL中,標準庫的全部成員在預先定義的命名空間std中。如果要用類模板vector ,有兩種方法:一是在程序的前面添加預處理指令:

第二種方法是: 

動態綁定和靜態綁定
  所謂綁定是指,對於參與多態行爲的類型,他們具有多態行爲的接口是在公共基類的設計中就預先確定的。而非綁定則對於參與多態行爲的類型,他們的接口沒有預先定義。
  在C++中通過繼承實現的多態是動態綁定,通過模板實現的多態是靜態綁定。動態綁定的接口是在運行期間(動態)完成的,靜態綁定的接口是在編譯期間(靜態)完成的。好了,有了以上的知識我們可以來學習STL 了。

STL 的組成
  STL有三大核心部分:容器(Container)、算法(Algorithms)、迭代器(Iterator),容器適配器(container adaptor),函數對象(functor),除此之外還有STL其他標準組件。
  • 容器:裝東西的東西,裝水的杯子,裝鹹水的大海,裝人的教室……STL裏的容器是可容納一些數據的模板類;
  • 算法:就是往杯子裏倒水,往大海里排污,從教室裏攆人……STL裏的算法,就是處理容器裏面數據的方法,操作;
  • 迭代器:往杯子裏倒水的水壺,排污的管道,攆人的那個物業管理人員……STL裏的迭代器:遍歷容器中數據的對象;

  對存儲於容器中的數據進行處理時,迭代器能從一個成員移向另一個成員。他能按預先定義的順序在某些容器中的成員間移動。對普通的一維數組、向量、雙端隊列和列表來說,迭代器是一種指針。
知道了吧?嘎嘎,當然了,你猜到了,那是我在瞎扯蛋。

下面讓我們來看看專家是怎麼說的:

  • 容器(container):容器是數據在內存中組織的方法,例如,數組、堆棧、隊列、鏈表或二叉樹(不過這些都不是STL標準容器)。STL中的容器是一種存儲T(Template)類型值的有限集合的數據結構,容器的內部實現一般是類。這些值可以是對象本身,如果數據類型T代表的是Class的話。
  • 算法(algorithm):算法是應用在容器上以各種方法處理其內容的行爲或功能。例如,有對容器內容排序、複製、檢索和合並的算法。在STL中,算法是由模板函數表現的。這些函數不是容器類的成員函數。相反,它們是獨立的函數。令人吃驚的特點之一就是其算法如此通用。不僅可以將其用於STL容器,而且可以用於普通的C++數組或任何其他應用程序指定的容器。
  • 迭代器(iterator):一旦選定一種容器類型和數據行爲(算法),那麼剩下唯一要他做的就是用迭代器使其相互作用。可以把達代器看作一個指向容器中元素的普通指針。可以如遞增一個指針那樣遞增迭代器,使其依次指向容器中每一個後繼的元素。迭代器是STL的一個關鍵部分,因爲它將算法和容器連在一起。

下面我將依次介紹STL的這三個主要組件。

容器
  STL中的容器有隊列容器和關聯容器,容器適配器(congtainer adapters:stack,queue,priority queue),位集(bit_set),串包(string_package)等等。
  在本文中,我將介紹list,vector,deque等隊列容器,和set和multisets,map和multimaps等關聯容器,一共7種基本容器類。
  隊列容器(順序容器):隊列容器按照線性排列來存儲T類型值的集合,隊列的每個成員都有自己的特有的位置。順序容器有向量類型、雙端隊列類型、列表類型三種。
基本容器——順序容器
  向量(vector容器類):#include <vector>,vector是一種動態數組,是基本數組的類模板。其內部定義了很多基本操作。既然這是一個類,那麼它就會有自己的構造函數。vector 類中定義了4中種構造函數:

  • 默認構造函數,構造一個初始長度爲0的空向量,
    如:vector<int> v1;
  • 帶有單個整形參數的構造函數,此參數描述了向量的初始大小。這個構造函數還有一個可選的參數,這是一個類型爲T的實例,描述了各個向量種各成員的初始值;
    如:vector<int> v2(init_size,0); 如果預先定義了:int init_size;他的成員值都被初始化爲0;
  • 複製構造函數,構造一個新的向量,作爲已存在的向量的完全複製,
    如:vector<int> v3(v2);
  • 帶兩個常量參數的構造函數,產生初始值爲一個區間的向量。區間由一個半開區間[first,last](MS word的顯示可能會有問題,first前是一個左方括號,last後面是一個右圓括號)來指定。
    如:vector<int> v4(first,last)
  • 下面一個例子用的是第四種構造方法,其它的方法讀者可以自己試試。

    
      爲了幫助理解向量的概念,這裏寫了一個小例子,其中用到了vector的成員函數:begin(),end(),push_back(),assign(),front(),back(),erase(),empty(),at(),size()。 
    
    
      push_back()是將數據放入vector(向量)或deque(雙端隊列)的標準函數。Insert()是一個與之類似的函數,然而它在所有容器中都可以使用,但是用法更加複雜。end()實際上是取末尾加一,以便讓循環正確運行--它返回的指針指向最靠近數組界限的數據。
      在Java裏面也有向量的概念。Java中的向量是對象的集合。其中,各元素可以不必同類型,元素可以增加和刪除,不能直接加入原始數據類型。

    雙端隊列(qeque容器類):#include <deque>
      deque(讀音:deck,意即:double queue)容器類與vector類似,支持隨機訪問和快速插入刪除,它在容器中某一位置上的操作所花費的是線性時間。與vector不同的是,deque還支持從開始端插入數據:
    push_front()。此外deque也不支持與vector的capacity()、reserve()類似的操作。
    
      上面我們演示了deque如何進行插入刪除等操作,像erase(),assign()是大多數容器都有的操作。關於deque的其他操作請參閱附錄。

    表(List容器類):#include <list>
       List又叫鏈表,是一種雙線性列表,只能順序訪問(從前向後或者從後向前),圖2是list的數據組織形式。與  前面兩種容器類有一個明顯的區別就是:它不支持隨機訪問。要訪問表中某個下標處的項需要從表頭或表尾處(接近該下標的一端)開始循環。而且缺少下標預算符:operator[]。


    圖2

      同時,list仍然包涵了erase(),begin(),end(),insert(),push_back(),push_front()這些基本函數,下面我們來演示一下list的其他函數功能。

    merge():合併兩個排序列表;
    splice():拼接兩個列表;
    sort():列表的排序;
    
      上面並沒有演示splice()函數的用法,這是一個拗口的函數。用起來有點麻煩。圖3所示是splice函數的功能。將一個列表插入到另一個列表當中。list容器類定義了splice()函數的3個版本: 
    
    
      list_value是一個已存在的列表,它將被插入到源列表中,position是一個迭代參數,他當前指向的是要進行拼接的列表中的特定位置。


    圖3
    
      執行listn1.splice(find(listn1.begin(),listn1.end(),0),listn2);之後,listn1將變爲:123,12,100,34,1123。即把listn2插入到listn1的0這個元素之前。其中,find()函數找到0這個元素在listn1中的位置。值得注意的是,在執行splice之後,list_value將不復存在了。這個例子中是listn2將不再存在。
      第二個版本當中的ptr是一個迭代器參數,執行的結果是把ptr所指向的值直接插入到position當前指向的位置之前.這將只向源列表中插入一個元素。
      第三個版本的first和last也是迭代器參數,並不等於list_value.begin(),list_value.end()。First指的是要插入的列的第一個元素,last指的是要插入的列的最後一個元素。

    如果listn1:123,0,34,1123 listn2:12,43,87,100 執行完以下函數之後
    
      以上,我們學習了vector,deque,list三種基本順序容器,其他的順序容器還有:slist,bit_vector等等。

    另一種容器——關聯容器(有點費解哦,出去讓腦子清醒一下再回來看)
      與前面講到的順序容器相比,關聯容器更注重快速和高效地檢索數據的能力。這些容器是根據鍵值(key)來檢索數據的,鍵可以是值也可以是容器中的某一成員。這一類中的成員在初始化後都是按一定順序排好序的。

    集和多集(set 和multiset 容器類):#include <set>
      一個集合(set)是一個容器,它其中所包含的元素的值是唯一的。這在收集一個數據的具體值的時候是有用的。集合中的元素按一定的順序排列,並被作爲集合中的實例。如果你需要一個鍵/值對(pair)來存儲數據,map(也是一個關聯容器,後面將馬上要講到)是一個更好的選擇。一個集合通過一個鏈表來組織,在插入操作和刪除操作上比向量(vector)快,但查找或添加末尾的元素時會有些慢。
      在集中,所有的成員都是排列好的。如果先後往一個集中插入:12,2,3,123,5,65
      則輸出該集時爲:2,3,5,12,65,123
      集和多集的區別是:set支持唯一鍵值,set中的值都是特定的,而且只出現一次;而multiset中可以出現副本鍵,同一值可以出現多次。

    Set和multiset的模板參數:
    
      第一個參數key是所存儲的鍵的類型,第二個參數是爲排序值而定義的比較函數的類型,第三個參數是被實現的存儲分配符的類型。在有些編譯器的具體實現中,第三個參數可以省略。第二個參數使用了合適形式的迭代器爲鍵定義了特定的關係操作符,並用來在容器中遍歷值時建立順序。集的迭代器是雙向,同時也是常量的,所以迭代器在使用的時候不能修改元素的值。

    Set定義了三個構造函數:
    默認構造函數:
    
      less<int>是一個標準類,用於形成降序排列函數對象。升序排列是用greater<int>。通過指定某一預先定義的區間來初始化set對象的構造函數:
    
    
    

    複製構造函數:

    
    

    下面我們來看一個簡單的集和多集的插入例程:

    
      在集之間可以進行並集(set_union())、交集(set_intersection())、差集(set_diffrence())d等操作,功能強大。

    映射和多重映射(map 和multimap):#include <map>
      映射和多重映射基於某一類型Key的鍵集的存在,提供對T類型的數據進行快速和高效的檢索。對map而言,鍵只是指存儲在容器中的某一成員。Map不支持副本鍵,multimap支持副本鍵。Map和multimap對象包涵了鍵和各個鍵有關的值,鍵和值的數據類型是不相同的,這與set不同。set中的key和value是Key類型的,而map中的key和value是一個pair結構中的兩個分量。Map支持下表運算符operator[],用訪問普通數組的方式訪問map,不過下標爲map的鍵。在multimap中一個鍵可以對應多個不同的值。

    下面的例程說明了map中鍵與值的關係。
    
      從以上例程中,我們可以看到map對象的行爲和一般數組的行爲類似。Map允許兩個或多個值使用比較操作符。下面我們再看看multimap: 
    
    
      在map中是不允許一個鍵對應多個值的,在multimap中,不支持operator[],也就是說不支持map中允許的下標操作。 

    算法(algorithm):#inlcude <algorithm>
      STL中算法的大部分都不作爲某些特定容器類的成員函數,他們是泛型的,每個算法都有處理大量不同容器類中數據的使用。值得注意的是,STL中的算法大多有多種版本,用戶可以依照具體的情況選擇合適版本。中在STL的泛型算法中有4類基本的算法:
    • 變序型隊列算法,可以改變容器內的數據;
    • 非變序型隊列算法,處理容器內的數據而不改變他們;
    • 排序值算法,包涵對容器中的值進行排序和合並的算法,還有二叉搜索算法 $$通用數值算法;

    注:STL的算法並不只是針對STL容器,對一般容器也是適用的。

    變序型隊列算法(mutating algorithms):
      又叫可修改的序列算法。這類算法有複製(copy)算法、交換(swap)算法、替代(replace)算法、刪除(remove)算法,移動(transfer)算法、翻轉(reverse)算法等等。這些算法可以改變容器中的數據(數據值和值在容器中的位置)。下面介紹2個比較常用的算法reverse()和copy()。

    
    revese()的功能是將一個容器內的數據順序翻轉過來,它的原型是: 
    
    
    將first和last之間的元素翻轉過來,上例中你也可以只將arr中的一部分進行翻轉: 
    
    
    Copy()是要將一個容器內的數據複製到另一個容器內,它的原型是: 
    
    
      它把[first,last-1]內的隊列成員複製到區間[result,result+(last-first)-1]中。泛型交換算法:Swap()操作的是單值交換,它的原型是: 
    
    
    swap_ranges()操作的是兩個相等大小區間中的值,它的原型是: 
    
    
      交換區間[first1,last1-1]和[first2, first2+(last1-first1)-1]之間的值,並假設這兩個區間是不重疊的。 

    非變序型隊列算法(Non-mutating algorithm)
      又叫不可修改的序列算法。這一類算法操作不影響其操作的容器的內容,包括搜索隊列成員算法,等價性檢查算法,計算隊列成員個數的算法。我將用下面的例子介紹其中的find(),search(),count():
    
    find()的原型是: 
    
    
      其功能是在序列[first,last-1]中查找value值,如果找到,就返回一個指向value在序列中第一次出現的迭代,如果沒有找到,就返回一個指向last的迭代(last並不屬於序列)。 search()的原型是: 
    
    
      其功能是在源序列[first1,last1-1]查找目標序列[first2,last2-1]如果查找成功,就返回一個指向源序列中目標序列出現的首位置的迭代。查找失敗則返回一個指向last的迭代。 Count()的原型是: 
    
    
      其功能是在序列[first,last-1]中查找出等於value的成員,返回等於value得成員的個數。

    排序算法(sort algorithm)
      這一類算法很多,功能強大同時也相對複雜一些。這些算法依賴的是關係運算。在這裏我只介紹其中比較簡單的幾種排序算法:sort(),merge(),includes()
    
    sort()的原型是: 
    
    
      功能是對[first,last-1]區間內的元素進行排序操作。與之類似的操作還有:partial_sort(), stable_sort(),partial_sort_copy()等等。 merge()的原型是: 
    
    
      將有序區間[first1,last1-1]和[first2,last2-1]合併到[result, result + (last1 - first1) + (last2 - first2)-1]區間內。

    Includes()的原型是:
    
      其功能是檢查有序區間[first2,last2-1]內元素是否都在[first1,last1-1]區間內,返回一個bool值。

    通用數值算法(generalized numeric algorithms)
      這一類算法還不多,涉及到專業領域中有用的算術操作,獨立包涵於頭文件<numeric>中(HP版本的STL中是<algo.h>)。這裏不作介紹。
      STL中的算法大都有多種版本,常見的版本有以下4中:
    • 默認版本,假設給出了特定操作符;
    • 一般版本,使用了成員提供的操作符;
    • 複製版本,對原隊列的副本進行操作,常帶有 _copy 後綴;
    • 謂詞版本,只應用於滿足給定謂詞的隊列成員,常帶有 _if 後綴;

      以上我們學習了STL容器和算法的概念,以及一些簡單的STL容器和算法。在使用算法處理容器內的數據時,需要從一個數據成員移向另一個數據成員,迭代器恰好實現了這一功能。下面我們來學習STL迭代器 。

    迭代器(itertor):#include<iterator>
      迭代器實際上是一種泛化指針,如果一個迭代器指向了容器中的某一成員,那麼迭代器將可以通過自增自減來遍歷容器中的所有成員。迭代器是聯繫容器和算法的媒介,是算法操作容器的接口。在運用算法操作容器的時候,我們常常在不知不覺中已經使用了迭代器。
    STL中定義了6種迭代器:

    • 輸入迭代器,在容器的連續區間內向前移動,可以讀取容器內任意值;
    • 輸出迭代器,把值寫進它所指向的隊列成員中;
    • 前向迭代器,讀取隊列中的值,並可以向前移動到下一位置(++p,p++);
    • 雙向迭代器,讀取隊列中的值,並可以向前向後遍歷容器;
    • 隨機訪問迭代器, vector<T>::iterator,list<T>::iterator等都是這種迭代器 ;
    • 流迭代器,可以直接輸出、輸入流中的值;

      實際上,在前面的例子中,我們不停的在用迭代器。下面我們用幾個例子來幫助理解這些迭代器的用法。
    下面的例子用到了輸入輸出迭代器:

    
      這裏用到了輸入迭代器istream_iterator,輸出迭代器ostream_iterator。程序完成了將一個文件輸出到屏幕的功能,先將文件讀入,然後通過輸入迭代器把文件內容複製到類型爲字符串的向量容器內,最後由輸出迭代器輸出。Inserter是一個輸入迭代器的一個函數(迭代器適配器),它的使用方法是:
    
    
    

      congtainer是將要用來存入數據的容器,pos是容器存入數據的開始位置。上例中,是把文件內容存入(copy())到向量v1中。

    現在我們已經對STL的三大基本組件有了一個大概的瞭解,下面讓我們一起來看看STL的其他標準組件。

    函數對象(functor或者funtion objects):#include <function>
      函數對象又稱之爲仿函數。函數對象將函數封裝在一個對象中,使得它可作爲參數傳遞給合適的STL算法,從而使算法的功能得以擴展。可以把它當作函數來使用。用戶也可以定義自己的函數對象。下面讓我們來定義一個自己的函數對象。

    
      這裏的int_max()就是一個函數對象,struct關鍵字也可以用class來代替,只不過struct默認情況下是公有訪問權限,而class定義的是默認私有訪問權限。下面我們來定義一個STL風格的函數對象: 
    
    
      在這裏,我們定義了一個函數對象adder(),這也是一個類,它的基類是unary_function函數對象。unary_function是一個空基類,不包涵任何操作或變量。只是一種格式說明,它有兩個參數,第一個參數是函數對象的使用數據類型,第二個參數是它的返回類型。基於它所定義的函數對象是一元函數對象。(注:用關鍵字struct或者class定義的類型實際上都是"類")
      STL內定義了各種函數對象,否定器、約束器、一元謂詞、二元謂詞都是常用的函數對象。函數對象對於編程來說很重要,因爲他如同對象類型的抽象一樣作用於操作。

    適配器(adapter)
      適配器是用來修改其他組件接口的STL組件,是帶有一個參數的類模板(這個參數是操作的值的數據類型)。STL定義了3種形式的適配器:容器適配器,迭代器適配器,函數適配器。
    • 容器適配器:包括棧(stack)、隊列(queue)、優先(priority_queue)。使用容器適配器,stack就可以被實現爲基本容器類型(vector,dequeue,list)的適配。可以把stack看作是某種特殊的VCtor,deque或者list容器,只是其操作仍然受到stack本身屬性的限制。queue和priority_queue與之類似。容器適配器的接口更爲簡單,只是受限比一般容器要多;
    • 迭代器適配器:修改爲某些基本容器定義的迭代器的接口的一種STL組件。反向迭代器和插入迭代器都屬於迭代器適配器,迭代器適配器擴展了迭代器的功能;
    • 函數適配器:通過轉換或者修改其他函數對象使其功能得到擴展。這一類適配器有否定器(相當於"非"操作)、幫定器、函數指針適配器。

    結束語
      如果你理解了算法、迭代器、容器,那麼你幾乎就瞭解了 STL。關於STL的其他方面,新手都是不常用的,可以暫時以理解STL的組成的編程思想爲主。這篇文章裏用到了19個cpp代碼,每個代碼都在Windows 2000+ Dev-C++ 4.9.9.0和windows 2000+VC環境下通過編譯運行。讀者可以通過copy/paste到任何一款C++編譯器中運行。無論你想不想學STL,先運行一下STL代碼吧。編程快樂,好好學習,天天向上。

    我是新手,歡迎高手批評,歡迎STL學習者交流: Email:[email protected] QQ:370679790

    【附錄】

    附錄一:Dev-C++ 和VC
      在Dev-C++ 4.9.9.0 +windows 2000下,不允許出現,void main(){} 而必須爲 int main() {return 0;} ,或者 int main(){},奇怪的是VC對 int main(){} 的寫法會提出警告,而必須爲 int main() {return 0;}。建議使用標準格式 int main(void) {……return 0;}
      Dev-C++而且不支持頭文件方式,#include <iostream.h>是不對的,而必須爲#include <iostream> using namespace std; VC兩種格式都支持。建議使用#include <iostream> using namespace std;
      如果用純C/C++編程,建議使用比較簡單的C++編譯器,甚至是命令行下的編譯方式。功能強大的IDE甚至會誤導編程者。還要花費不少的時間來學習使用IDE開發環境。Dev比VC要簡單一些,只是不適合做大型工程,而且編譯時間比VC稍慢一點,純C++編程建議使用。他有插入時間和頭文件註釋模板的功能,作者可以方便地插入編程、程序更改時間,方便地填寫程序說明信息。
      在Dev下可以導入VC工程,而且保持原來的VC工程文件,但是Dev對VC的支持還不夠,在編譯的時候會遇到錯誤。
      在編寫dos程序的時候,建議在程序的末尾return之前加上:getchar();cin.get();之類的代碼,以方便看運行結果。

    附錄二:中小型程序段的編輯工具
      在編輯程序過程中並不一定非要在特定的IDE環境中,在有些專業化的文本編輯工具中編輯代碼會更有利於代碼的修改和編輯。這裏介紹幾種更能比較強大的文本編輯器。

    • UltraEdit-32;
    • EditPlus;
    • SourceInsight;
    • Vim;
     
    發表評論
    所有評論
    還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
    相關文章