第1章 快速入門
1,介紹main函數(shù)的意義和其基本結(jié)構(gòu),return語句。不同平臺(tái)下編譯與執(zhí)行程序。
2,兩個(gè)類isrteam與otream與它們的實(shí)例對(duì)象cin,cout,cerr,clog。說明了程序中基本的輸入與輸出。“<<”與”>>”作為操作符,左操作符是一個(gè)iostream 對(duì)象,右操作符是一個(gè)變量。返回值仍為一個(gè)iostream對(duì)象,所以輸入或輸出可以這樣 cout<<”a=”<<a<<endl 連著寫。
3,C++中的兩種注釋風(fēng)格以及需要注意的問題。
4,控制結(jié)果:循環(huán)(while與for),選擇(if…else…)。引入一個(gè)計(jì)算兩個(gè)數(shù)之間所有整數(shù)的和例子。
5,C++最重要的特性:類。說明了在類上定義的一些操作,簡(jiǎn)單介紹成員函數(shù),用“.”來調(diào)用成員函數(shù)。
6,書的開頭引入的一個(gè)書店書目的問題,用一個(gè)完整的程序,進(jìn)一步說明了C++程序中的一些基本元素。當(dāng)然Scales_item并沒有具體的實(shí)現(xiàn)代碼。
第2章 變量和基本類型
1,執(zhí)行算術(shù)運(yùn)算時(shí),數(shù)據(jù)類型的選擇:short 一般很少使用,容易產(chǎn)生越界。char類型在一些實(shí)現(xiàn)中有時(shí)作為signed處理,而有時(shí)作為unsigned處理,所以只用char來表示字符是明智之舉。所以在大多數(shù)的時(shí)候使用int就沒有問題,在很多機(jī)器上int用4個(gè)字節(jié)存儲(chǔ),足夠滿足大部分計(jì)算的要求。浮點(diǎn)型的選擇就很簡(jiǎn)單了,使用double類型基本不會(huì)有什么錯(cuò)誤,而且有可能會(huì)比float計(jì)算代價(jià)低。
2,字面值常量。只有內(nèi)置類型存在字面值。寬字符的類型wchar_t,其實(shí)字面值字符常量前面加一個(gè)“L”,如wchar_t c=L'A';多行字符串可以用‘/'進(jìn)行連接,但是/后面不可以有任何空格或制表符,下一行字符串字面值前也不可以有任何空格和制表符。
3,介紹了變量的概念,變量名的命名規(guī)范:1)變量名一般用小寫字母;2)標(biāo)識(shí)符最好有意義;3)多個(gè)詞之間用下劃線或內(nèi)嵌的單詞第一個(gè)字母大寫。另外,標(biāo)識(shí)符不要以兩個(gè)連續(xù)的下劃線或下劃線+大寫字母命名。
4,定義對(duì)象(變量定義)。變量在定義的時(shí)候可以進(jìn)行初始化,可以選擇復(fù)制初始化(不要理解為了賦值),也可以選擇直接初始化。
5,定義與聲明的區(qū)別;注意extern的使用。
6,const限定符的用法。const 定義的變量不能修改,所以必須在定義的時(shí)候進(jìn)行初始化。const變量如果想在多文件中使用,必須在定義的時(shí)候就聲明為外部變量,即用extern。
7,引入與const。
1)非cosnt引用只能綁定到與該引用同類型的對(duì)象。
2)const引用則可以綁定到不同但相關(guān)的類型的對(duì)象或綁定到右值。
8,枚舉類型enum。
9,struct與class在創(chuàng)建類時(shí)的區(qū)別:struct的默認(rèn)訪問級(jí)別為public,而class的則為private。
10,說明了C++語言頭文件的使用與編寫,以及使用定義預(yù)處理器變量來避免頭文件的重復(fù)包含。
第3章 標(biāo)準(zhǔn)庫類型
1,命名空間的using聲明
using std::string
2,標(biāo)準(zhǔn)庫string類型
標(biāo)準(zhǔn)庫string類型。string類型和字符串字面值不是同一種類型,注意幾種string的構(gòu)造函數(shù)。
用cin讀取string類型時(shí),讀取并忽略開頭所有的空白字符,直至再次遇到空白字符,讀取終止。
getline可以讀取輸入流中的一行,但是不包括換行符。
在string對(duì)象比較時(shí),小寫字母都比大寫字母要大,即大寫字母排在前面。
string對(duì)象的下標(biāo)是從0開始到s.size()-1為止。
3,標(biāo)準(zhǔn)庫vector類型
C++程序員習(xí)慣于優(yōu)先使用!=而不是<來編寫循環(huán)判斷條件。for(string::size_type i=0; i != s.size(); i++)
C++編譯器遇到內(nèi)聯(lián)函數(shù)時(shí),都是直接擴(kuò)展相應(yīng)的代碼,而不是實(shí)際的函數(shù)調(diào)用,所以像size這樣的小庫函數(shù)在循環(huán)中調(diào)用它代價(jià)是很小的。
4,迭代器簡(jiǎn)介
每一種容器都定義了begin與end函數(shù),begin返回容器的第一個(gè)元素,end函數(shù)返回vector的末端元素的下一個(gè),通常稱為超出末端迭代器,表明它指向了一個(gè)不存在的元素。如果vector為空,begin返回的迭代器與end返回的迭代器相同。end返回的迭代器實(shí)際上是一個(gè)“哨兵”。
注意區(qū)別:
vector<int>::const_iterator // an iterator that cannot write elements
const vector<int>::iterator // an iterator whose value cannot change
5,bitset類型
幾種bitset的構(gòu)造函數(shù):
bitset<n> b;
bitset<n> b(u); // u是一個(gè)usigned long弄的數(shù)字,將換算成二進(jìn)制數(shù)
bitset<n> b(s); // b 是string對(duì)象s中含有位串的副本
bitset<n> b(s,pos,n); // b是s中從位置pos開始的n個(gè)位的副本
第4章 數(shù)組與指針
1,數(shù)組
沒有所有元素都是引用的數(shù)組,數(shù)組中定義的類型可以是內(nèi)置數(shù)據(jù)類型或類類型或任意的復(fù)合類型(引用除外)。
數(shù)組的維數(shù)只能用在編譯階段就能知道的常量值。const int arSize=num; int ar[arSize];這樣是不行的,因?yàn)閚um變量在運(yùn)行階段才會(huì)計(jì)算出。
如果沒有給數(shù)組顯式地初始化,則會(huì)像普通變量一樣進(jìn)行初始化:1)在函數(shù)體外定義,則初始化為0;2)在函數(shù)體內(nèi)定義,則其元素?zé)o初始化;3)不管數(shù)組在哪,如果其元素為類類型,則自動(dòng)調(diào)用該類的默認(rèn)構(gòu)造函數(shù)。如果該類沒有默認(rèn)的構(gòu)造函數(shù),則必須為數(shù)組的元素提供顯式的初始化。
vector對(duì)象不能用同類型的數(shù)直接進(jìn)行初始化。假設(shè)有如下數(shù)組:const int ar_size=5; ar[ar_size]={0,1,2,3,4}>
vector<int> ivec(ar); // error
vector<int> ivec(ar,ar+ar_size); // ok
2,指針的引入
不允許把int型的0賦給指針,但是可以把const修飾的0可以賦于指針
cosnt int c_ival=0; int *p=c_ival;
C++提供了一種特殊類型的指針void*,void*只支持幾種有限的操作:1)與另一個(gè)指針進(jìn)行比較;2)向函數(shù)傳遞void*指針或從函數(shù)返回void*指針;給另一個(gè)void*指針賦值。不允許使用void*指針操縱它所指向的對(duì)象。
ptrdiff_t是標(biāo)準(zhǔn)庫中定義的用于保存指向同一類型的指針之間減法的結(jié)果的類型。
const int* ptr; // ptr可以指向他變量,但是在沒有改變ptr之前,不能用ptr是改變它所指向的變量的值。
int* const ptr; // ptr不能指向其他變量,但是可以改變ptr所指向的變量的值。
注意:
typedef string *pstring;
const pstring cstr;
上面的cstr是一種const指針,指針指向字符串類型的變量。pstring const cstr是一樣的。
3,C風(fēng)格字符串
每一個(gè)程序在執(zhí)行時(shí)都占用一塊可用的內(nèi)存空間,用于存放動(dòng)態(tài)分配的對(duì)象,此內(nèi)存空間稱為程序的自由存儲(chǔ)區(qū)或堆。
動(dòng)態(tài)分配的數(shù)組不能像數(shù)組一樣使用初始化列表,只能初始化為元素類型的默認(rèn)值。int* ar=new int[10]();后面的空括號(hào)可以讓數(shù)組元素都初始化為0。
用delete釋放自由存儲(chǔ)空間時(shí),如果釋放的是數(shù)組,則別忘了[]。delete [] ar;
注意string對(duì)象的成員函數(shù)c_str()可以返回字符串的首指針。但是應(yīng)該加const。 const char* str=s.c_str();
int* ip[4]:一個(gè)指向int的指針數(shù)組。
int (*ip)[4]:一個(gè)指針4元素?cái)?shù)組的指針。
第5章 表達(dá)式
1,區(qū)別i++與++i
后置操作符需要先保存原來的值,再將i+1,然后返回原來的值;而前置操作符,只需要在原來值上加1,然后返回。所以++i比i++效率更高,當(dāng)然如果i為int類型時(shí),編譯器會(huì)對(duì)i++進(jìn)行優(yōu)化,但如果是其他類類型或指針時(shí)就不會(huì)了。
2,注意解除引用操作符與++操作符的優(yōu)先級(jí),在實(shí)際代碼中為了簡(jiǎn)潔經(jīng)常將*(i++)寫為*i++。因?yàn)?+的優(yōu)先級(jí)高于解除引用操作符。
3,在使用條件操作符時(shí),盡量避免寫出深度嵌套的條件操作符。另外條件操作符的優(yōu)先級(jí)非常低,在表示式中使用時(shí)要注意加括號(hào),比如:cout<<(i<j?i:j);
4,關(guān)于sizeof運(yùn)算符。sizeof的運(yùn)算結(jié)果是編譯時(shí)的常量,注意下面的代碼的值:
5,在復(fù)合表達(dá)式求值時(shí),要特別注意運(yùn)算符的優(yōu)先級(jí)與結(jié)合性。特別地,!=與==的優(yōu)先級(jí)小于<=,>=等關(guān)系運(yùn)算符。
6,在使用new進(jìn)行動(dòng)態(tài)內(nèi)存分配時(shí),有以下幾點(diǎn)值得注意:
1)動(dòng)態(tài)創(chuàng)建的對(duì)象可以用括號(hào)進(jìn)行初始化,比如:
2)可以delete刪除0指針,而且delete刪除的是分配到的內(nèi)存區(qū)域,并沒有刪除指針變量p,p依然指向原來的地址,只是原來的內(nèi)存已經(jīng)不存在了。這時(shí)p稱為懸垂指針,應(yīng)該將p設(shè)為0.
3)避免對(duì)同一內(nèi)存空間使用兩次delete。、
第6章 語句
1,在使用塊狀語句時(shí)注意,在塊狀語句內(nèi)定義的變量作用域只在塊狀區(qū)域內(nèi)。特別地,在控制語句,比如if或for語句中,初始化或定義的變量,都只有塊區(qū)域的作用域。
2,switch語句的使用。case標(biāo)號(hào)必須是整形常量表達(dá)式,不允許在switch語句內(nèi)定義變量如果在它下面還有case或default語句,因?yàn)檫@樣會(huì)在某些情況下,在沒有執(zhí)行變量定義的case分支的情況下,執(zhí)行變量定義下面case分支。除非把變量定義在代碼塊內(nèi)。
3,在for循環(huán)中,如果有continue語句,會(huì)跳下continue后面的語句,但是不會(huì)跳變for語句中的計(jì)數(shù)器變化語句。
4,可以使用預(yù)處理器進(jìn)行調(diào)試。
在編譯時(shí)加上參數(shù)就可以決定是否打印那些調(diào)試信息。
第7章 函數(shù)
1,函數(shù)可以看作是程序員自己定義的操作符,與操作符一樣函數(shù)也可以進(jìn)行重載。
2,下面是用輾轉(zhuǎn)相除法求最大公約數(shù)的函數(shù),說明了函數(shù)定義的基本結(jié)構(gòu)。
5,沒有返回值的函數(shù)(返回值為void)里一般是不能有return語句,但是可以用return返回一個(gè)返回值為void的函數(shù)表達(dá)式。
6,函數(shù)允許提供默認(rèn)的實(shí)參,在調(diào)用時(shí),這一項(xiàng)參數(shù)可以省略,而讓程序使用默認(rèn)值。一般應(yīng)在函數(shù)聲明中指定默認(rèn)實(shí)參,并將該聲明放在合適的頭文件中。
7,在函數(shù)體內(nèi)定義的變量具有塊區(qū)域的作用域,可分為兩種一種為自動(dòng)對(duì)象,如:形參。這類對(duì)象在每次函數(shù)調(diào)用時(shí)都會(huì)創(chuàng)建,在函數(shù)執(zhí)行完時(shí)銷毀。還有一種對(duì)象為靜態(tài)局部對(duì)象,這種對(duì)象只有在程序結(jié)束時(shí)才會(huì)撤銷。不然一直在內(nèi)存中保留。
8,對(duì)于那種經(jīng)常需要調(diào)用且短小的函數(shù),可以設(shè)置為內(nèi)聯(lián)函數(shù),這種函數(shù)在編譯時(shí),編譯器會(huì)在函數(shù)調(diào)用處對(duì)函數(shù)進(jìn)行展開,進(jìn)行代碼替換。這樣就避免了函數(shù)調(diào)用中的開銷。定義內(nèi)聯(lián)函數(shù)是在函數(shù)定義前加inline。一般需要將inline函數(shù)放在頭文件中。
9,在類的成員函數(shù)中有一類函數(shù)在后面加上const限定符,用來說明為常量成員函數(shù),在對(duì)象使用時(shí),只能讀取不能改變對(duì)象的數(shù)據(jù)成員。
10,不要把this指針寫在了成員函數(shù)的形參表中。
11,在定義類時(shí),如果沒有定義默認(rèn)的構(gòu)造函數(shù),那么編譯器將為類創(chuàng)建一個(gè)合成的默認(rèn)構(gòu)造函數(shù)。這個(gè)函數(shù)將類的成員變量按對(duì)應(yīng)變量類型初始化方法進(jìn)行初始化:類類型的將調(diào)用該類的默認(rèn)構(gòu)造函數(shù),內(nèi)置類型則依賴于所處的環(huán)境是全局或靜態(tài)局部對(duì)象還是局部對(duì)象。合成的默認(rèn)構(gòu)造函數(shù)只適用僅包含類類型成員的類。
12,函數(shù)不能僅僅基于不同的返回類型而實(shí)現(xiàn)重載。
13,const在函數(shù)重載中值得注意的問題:
void fun(int& num);
void fun(const int& num); // 可以重載
void fun(int* num);
void fun(const int* num); // 可以重載
14,局部聲明的函數(shù)將會(huì)屏蔽將全局定義的重載函數(shù)。
15,指向函數(shù)的指針
函數(shù)指針指向函數(shù)而并非指向?qū)ο蟆ool (*pf) (int,int*); 其中pf是一個(gè)函數(shù)指針,該指針的類型為“指向返回bool類型并帶int與int*形參的函數(shù)的指針”。
1)可以用typedef來給指定函數(shù)的指針簡(jiǎn)單定義:
上面代碼中定義了一種指針函數(shù)的類型,并用typedef提供了別名。f1與f2都是這種類型的指針。
2)給指向函數(shù)的指針初始化與賦值
對(duì)于定義好的函數(shù),其函數(shù)名沒有被調(diào)用時(shí),都被解釋為指向函數(shù)的指針,可以給同類型的指針賦值。
給指向函數(shù)的指針賦值為0,表明不指向任何函數(shù)。
在進(jìn)行指向函數(shù)的指針賦值時(shí),不存在任何類型的轉(zhuǎn)換。
3)通過指針調(diào)用函數(shù)
可以不用解除引用符號(hào),如:f1(1,2)、(*f1)(1,2)。
4)指向函數(shù)的指針可以作為函數(shù)的形參:
上面兩個(gè)函數(shù)的聲明中上式第3個(gè)參數(shù)為一個(gè)指向函數(shù)指針類型,下式的第3個(gè)參數(shù)為一個(gè)函數(shù)類型,它會(huì)自動(dòng)轉(zhuǎn)換為一個(gè)指針類型。
5)函數(shù)類型可以作為函數(shù)的形參,但是不能作為函數(shù)的返回類型。
6)在指向函數(shù)的指針指向重載函數(shù)時(shí),類型必須一致。
第8章 標(biāo)準(zhǔn)IO庫
1,標(biāo)準(zhǔn)庫類型不允許做復(fù)制和賦值操作。因?yàn)橹挥兄С謴?fù)制的元素類型可以存儲(chǔ)在vector中,所以流對(duì)象不能存儲(chǔ)在vector或容器中,另外函數(shù)的形參與返回類型也不能為流類型,如果需要?jiǎng)t必須傳遞或返回指向該對(duì)象的引用或指針。一般來說,如果要傳遞IO對(duì)象以便對(duì)它進(jìn)行讀 寫,可以用非const引用方式傳遞這個(gè)流對(duì)象。對(duì)IO對(duì)象的讀寫會(huì)改變它的狀態(tài),所以必須是非const的。
2,每個(gè)IO對(duì)象都管理著一個(gè)緩沖區(qū),有以下幾種方式可以刷新緩沖區(qū)(將緩沖區(qū)內(nèi)容寫到設(shè)備上)。
1)輸出緩沖區(qū)的刷新:flush刷新流但不添加任何字符;ends這個(gè)操作符在緩沖區(qū)中插入空字符NULL,然后刷新它。endl換行并刷新。
2)unitbuf操作符:cout<<unitbuf<<”first”<<”second”<<nounitbuf;nounitbuf操作符將流恢復(fù)為正常的,由系統(tǒng)管理的緩沖區(qū)刷新方式。
3)程序崩潰時(shí),不會(huì)刷新緩沖區(qū)。這一點(diǎn)在調(diào)試已崩潰的程序時(shí)需要特別注意。
4)可以用tie函數(shù)將istream與ostream捆綁在一起,當(dāng)使用任何IO操作時(shí)都會(huì)刷會(huì)實(shí)參所關(guān)聯(lián)的緩沖區(qū)。
3,注意清除文件流的狀態(tài),下面程序從一個(gè)vector中讀文件的名字,并對(duì)每個(gè)文件內(nèi)的內(nèi)容進(jìn)行處理,如果開始的流是定義在循環(huán)外的,則需要在循環(huán)結(jié)束時(shí)清除文件流的狀態(tài)。
上面程序中,每一次讀文件,都會(huì)以遇到文件結(jié)束符或其他錯(cuò)誤終止,這個(gè)點(diǎn)上input處于錯(cuò)誤狀態(tài)。如果關(guān)閉該流前沒有調(diào)用clear消除流的狀態(tài),接著在input上做的任何輸入運(yùn)算都會(huì)失敗。
4,stringstream由iostream派生而來,提供讀寫string的功能??梢詫⒁粋€(gè)字符串轉(zhuǎn)化為流用于輸入或輸出。這個(gè)類主要有兩種常見的用處:
1)將一定格式的變量值組成一個(gè)字符串。 假設(shè)在一個(gè)循環(huán)內(nèi),我們要保存中間數(shù)據(jù)到硬盤,那么需要文件名,且需要將循環(huán)的索引寫入文件名,避免文件名的重復(fù)。
2)將一串有格式的字符串,按格式解析為一些基本類型數(shù)據(jù)。比如,需要將一行日志文件內(nèi)容中的字符串與整數(shù)分別提取出來:
新聞熱點(diǎn)
疑難解答