C++ Primer 第一部分基本語言
第1章 快速入門
1,介紹main函數(shù)的意義和其基本結(jié)構(gòu),return語句。不同平臺下編譯與執(zhí)行程序。
2,兩個(gè)類isrteam與otream與它們的實(shí)例對象cin,cout,cerr,clog。說明了程序中基本的輸入與輸出。“<<”與”>>”作為操作符,左操作符是一個(gè)iostream 對象,右操作符是一個(gè)變量。返回值仍為一個(gè)iostream對象,所以輸入或輸出可以這樣 cout<<”a=”<<a<<endl 連著寫。
3,C++中的兩種注釋風(fēng)格以及需要注意的問題。
4,控制結(jié)果:循環(huán)(while與for),選擇(if…else…)。引入一個(gè)計(jì)算兩個(gè)數(shù)之間所有整數(shù)的和例子。
5,C++最重要的特性:類。說明了在類上定義的一些操作,簡單介紹成員函數(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)型的選擇就很簡單了,使用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)識符最好有意義;3)多個(gè)詞之間用下劃線或內(nèi)嵌的單詞第一個(gè)字母大寫。另外,標(biāo)識符不要以兩個(gè)連續(xù)的下劃線或下劃線+大寫字母命名。
4,定義對象(變量定義)。變量在定義的時(shí)候可以進(jìn)行初始化,可以選擇復(fù)制初始化(不要理解為了賦值),也可以選擇直接初始化。
int ival(1024); // direct-initialization
int ival = 1024; // copy-intialization
5,定義與聲明的區(qū)別;注意extern的使用。
6,const限定符的用法。const 定義的變量不能修改,所以必須在定義的時(shí)候進(jìn)行初始化。const變量如果想在多文件中使用,必須在定義的時(shí)候就聲明為外部變量,即用extern。
7,引入與const。
1)非cosnt引用只能綁定到與該引用同類型的對象。
2)const引用則可以綁定到不同但相關(guān)的類型的對象或綁定到右值。
8,枚舉類型enum。
9,struct與class在創(chuàng)建類時(shí)的區(qū)別:struct的默認(rèn)訪問級別為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對象比較時(shí),小寫字母都比大寫字母要大,即大寫字母排在前面。
string對象的下標(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,迭代器簡介
每一種容器都定義了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對象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對象不能用同類型的數(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*指針操縱它所指向的對象。
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)分配的對象,此內(nèi)存空間稱為程序的自由存儲(chǔ)區(qū)或堆。
動(dòng)態(tài)分配的數(shù)組不能像數(shù)組一樣使用初始化列表,只能初始化為元素類型的默認(rèn)值。int* ar=new int[10]();后面的空括號可以讓數(shù)組元素都初始化為0。
用delete釋放自由存儲(chǔ)空間時(shí),如果釋放的是數(shù)組,則別忘了[]。delete [] ar;
注意string對象的成員函數(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ì)對i++進(jìn)行優(yōu)化,但如果是其他類類型或指針時(shí)就不會(huì)了。
2,注意解除引用操作符與++操作符的優(yōu)先級,在實(shí)際代碼中為了簡潔經(jīng)常將*(i++)寫為*i++。因?yàn)?+的優(yōu)先級高于解除引用操作符。
3,在使用條件操作符時(shí),盡量避免寫出深度嵌套的條件操作符。另外條件操作符的優(yōu)先級非常低,在表示式中使用時(shí)要注意加括號,比如:cout<<(i<j?i:j);
4,關(guān)于sizeof運(yùn)算符。sizeof的運(yùn)算結(jié)果是編譯時(shí)的常量,注意下面的代碼的值:
int a[10];
int* p = a;
int n1 = sizeof(a) / sizeof(*a); // n1=10
int n2 = sizeof(p) / sizeof(*p); // n2=1
5,在復(fù)合表達(dá)式求值時(shí),要特別注意運(yùn)算符的優(yōu)先級與結(jié)合性。特別地,!=與==的優(yōu)先級小于<=,>=等關(guān)系運(yùn)算符。
6,在使用new進(jìn)行動(dòng)態(tài)內(nèi)存分配時(shí),有以下幾點(diǎn)值得注意:
1)動(dòng)態(tài)創(chuàng)建的對象可以用括號進(jìn)行初始化,比如:
int* p = new int();// 初始化為0
int* q = new int(1024);// 初始化為1024
2)可以delete刪除0指針,而且delete刪除的是分配到的內(nèi)存區(qū)域,并沒有刪除指針變量p,p依然指向原來的地址,只是原來的內(nèi)存已經(jīng)不存在了。這時(shí)p稱為懸垂指針,應(yīng)該將p設(shè)為0.
3)避免對同一內(nèi)存空間使用兩次delete。、
第6章 語句
1,在使用塊狀語句時(shí)注意,在塊狀語句內(nèi)定義的變量作用域只在塊狀區(qū)域內(nèi)。特別地,在控制語句,比如if或for語句中,初始化或定義的變量,都只有塊區(qū)域的作用域。
2,switch語句的使用。case標(biā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)試。
#ifndef NDEBUG
cout << "some useful information!";
#endif // !NDEBUG
在編譯時(shí)加上參數(shù)就可以決定是否打印那些調(diào)試信息。
第7章 函數(shù)
1,函數(shù)可以看作是程序員自己定義的操作符,與操作符一樣函數(shù)也可以進(jìn)行重載。
2,下面是用輾轉(zhuǎn)相除法求最大公約數(shù)的函數(shù),說明了函數(shù)定義的基本結(jié)構(gòu)。
int gcd(int v1, int v2)
{
// 輾轉(zhuǎn)相除法求最大公約數(shù)
while (v2)
{
int temp = v2;
v2 = v1%v2;
v1 = temp;
}
return v1;
}
5,沒有返回值的函數(shù)(返回值為void)里一般是不能有return語句,但是可以用return返回一個(gè)返回值為void的函數(shù)表達(dá)式。
void fun1()
{
void fun2();
return fun2();
}
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)對象,如:形參。這類對象在每次函數(shù)調(diào)用時(shí)都會(huì)創(chuàng)建,在函數(shù)執(zhí)行完時(shí)銷毀。還有一種對象為靜態(tài)局部對象,這種對象只有在程序結(jié)束時(shí)才會(huì)撤銷。不然一直在內(nèi)存中保留。
8,對于那種經(jīng)常需要調(diào)用且短小的函數(shù),可以設(shè)置為內(nèi)聯(lián)函數(shù),這種函數(shù)在編譯時(shí),編譯器會(huì)在函數(shù)調(diào)用處對函數(shù)進(jìn)行展開,進(jìn)行代碼替換。這樣就避免了函數(shù)調(diào)用中的開銷。定義內(nèi)聯(lián)函數(shù)是在函數(shù)定義前加inline。一般需要將inline函數(shù)放在頭文件中。
9,在類的成員函數(shù)中有一類函數(shù)在后面加上const限定符,用來說明為常量成員函數(shù),在對象使用時(shí),只能讀取不能改變對象的數(shù)據(jù)成員。
10,不要把this指針寫在了成員函數(shù)的形參表中。
11,在定義類時(shí),如果沒有定義默認(rèn)的構(gòu)造函數(shù),那么編譯器將為類創(chuàng)建一個(gè)合成的默認(rèn)構(gòu)造函數(shù)。這個(gè)函數(shù)將類的成員變量按對應(yīng)變量類型初始化方法進(jìn)行初始化:類類型的將調(diào)用該類的默認(rèn)構(gòu)造函數(shù),內(nèi)置類型則依賴于所處的環(huán)境是全局或靜態(tài)局部對象還是局部對象。合成的默認(rèn)構(gòu)造函數(shù)只適用僅包含類類型成員的類。
12,函數(shù)不能僅僅基于不同的返回類型而實(shí)現(xiàn)重載。
13,const在函數(shù)重載中值得注意的問題:
void fun(int num);
void fun(const int num); // 重復(fù)聲明
void fun(int& num);
void fun(const int& num); // 可以重載
void fun(int* num);
void fun(const int* num); // 可以重載
14,局部聲明的函數(shù)將會(huì)屏蔽將全局定義的重載函數(shù)。
void fun(int x, int y = 1);
int main()
{
void fun(double x);
fun(2,4); //error
return EXIT_SUCCESS;
}
15,指向函數(shù)的指針
函數(shù)指針指向函數(shù)而并非指向?qū)ο蟆ool (*pf) (int,int*); 其中pf是一個(gè)函數(shù)指針,該指針的類型為“指向返回bool類型并帶int與int*形參的函數(shù)的指針”。
1)可以用typedef來給指定函數(shù)的指針簡單定義:
typedef bool(*cmpFcn) (int,int*);
cmpFcn f1, f2;
上面代碼中定義了一種指針函數(shù)的類型,并用typedef提供了別名。f1與f2都是這種類型的指針。
2)給指向函數(shù)的指針初始化與賦值
對于定義好的函數(shù),其函數(shù)名沒有被調(diào)用時(shí),都被解釋為指向函數(shù)的指針,可以給同類型的指針賦值。
給指向函數(shù)的指針賦值為0,表明不指向任何函數(shù)。
在進(jìn)行指向函數(shù)的指針賦值時(shí),不存在任何類型的轉(zhuǎn)換。
3)通過指針調(diào)用函數(shù)
可以不用解除引用符號,如:f1(1,2)、(*f1)(1,2)。
4)指向函數(shù)的指針可以作為函數(shù)的形參:
void iVectSort(vector<int>::iterator , vector<int>::iterator ,bool(*)(int,int));
void iVectSort(vector<int>::iterator, vector<int>::iterator, bool (int, int));
上面兩個(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中,所以流對象不能存儲(chǔ)在vector或容器中,另外函數(shù)的形參與返回類型也不能為流類型,如果需要?jiǎng)t必須傳遞或返回指向該對象的引用或指針。一般來說,如果要傳遞IO對象以便對它進(jìn)行讀 寫,可以用非const引用方式傳遞這個(gè)流對象。對IO對象的讀寫會(huì)改變它的狀態(tài),所以必須是非const的。
2,每個(gè)IO對象都管理著一個(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中讀文件的名字,并對每個(gè)文件內(nèi)的內(nèi)容進(jìn)行處理,如果開始的流是定義在循環(huán)外的,則需要在循環(huán)結(jié)束時(shí)清除文件流的狀態(tài)。
ifstream input; // inPut是在循環(huán)外定義
vector < string::const_iterator it = files.begin();
while (it != files.end())
{
input.open(it->c_str());
if (!input)
break;
while (input >> s)
process(s);
input.close();
input.clear(); // 清除文件流的狀態(tài)
++it;
}
上面程序中,每一次讀文件,都會(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ù)。
ostringstream filename;
string prefix = "file_";
string suffix = ".jpg";
for (int i = 0; i < 100; i++)
{
filename << prefix << i << suffix;
}
2)將一串有格式的字符串,按格式解析為一些基本類型數(shù)據(jù)。比如,需要將一行日志文件內(nèi)容中的字符串與整數(shù)分別提取出來:
string logContent = "20140225 C++Primer 42";
istringstream input(logContent.c_str());
string dump;
int price;
input >> dump >> dump >> price;
欄 目:C語言
下一篇:c++實(shí)現(xiàn)發(fā)送http請求通過get方式獲取網(wǎng)頁源代碼
本文標(biāo)題:C++ Primer 第一部分基本語言
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/3773.html
您可能感興趣的文章
- 04-02c語言沒有round函數(shù) round c語言
- 01-10深入理解C++中常見的關(guān)鍵字含義
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10深入第K大數(shù)問題以及算法概要的詳解
- 01-10c++中inline的用法分析
- 01-10如何尋找數(shù)組中的第二大數(shù)
- 01-10用C++實(shí)現(xiàn)DBSCAN聚類算法
- 01-10全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法(C++)
- 01-10C++大數(shù)模板(推薦)
- 01-10淺談C/C++中的static與extern關(guān)鍵字的使用詳解


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達(dá)式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-10C#中split用法實(shí)例總結(jié)
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10delphi制作wav文件的方法
- 04-02jquery與jsp,用jquery
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 08-05織夢dedecms什么時(shí)候用欄目交叉功能?
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-11ajax實(shí)現(xiàn)頁面的局部加載