天天看點

c++ primer 第三章 字元串、向量和數組命名空間的using聲明标準庫類型string标準庫類型vector疊代器數組

命名空間的using聲明

  • ::位域操作符
  • std::cin 意思是就是使用命名空間std的名字cin
  • 按照規定,每個using聲明引入命名空間中的一個成員。
  • 位于頭檔案的代碼一般不應該使用using聲明。可能會産生名字沖突。

标準庫類型string

  • 标準庫類型string表示可變長的字元序列。
  • 初始化:
string s1 預設初始化,s1是一個空串
string s2(s1) s2是s1的副本
string s2 = s1 等價于s2(s1),s2是s1的副本
string s3(“value”) s3是字面值“value”的副本,除了字面值最後的那個空字元外
string s3 = “value” 等價于s3(“value”),s3是字面值"value"的副本
string s4(n, ‘c’) 把s4初始化為由連續n個字元c組成的串
  • 使用“=”實際上執行的是拷貝初始化,如果不适用“=”,則是直接初始化
string s1="hello word!";//拷貝初始化
string s2("hiya");//直接初始化
           

string對象上的操作

os<<s 将s寫到輸出流os當中,傳回os
is >> s 從is中讀取字元串賦給s,字元串以空白分割,傳回is
getline(is, s) 從is中讀取一行賦給s,傳回is
s.empty() s為空傳回true,否則傳回false
s.size() 傳回s中字元的個數
s[n] 傳回s中第n個字元的引用,位置n從0計起
s1+s2 傳回s1和s2連接配接後的結果
s1=s2 用s2的副本代替s1中原來的字元
s1==s2、s1!=s2 如果s1和s2中所含的字元完全一樣,則它們相等;string對象的相等性判斷對字母的大小寫敏感
<, <=, >, >= 利用字元在字典中的順序進行比較,且對字母的大小寫敏感

string加法運算

string s1="hi,",s2="bee";
string s3=s1+s2;//s3="hi,bee"
string s4=s1+"word";//s4="hi,word"
string s5="hi,"+"error";//錯誤,兩個對象都不是string
           
  • 注意當string 對象和字元字面值及字元串字面值混在一條語句中使用時,必須確定每個加法運算符(+)的兩側運算對象至少一個是string。
  • string s6=“hello”+","+s2;//錯誤=>string s6=(“hello”+",")+s2;

處理string對象中的字元

isalnum(ch) 當c是字母或數字時為真
isalpha(ch) 當c是字母時為真
iscntrl(ch) 當c是控制字元時為真
isdigit(ch) 當c是數字時為真
isgraph(ch) 當c不是空格但可以列印時為真
islower(ch) 當c是小寫字母時為真
isprint(ch) 當c是可列印字元時為真
ispunct(ch) 當c是标點符号時為真
isspace(ch) 當c是空白時為真(空格、橫向制表符、縱向制表符、回車符、換行符、進紙符)
isupper (ch) 當c是大寫字母時為真
isxdigit (ch) 當c是十六進制數字時為真
tolower(ch) 當c是大寫字母,輸出對應的小寫字母;否則原樣輸出c
toupper (ch) 當c是小寫字母,輸出對應的大寫字母;否則原樣輸出c
  • 使用範圍for周遊字元串(像python)
string s1("some string");
for(auto c:s1)
	cout<<c<<endl;
           
  • 如果想要改變string對象中字元的值,必須把循環變量定義成引用類型
string s("hello,word!");
//轉化成大寫形式
for(auto &c:s)
	c=toupper(c);
cout<<s<<endl;
           
  • 如果想要對某個或一部分字元串進行修改,可以使用下标運算

标準庫類型vector

  • vector 表示對象的集合,其中所有對象的類型都相同。
  • vector 也被稱為“容器”
  • ** vector 是模闆而不是類型,由vector生成的類型必須包含vector中的元素類型,例如:vector< int> **
  • 定義初始化:
vector< T> v1 v1是一個空vector,它潛在的元素是T類型的,執行預設初始化
vector v2(v1) v2中包含有v1所有元素的副本
vector v2 = v1 等價于v2(v1),v2中包含v1所有元素的副本
vector v3(n, val) v3包含了n個重複的元素,每個元素的值都是val
vector v4(n) v4包含了n個重複地執行了值初始化的對象
vector v5{a, b, c…} v5包含了初始值個數的元素,每個元素被賦予相應的初始值
vector v5={a, b, c…} 等價于v5{a, b, c…}
  • 清單初始化vector對象:1.拷貝初始化。2.提供類内初始值。3. 花括号vector< string> v{“a”, “an”, “the”};
  • 如果使用圓括号(),提供的值使用老構造vector對象的
vector<int >v1(10);//v1有是個元素,每個值都是0
vector<int>v2{10}//v2有一個元素,是10
vector<int>v3(10,1)//v3有10個元素,每個的值都是1

vector<string>v4{"hi"};//清單初始化:v4有一個元素
vector<string>v5("hi");//錯誤
vector<string>v6{10};//v6有10個預設初始值
           
  • vector 的操作:
v.emtpy() 如果v不含有任何元素,傳回真;否則傳回假
v.size() 傳回v中元素的個數
v.push_back(t) 向v的尾端添加一個值為t的元素
v[n] 傳回v中第n個位置上元素的引用
v1 = v2 用v2中的元素拷貝替換v1中的元素
v1 = {a,b,c…} 用清單中元素的拷貝替換v1中的元素
v1 == v2、v1!=v2 v1和v2相等當且僅當它們的元素數量相同且對應位置的元素值都相同
<,<=,>, >= 顧名思義 以字典順序進行比較
  • 範圍for語句内不應該改變其周遊序列的大小。
  • vector對象(以及string對象)的下标運算符,隻能對确知已存在的元素執行下标操作,不能用于添加元素。

疊代器

  • 容器都可支援疊代器
  • 類似于指針,疊代器提供了對對象的間接通路。
  • ** 和指針不一樣的是,擷取疊代器不是使用取位址符,有疊代器的類型同時擁有傳回疊代器的成員**

疊代器使用

  • vector::iterator iter。
  • auto b = v.begin();傳回指向第一個元素的疊代器。
  • auto e = v.end();傳回指向最後一個元素的下一個(哨兵,尾後,one past the end)的疊代器(off the end)。
  • 如果容器為空, begin()和 end()傳回的是同一個疊代器,都是尾後疊代器。
  • 使用解引用符*通路疊代器指向的元素。
  • 養成使用疊代器和!=的習慣(泛型程式設計),for循環不用總考慮大于和小于。
  • 容器:可以包含其他對象;但所有的對象必須類型相同。
  • 疊代器(iterator):每種标準容器都有自己的疊代器。C++傾向于用疊代器而不是下标周遊元素。
  • const_iterator:隻能讀取容器内元素不能改變。
  • 箭頭運算符: 解引用 + 成員通路,it->mem等價于 (*it).mem
  • 注意:但凡是使用了疊代器的循環體,都不要向疊代器所屬的容器添加元素
*iter 傳回疊代器iter所指向的元素的引用
iter->mem 等價于(*iter).mem
++iter 令iter訓示容器中的下一個元素
–iter 令iter訓示容器中的上一個元素
iter1 == iter2 判斷兩個疊代器是否相等

疊代器的運算

iter + n 疊代器加上一個整數值仍得到一個疊代器,疊代器訓示的新位置和原來相比向前移動了若幹個元素。結果疊代器或者訓示容器内的一個元素,或者訓示容器尾元素的下一位置。
iter- n 疊代器減去一個證書仍得到一個疊代器,疊代器訓示的新位置比原來向後移動了若幹個元素。結果疊代器或者指向容器内的一個元素,或者訓示容器尾元素的下一位置。
iter1 += n 疊代器加法的複合指派語句,将iter1加n的結果賦給iter1
iter1 -= n 疊代器減法的複合指派語句,将iter2減n的加過賦給iter1
iter1 - iter2 兩個疊代器相減的結果是它們之間的距離,也就是說,将運算符右側的疊代器向前移動內插補點個元素後得到左側的疊代器。參與運算的兩個疊代器必須指向的是同一個容器中的元素或者尾元素的下一位置。
>、>=、<、<= 疊代器的關系運算符,如果某疊代器指向的容器位置在另一個疊代器所指位置之前,則說前者小于後者,參與運算的兩個疊代器必須指向的是一個同一個容器中的元素或者尾元素的下一個位置

數組

  • 數組是一種複合類型。(相當于低級版的vector,長度固定)
  • 初始化:type name[size];size必須是常量表達式。
  • 數組不能指派給另一個數組。
  • 想要了解數組聲明的含義,最好的方法就是從數組的名字開始按照由内向外的順序閱讀

數組和指針

  • 在大多數表達式中,使用數組的類型的對象其實是一個指向該數組首元素的指針。
string nums[]={"one","two","three"};
string *p=&nums[0];
string *p2=nums//p2=&nums[0]
           
  • 指針也是疊代器
  • 數組的内置下标運算所使用的索引值不是無符号類型,這一點與vector和string不一樣
int ia[]={0,2,4,6};
int *p=&ia[2];
int j=p[-2]//j=ia[0]
           

多元數組

  • c++語言中沒有多元數組,多元數組就是數組的數組
  • 多元數組的初始化: int ia[3 ][4 ] = {{0,1,2,3},{1} ,{1}}
//使用範圍for循環指派和周遊輸出
#include <iostream>
using namespace std;

int main() {
  int num[3][4];
  int n=0;
  for(auto &row:num){
      for(auto &col:row){
          col=n;
          n++;
      }
  }
  for(auto &row:num){
      for (auto col:row)
      std::cout << col << std::endl;
  }
	return 0;
}
           
  • ** 要使用範圍語句處理多元數組,除了最内層的循環外,其他所有循環的控制變量都應該是引用類型。**

參考資料

  • c++ primer 第五版
  • Github :https://github.com/applenob/Cpp_Primer_Practice/blob/master/notes/ch03.md

繼續閱讀