天天看點

C++ Primer 5th學習筆記2 字元串、向量和數組

一、字元串、向量、數組

1 标準庫類型string

  标準庫類型string表示可變長的字元序列,使用時必須先包含string頭檔案

#include <string>

,檔案中還需要聲明

using std::string;

1.1 定義和初始化string對象

eg

聲明形式 描述

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”)

string s4(n, 'c')

把s4初始化為由連續n個字元c組成的串

拷貝初始化與直接初始化的差別:

string s5 = "hiya";		//拷貝初始化
string s6("hiya");		//直接初始化
string s7(10, 'c');		//直接初始化
           

Tips:帶等号的為拷貝初始化,不帶等号的即直接初始化

1.2 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的每個字元串與較長的string對應位置上的字元相同,則較短的string小于較長的string對象
  • 兩個string在某些對應位置上不一緻,則比較結果是string中第一對相異字元的比較結果。
string str1 = "Hello";
string str2 = "Hello World";
string str3 = "Hiya";
           

如上例:str1小于str2,str3大于str2,str3大于str1。

string相加規則:必須確定每個加法運算符(+)的兩側的運算對象至少有一個是string對象。

1.3 處理string對象中的字元

以下函數都包含在

cctype

頭檔案中

函數名 描述

tolower(c)

大寫轉小寫,小寫還是傳回小寫

toupper(c)

小寫轉大寫,大寫還是傳回大寫

isalnum(c)

c是字母or數字為真

isalpha(c)

c是字母為真

isdigit(c)

c是數字為真

isspace(c)

c是空白(空格、橫縱制表符、回車、換行、進紙符)為真

isxdigit(c)

c是十六進制數字為真

2 标準庫類型vector

标準庫類型vector表示對象的集合,vector也稱作容器。使用時必須先包含string頭檔案

#include <vector>

,檔案中還需要聲明

using std::vector;

2.1 定義和初始化vector對象

eg

聲明形式 描述

vector<T> v1

v1是一個類型為T的空vector。

vector<T> v2(v1)

v2包含v1所有元素的副本

vector<T> v2 = v1

等價于v2(v1),v2是v1的副本

vector<T> v3(n, val)

v3包含了n個重複的元素,每個元素的值都是val

vector<T> v4(n)

v4包含了n個重複地執行了值初始化的對象

vector<T> v5{a,b,c...}

v5包含了初始值個數的元素

vector<T> v5 = {a,b,c...}

等價于v5{a,b,c…}

2.2 vector對象上的操作

操作 描述

v.empty()

若v中不含任何元素,傳回真,否則傳回假

v.size()

傳回v中元素的個數

v[n]

傳回v中第n個位置上元素的引用

v.push_back()

傳回

v1

v2

連接配接後的結果

v1 = v2

v2

中的元素的拷貝替換

v1

中的元素

v1 = {a,b,c...}

用清單中的元素拷貝替換v1中的元素

v1 == v2

v1

v2

相等當且僅當他們的元素數量相同且

v1 != v2

對應位置的元素值都相同

<,<=,>,>=

以字典順序進行比較

Tip:vector對象(以及string對象)的下标運算符隻能用于通路已存在的元素

2.3 疊代器運算符

  疊代器:所有的标準庫容器都可以使用疊代器,都擁有begin和end成員,其中begin成員負責傳回指向第一個元素的疊代器;end成員負責傳回容器“尾元素的下一個位置”;若容器為空,則begin和end傳回的是同一個疊代器

标準容器疊代器的運算符

操作 描述

*iter

傳回疊代器iter所指元素的引用

iter->mem

解引用iter并擷取該元素的名為mem的成員,等價于(*iter).mem

++iter

令iter訓示容器中的下一個元素

--iter

令iter訓示容器中的上一個元素

iter1 == iter2

判斷兩個疊代器是否相等

iter1 != iter2

(主要針對同一個容器)

Tip:凡是使用了疊代器的循環體,都不要向疊代器所屬的容器添加元素

  • vector和string疊代器支援的運算
運算 描述

iter + n

疊代器向後移動n個位置

iter - n

疊代器向前移動n個位置

iter += n

疊代器加法的複合指派語句

iter -= n

疊代器減法的複合指派語句

iter1 - iter2

兩個疊代器之間的距離

>、>=、<、<=

疊代器之間的關系運算

使用疊代器的經典例子------二分搜尋

//text為一有序的對象
//sought表示在text中搜尋的元素
auto beg = text.begin(), end = text.end();
auto mid = text.begin() + (end - beg)/2;		//初始狀态下的中間點
//當還有元素未檢查并且還未找到sought時執行循環
while(mid != end && *mid != sought)
{
    if(sought < *mid)		//若sought在前半部分,則此時的mid為下一次的end
    {
        end = mid;
    }
    else					//sought在後半部分,則此時的mid+1為下一次的beg
    {
        beg = mid + 1;
    }
    mid = beg + (end - beg)/2;	//新的中間點
}
           

Tip:此處的

mid = beg + (end - beg)/2

不能簡寫成

mid = (beg + end)/2

,因為疊代器不支援此運算,而且

(end - beg)/2

得到的是距離,beg + 距離符合

iter + n

的形式

3 數組

3.1 定義和初始化數組對象

  • 字元數組的特殊性

    字元數組有一種額外的初始化方式,==此處一定要注意字元串字面值的結尾處還有一個空字元,==示例如下:

char a1[] = {'C','+','+'};		//清單初始化,沒有空字元
char a2[] = {'C','+','+','\0'};		//清單初始化,含有顯示的空字元
char a3[] = "C++";		//自動添加表示字元串結束的空字元
const char a4[3] = "C++";		//錯誤:沒有空間可存放空字元
           
  • 不允許拷貝和指派

    不能将數組的内容拷貝給其他數組作為其初始值,也不能用數組為其他數組指派

  • 數組的含義

    Tip:了解數組的含義,從數組的名字開始按照由内向外的順序閱讀

  • 标準庫函數begin和end

      begin和end均定義在iterator頭檔案中,注意尾後指針不能執行解引用和遞增操作

    eg:

int a[] = {1,2,3,4,5,6,7,8,9,0};		//以拷貝的形式定義數組a
int *beg = begin(a);		//指向a首元素的指針
int *last = end(a);			//指向a尾元素的下一個位置的指針
           
  • 指針運算
int a[] = {1,2,3,4,5,6,7,8,9,0};		//以拷貝的形式定義數組a
int *beg = begin(a);		//指向a首元素的指針
int *last = end(a);			//指向a尾元素的下一個位置的指針
auto n = end(a) - begin(a);		//n的值為10,即a中元素的數量
           

兩個指針相減的結果的類型是一種名為ptrdiff_t的标準庫類型

int a[] = {0,1,2,3,4,5,6,7,8,9};		//以拷貝的形式定義數組a
int last = *(a + 4);			//定義last初始化的值等于a[4]
last = *a + 4;		//指派last = a[0] + 4 = 4
int k = a[-2];		//a[-2]是a[0]的值
           

4 C标準庫String函數

  下表中的函數均定義在cstring頭檔案中,cstring是C中的頭檔案string.h的cpp版本。

函數名稱 描述

strlen(p)

傳回p的長度,不包括空字元

strcmp(p1,p2)

比較

p1

p2

的相等性,若相等傳回0,若大于,傳回一個正值;若小于,傳回一個負值

strcat(p1,p2)

p2

附加到

p1

之後,傳回

p1

strcpy(p1,p2)

p2

拷貝給

p1

,傳回

p1