小人物學個大習(121-130)
C++ primer
關鍵概念:范型編程,在for循環(huán)中使用!=而非<,更多的使用迭代器。
迭代器類型
就像不知道string和vector的size type成員(參見3.2.2節(jié),第79頁)到底是什么類型一樣,一般來說我們也不知道(其實是無須知道)迭代器的精確類型。而實際上, 那些擁有迭代器的標準庫類型使用iterator和const iterator來表示迭代器的類型:
vector::iterator it;//it能讀寫vector的元素
string::iterator it2; //it2能讀寫string對象中的字符
vector::const iterator it3;//it3只能讀元素,不能寫元素
string::const iterator it4; //it4只能讀字符,不能寫字符
const iterator和常量指針(參見242節(jié),第56頁)差不多,能讀取但不能修改它所指的元素值。相反,iterator的對象可讀可寫。如果vector對象或string對象是一個常量,只能使用const iterator;如果vector對象或string對象不是常量, 那么既能使用iterator也能使用const iterator。
術語:迭代器和迭代器類型
迭代器這個名詞有三種不同的含義:可能是迭代器概念本身,也可能是指容器定義的迭代器類型,還可能是指某個迭代器對象。
重點是理解存在一組概念上相關的類型,我們認定某個類型是迭代器當且僅當它支持一套操作,這套操作使得我們能訪問容器的元素或者從某個元素移動到另外一個元素。 每個容器類定義了一個名為iterator的類型,該類型支持迭代器概念所規(guī)定的一套操作。結合解引用和成員訪問操作(*it).empty
for(auto it = text.cbegin();it != text.cend()&& !it->empty();it++)
{
cout<<*it<<endl;
}迭代器運算,使用迭代器實現二分查找
下面的程序使用迭代器完成了二分搜索:
// text必須是有序的
//beg和 end表示我們搜索的范圍
auto beg = text.begin(), end = text.end();
auto mid = text.begin() + (end - beg)/2;//初始狀態(tài)下的中間點
//當還有元素尚未檢查并且我們還沒有找到sought時執(zhí)行循環(huán)
while (mid != end && *mid != sought)
{
if (sought < *mid)//我們要找的元素在前半部分嗎?
end = mid; //如果是,調整搜索范圍使得忽略掉后半部分
else //我們要找的元素在后半部分
beg = mid + 1;//在mid之后尋找
mid = beg + (end - beg)/2; //新的中間點
}如果不清楚元素的確切個數,使用vector
定義和初始化內置數組
顯式初始化數組
字符數組的特殊性
復雜數組,指向數組的指針,和存放指針的數組和數組的引用通過下標,訪問數組元素
指針和數組,在很多用到數組名字的地方,編譯器都會自動地將其替換為一個指向數組首元素的指針;
指針也是迭代器,可以使用begin和end,begin返回指向ia首元素的指針,end返回指向ia尾元素的指針
int ia[]=(0,1,2,3,4,5,6,7,8,9);//ia是一個含有10個整數的數組
int *beg = begin(ia); int *last = end(ia);
int *pbeg = begin(arr), *pend = end(arr);
while (pbeg != pend && *pbeg >= 0)
++pbeg;
指向數組的指針也具有指針運算的相關性質。C風格字符串,c風格字符串是一種約定俗成的寫法,按習慣書寫字符串存放在字符數組中,并以空字符結束。
c標準庫string函數
strlen(p);返回p的長度,這里p是一個字符數組指針
strcmp(p1,p2);比較p1和p2的相等性,如果p1>p2返回正
strcat(p1,p2);將p2附加到p1之后,有泄漏風險
strcpy(p1,p2);將p2拷貝給p1,有泄漏風險
應當盡量減少c風格字符串的使用混用string對象和c風格字符串
string s(“Hello World”)
Char?str = s;錯誤
const char?str = s.c_str();//正確,但有風險,s變化時,str可能會失效
使用數組初始化vector
int int arr[] = {0,1, 2, 3, 4, 5};
vector ivec(begin(int arr), end(int arr));
用于初始化vector對象的值也可能僅是數組的一部分:
vector subVec(int arr + l, int arr + 4);
莫要爭雄,莫要妄言,莫要怕錯,安心做事。
2023年08月04日