C++知识总结(2)--字符串和数组
標準庫類型string
標準庫類型string表示可變長的字符序列。
使用string類型需要先添加頭文件#include<string>,并且由于其定義在命名空間std中,所以還要添加using std::string;。
string初始化的方式有下面幾種方式:
其中使用等號的初始化執行的是拷貝初始化,是將等號右側的初始值拷貝到新創建的對象中;而不使用等號,執行的就是直接初始化。
下面給出了string的大多數操作:
讀取操作中,string對象會自動忽略開頭的空白(即空格符、換行符、制表符等)并從第一個真正的字符開始讀起,直到遇到下一處空白為止。
而如果需要讀取一行,則可以使用函數getline,它的參數是一個輸入流和string對象,從給定的輸入流中讀取內容,直到遇到換行符為止,注意它會將換行符也讀取進來,但是并不保存到string對象中。
size()函數會返回string對象的長度,其返回值的類型是string::size_type,它是一個無符號類型的值,而且能夠存放任何string對象的大小。
當把string對象和字符字面值及字符串字面值混在一條語句中使用時,必須確保每個加法運算符兩側運算對象至少有一個是string。此外,字符串字面值和string是不同的類型。
在cctype頭文件中定義了一組標準庫函數用于改變某個字符的特性,具體如下所示:
基于范圍的for語句形式如下所示:
string str("string"); for(auto c : str)cout << c << endl;上面是利用這個for語句來輸出字符串str中的每個字符,而如果要改變字符串中的內容,則需要將循環變量定義成引用類型,如下所示:
string str("string"); for(auto &c : str)c = toupper(c); cout << str <<endl;上述代碼就是將str中的字符串都變成大寫字母,其中關鍵之處就是auto &c中使用引用類型。
標準庫類型vector
標準庫類型vector表示對象的集合,其中所有對象的類型都相同。
要使用vector,都必須做如下using聲明和添加頭文件:
#include<vector> using std::vector;C++語言既有類模板,也有函數模板,而vector是一個類模板。
模板本身不是類或函數,可以將模板看作是編譯器生成類或函數編寫的一份說明。編譯器根據模板創建類或函數的過程稱為實例化,當使用模板時,需要指出編譯器應把類或函數實例化成何種類型。
對于類模板,需要提供一些額外信息來指定模板到底實例化成什么類,提供的信息總是這樣:即在模板名字后面跟一對尖括號,在括號內放上信息。例如,vector<int> ivec;則是定義了一個保存int類型的對象ivec。
vector可以容納大多數類型的對象作為其元素,但是因為引用不是對象,所以不存在包含引用的vector。
初始化vector的方法如下:
一般初始化的時候,使用的是圓括號,提供的值是用來構建vector,如上述例子的v3,v4;而如果使用的是花括號,則一般是表示我們想使用列表初始化vector對象,但如果提供的值不能進行列表初始化,如vector<string> v{10};這表示v有10個默認初始化的元素,或者如vector<string> v{10, "hi"};這表示v有10個值為”hi”的元素。
注意,如果循環體內部包含有向vector對象添加元素的語句,則不能使用范圍for語句,范圍for語句體內不應改變其所遍歷序列的大小。
迭代器介紹
迭代器也可以實現下標運算符的功能,即能夠訪問string對象的字符或者vector對象的元素。
迭代器提供 了對對象的間接訪問,跟指針不一樣的是,獲取迭代器不是使用取地址符,有迭代器的類型同時擁有返回迭代器的成員。這些類型都擁有名為begin和end的成員,其中begin成員負責返回指向第一個元素的迭代器,而end成員負責返回指向容器或string對象“尾元素的下一位置”的迭代器,即其指示的是容器的一個本不存在的尾后元素,因此它也常被稱為尾后迭代器。如果容器為空,則begin和end返回的是同一個迭代器。
迭代器的運算符如下:
實際上,跟不知道string和vector的size_type成員到底是什么類型一樣,一般來說我們也不知,或者也無需知道迭代器的精確類型。實際上,擁有迭代器的標準庫類型使用iterator和const_iterator來表示迭代器的類型,如:
vector<int>::iterator it; // it能讀寫vector<int>的元素 string::iterator it2; // it2能讀寫string對象中的字符vector<int>::const_iterator it3; // it3只能讀元素,不能寫元素 string::const_iterator it4; // it4只能讀字符,不能寫字符const_iterator和常量指針差不多,能讀取但不能修改它所指的元素值,如果vector或string對象是常量,則只能使用const_iterator;相反,iterator的對象可讀可寫,只有vector或string對象不是常量,則這兩者都可以使用。
解引用迭代器可獲得迭代器所指的對象,如果該對象的類型恰好是類,就有可能希望進一步訪問它的成員。如(*it).empty(),it是一個vector對象的迭代器,這句代碼就是調用vector的empty函數,但是注意這里必須有圓括號,否則點運算符是指向it,而不是it解引用的結果??梢允褂眉^運算符->實現同樣的效果,即it->empty(),它就是等價于(*it).empty()。
注意,但凡是使用了迭代器的循環體,都不要向迭代器所屬的容器添加元素。
數組
數組是一種復合類型,其聲明形如a[d],a是數組名,而d是數組的維度,維度必須大于0,且必須是一個常量表達式,即編譯的時候維度應該是已知的。
和內置類型變量一樣,在函數內部定義了某種內置類型的數組,那么默認初始化會令數組含有未定義的值。
不能將數組的內容拷貝給其他數組作為初始值,也不能用數組為其他數組賦值,即下列行為是錯誤的:
int a[] = {0,1,2}; // 含有3個整數的數組 int a2[] = a; // 錯誤:不允許使用一個數組初始化另一個數組 a2 = a; // 錯誤:不能把一個數組直接賦值給另一個數組在C++中,指針和數組由非常緊密的聯系,在使用數組的時候,編譯器一般會把它轉換成指針。
通常情況下,使用取地址符來獲取執行某個對象的指針,取地址符可以用于任何對象,數組的元素也是對象,因此對數組的元素使用取地址符就能得到指向該元素的指針。
此外,數組還有一個特性:在很多用到數組名字的地方,編譯器都會自動地將其替換為一個指向數組首元素的指針。如string *p2 = nums;等價于p2 = &nums[0];。所以大多數表達式中,使用數組類型的對象其實是使用一個指向該數組首元素的指針。
當使用數組作為一個auto變量的初始值時,推斷得到的類型是指針而非數組。
C++11新標準引入了兩個名為begin和end的函數,這兩個函數與容器中兩個同名成員功能類型,不過數組不是類類型,因此這兩個函數不是成員函數,正確的使用形式是將數組作為它們的參數。
指向數組元素的指針可以執行一些如解引用、遞增、比較、與整數相加、兩個指針相減等的迭代器運算。
其中,兩個指針相減的結果是它們之間的距離,但兩個指針必須指向同一個數組中的元素;而對于比較運算,也要求兩個指針指向同一個數組的元素或者該數組的尾元素的下一位置,否則就不能比較;
可以使用數組來初始化vector對象,只需指明要拷貝區域的首元素地址和尾后地址,如:
int int_arr[] = {0, 1, 2, 3, 4, 5}; // ivec有6個元素,分別是int_arr中對應元素的副本 vector<int> ivec(begin(int_arr), end(int_arr)); // 也可以是數組的一部分,下面是拷貝三個元素:int_arr[1], int_arr[2], int_arr[3] vector<int> subVec(int_arr+1, int_arr+4);多維數組其實就是數組的數組。
使用范圍for語句處理多維數組,除了最內層的循環外,其他所有循環的控制變量都應該是引用類型。
總結
以上是生活随笔為你收集整理的C++知识总结(2)--字符串和数组的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 算法基础:常用的排序算法知识笔记
- 下一篇: 函数模板(参考《C++ Template