C++ Primer 第一部門根本說話。本站提示廣大學習愛好者:(C++ Primer 第一部門根本說話)文章只能為提供參考,不一定能成為您想要的結果。以下是C++ Primer 第一部門根本說話正文
第1章 疾速入門
1,引見main函數的意義和其根本構造,return語句。分歧平台下編譯與履行法式。
2,兩個類isrteam與otream與它們的實例對象cin,cout,cerr,clog。解釋了法式中根本的輸出與輸入。“<<”與”>>”作為操作符,左操作符是一個iostream 對象,右操作符是一個變量。前往值仍為一個iostream對象,所以輸出或輸入可以如許 cout<<”a=”<<a<<endl 連著寫。
3,C++中的兩種正文作風和須要留意的成績。
4,掌握成果:輪回(while與for),選擇(if…else…)。引入一個盤算兩個數之間一切整數的和例子。
5,C++最主要的特征:類。解釋了在類上界說的一些操作,簡略引見成員函數,用“.”來挪用成員函數。
6,書的開首引入的一個書店書目標成績,用一個完全的法式,進一步解釋了C++法式中的一些根本元素。固然Scales_item並沒有詳細的完成代碼。
第2章 變量和根本類型
1,履行算術運算時,數據類型的選擇:short 普通很少應用,輕易發生越界。char類型在一些完成中有時作為signed處置,而有時作為unsigned處置,所以只用char來表現字符是明智之舉。所以在年夜多半的時刻應用int就沒有成績,在許多機械上int用4個字節存儲,足夠知足年夜部門盤算的請求。浮點型的選擇就很簡略了,應用double類型根本不會有甚麼毛病,並且有能夠會比float盤算價值低。
2,字面值常量。只要內置類型存在字面值。寬字符的類型wchar_t,其實字面值字符常量後面加一個“L”,如wchar_t c=L'A';多行字符串可以用‘\'停止銜接,然則\前面弗成以有任何空格或制表符,下一行字符串字面值前也弗成以有任何空格和制表符。
3,引見了變量的概念,變量名的定名標准:1)變量名普通用小寫字母;2)標識符最好成心義;3)多個詞之間用下劃線或內嵌的單詞第一個字母年夜寫。別的,標識符不要以兩個持續的下劃線或下劃線+年夜寫字母定名。
4,界說對象(變量界說)。變量在界說的時刻可以停止初始化,可以選擇復制初始化(不要懂得為了賦值),也能夠選擇直接初始化。
int ival(1024); // direct-initialization
int ival = 1024; // copy-intialization
5,界說與聲明的差別;留意extern的應用。
6,const限制符的用法。const 界說的變量不克不及修正,所以必需在界說的時刻停止初始化。const變量假如想在多文件中應用,必需在界說的時刻就聲明為內部變量,即用extern。
7,引入與const。
1)非cosnt援用只能綁定到與該援用同類型的對象。
2)const援用則可以綁定到分歧但相干的類型的對象或綁定到右值。
8,列舉類型enum。
9,struct與class在創立類時的差別:struct的默許拜訪級別為public,而class的則為private。
10,解釋了C++說話頭文件的應用與編寫,和應用界說預處置器變量來防止頭文件的反復包括。
第3章 尺度庫類型
1,定名空間的using聲明
using std::string
2,尺度庫string類型
尺度庫string類型。string類型和字符串字面值不是統一品種型,留意幾種string的結構函數。
用cin讀取string類型時,讀取並疏忽開首一切的空白字符,直至再次碰到空白字符,讀取終止。
getline可以讀取輸出流中的一行,然則不包含換行符。
在string對象比擬時,小寫字母都比年夜寫字母要年夜,即年夜寫字母排在後面。
string對象的下標是從0開端到s.size()-1為止。
3,尺度庫vector類型
C++法式員習氣於優先應用!=而不是<來編寫輪回斷定前提。for(string::size_type i=0; i != s.size(); i++)
C++編譯器碰到內聯函數時,都是直接擴大響應的代碼,而不是現實的函數挪用,所以像size如許的小庫函數在輪回中挪用它價值是很小的。
4,迭代器簡介
每種容器都界說了begin與end函數,begin前往容器的第一個元素,end函數前往vector的末尾元素的下一個,平日稱為超越末尾迭代器,注解它指向了一個不存在的元素。假如vector為空,begin前往的迭代器與end前往的迭代器雷同。end前往的迭代器現實上是一個“尖兵”。
留意差別:
vector<int>::const_iterator // an iterator that cannot write elements
const vector<int>::iterator // an iterator whose value cannot change
5,bitset類型
幾種bitset的結構函數:
bitset<n> b;
bitset<n> b(u); // u是一個usigned long弄的數字,將換算成二進制數
bitset<n> b(s); // b 是string對象s中含有位串的正本
bitset<n> b(s,pos,n); // b是s中從地位pos開端的n個位的正本
第4章 數組與指針
1,數組
沒有一切元素都是援用的數組,數組中界說的類型可所以內置數據類型或類類型或隨意率性的復合類型(援用除外)。
數組的維數只能用在編譯階段就可以曉得的常量值。const int arSize=num; int ar[arSize];如許是不可的,由於num變量在運轉階段才管帳算出。
假如沒有給數組顯式地初始化,則會像通俗變量一樣停止初始化:1)在函數體外界說,則初始化為0;2)在函數體內界說,則其元素無初始化;3)不論數組在哪,假如其元素為類類型,則主動挪用該類的默許結構函數。假如該類沒有默許的結構函數,則必需為數組的元素供給顯式的初始化。
vector對象不克不及用同類型的數直接停止初始化。假定有以下數組: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)與另外一個指針停止比擬;2)向函數傳遞void*指針或從函數前往void*指針;給另外一個void*指針賦值。不許可應用void*指針把持它所指向的對象。
ptrdiff_t是尺度庫中界說的用於保留指向統一類型的指針之間減法的成果的類型。
const int* ptr; // ptr可以指向他變量,然則在沒有轉變ptr之前,不克不及用ptr是轉變它所指向的變量的值。
int* const ptr; // ptr不克不及指向其他變量,然則可以轉變ptr所指向的變量的值。
留意:
typedef string *pstring;
const pstring cstr;
下面的cstr是一種const指針,指針指向字符串類型的變量。pstring const cstr是一樣的。
3,C作風字符串
每個法式在履行時都占用一塊可用的內存空間,用於寄存靜態分派的對象,此內存空間稱為法式的自在存儲區或堆。
靜態分派的數組不克不及像數組一樣應用初始化列表,只能初始化為元素類型的默許值。int* ar=new int[10]();前面的空括號可讓數組元素都初始化為0。
用delete釋放自在存儲空間時,假如釋放的是數組,則別忘了[]。delete [] ar;
留意string對象的成員函數c_str()可以前往字符串的首指針。然則應當加const。 const char* str=s.c_str();
int* ip[4]:一個指向int的指針數組。
int (*ip)[4]:一個指針4元素數組的指針。
第5章 表達式
1,差別i++與++i
後置操作符須要先保留本來的值,再將i+1,然後前往本來的值;而前置操作符,只須要在本來值上加1,然後前往。所以++i比i++效力更高,固然假如i為int類型時,編譯器會對i++停止優化,但假如是其他類類型或指針時就不會了。
2,留意消除援用操作符與++操作符的優先級,在現實代碼中為了簡練常常將*(i++)寫為*i++。由於++的優先級高於消除援用操作符。
3,在應用前提操作符時,盡可能防止寫出深度嵌套的前提操作符。別的前提操作符的優先級異常低,在表現式中應用時要留意加括號,好比:cout<<(i<j?i:j);
4,關於sizeof運算符。sizeof的運算成果是編譯時的常量,留意上面的代碼的值:
int a[10];
int* p = a;
int n1 = sizeof(a) / sizeof(*a); // n1=10
int n2 = sizeof(p) / sizeof(*p); // n2=1
5,在復合表達式求值時,要特殊留意運算符的優先級與聯合性。特殊地,!=與==的優先級小於<=,>=等關系運算符。
6,在應用new停止靜態內存分派時,有以下幾點值得留意:
1)靜態創立的對象可以用括號停止初始化,好比:
int* p = new int();// 初始化為0
int* q = new int(1024);// 初始化為1024
2)可以delete刪除0指針,並且delete刪除的是分派到的內存區域,並沒有刪除指針變量p,p仍然指向本來的地址,只是本來的內存曾經不存在了。這時候p稱為懸垂指針,應當將p設為0.
3)防止對統一內存空間應用兩次delete。、
第6章 語句
1,在應用塊狀語句時留意,在塊狀語句內界說的變量感化域只在塊狀區域內。特殊地,在掌握語句,好比if或for語句中,初始化或界說的變量,都只要塊區域的感化域。
2,switch語句的應用。case標號必需是整形常量表達式,不許可在switch語句內界說變量假如在它上面還有case或default語句,由於如許會在某些情形下,在沒有履行變量界說的case分支的情形下,履行變量界說上面case分支。除非把變量界說在代碼塊內。
3,在for輪回中,假如有continue語句,會跳下continue前面的語句,然則不會跳變for語句中的計數器變更語句。
4,可使用預處置器停止調試。
#ifndef NDEBUG
cout << "some useful information!";
#endif // !NDEBUG
在編譯時加上參數便可以決議能否打印那些調試信息。
第7章 函數
1,函數可以看做是法式員本身界說的操作符,與操作符一樣函數也能夠停止重載。
2,上面是用展轉相除法求最年夜條約數的函數,解釋了函數界說的根本構造。
int gcd(int v1, int v2)
{
// 展轉相除法求最年夜條約數
while (v2)
{
int temp = v2;
v2 = v1%v2;
v1 = temp;
}
return v1;
}
5,沒有前往值的函數(前往值為void)裡普通是不克不及有return語句,然則可以用return前往一個前往值為void的函數表達式。
void fun1()
{
void fun2();
return fun2();
}
6,函數許可供給默許的實參,在挪用時,這一項參數可以省略,而讓法式應用默許值。普通應在函數聲明中指定默許實參,並將該聲明放在適合的頭文件中。
7,在函數體內界說的變量具有塊區域的感化域,可分為兩種一種為主動對象,如:形參。這類對象在每次函數挪用時都邑創立,在函數履行完時燒毀。還有一種對象為靜態部分對象,這類對象只要在法式停止時才會撤消。否則一向在內存中保存。
8,關於那種常常須要挪用且短小的函數,可以設置為內聯函數,這類函數在編譯時,編譯器會在函數挪用處對函數停止睜開,停止代碼調換。如許就防止了函數挪用中的開支。界說內聯函數是在函數界說前加inline。普通須要將inline函數放在頭文件中。
9,在類的成員函數中有一類函數在前面加上const限制符,用來講明為常量成員函數,在對象應用時,只能讀取不克不及轉變對象的數據成員。
10,不要把this指針寫在了成員函數的形參表中。
11,在界說類時,假如沒有界說默許的結構函數,那末編譯器將為類創立一個分解的默許結構函數。這個函數將類的成員變量按對應變量類型初始化辦法停止初始化:類類型的將挪用該類的默許結構函數,內置類型則依附於所處的情況是全局或靜態部分對象照樣部分對象。分解的默許結構函數只實用僅包括類類型成員的類。
12,函數不克不及僅僅基於分歧的前往類型而完成重載。
13,const在函數重載中值得留意的成績:
void fun(int num);
void fun(const int num); // 反復聲明
void fun(int& num);
void fun(const int& num); // 可以重載
void fun(int* num);
void fun(const int* num); // 可以重載
14,部分聲明的函數將會屏障將全局界說的重載函數。
void fun(int x, int y = 1);
int main()
{
void fun(double x);
fun(2,4); //error
return EXIT_SUCCESS;
}
15,指向函數的指針
函數指針指向函數而並不是指向對象。bool (*pf) (int,int*); 個中pf是一個函數指針,該指針的類型為“指向前往bool類型並帶int與int*形參的函數的指針”。
1)可以用typedef來給指定函數的指針簡略界說:
typedef bool(*cmpFcn) (int,int*);
cmpFcn f1, f2;
下面代碼中界說了一種指針函數的類型,並用typedef供給了別號。f1與f2都是這類類型的指針。
2)給指向函數的指針初始化與賦值
關於界說好的函數,其函數名沒有被挪用時,都被說明為指向函數的指針,可以給同類型的指針賦值。
給指向函數的指針賦值為0,注解不指向任何函數。
在停止指向函數的指針賦值時,不存在任何類型的轉換。
3)經由過程指針挪用函數
可以不消消除援用符號,如:f1(1,2)、(*f1)(1,2)。
4)指向函數的指針可以作為函數的形參:
void iVectSort(vector<int>::iterator , vector<int>::iterator ,bool(*)(int,int));
void iVectSort(vector<int>::iterator, vector<int>::iterator, bool (int, int));
下面兩個函數的聲明中上式第3個參數為一個指向函數指針類型,下式的第3個參數為一個函數類型,它會主動轉換為一個指針類型。
5)函數類型可以作為函數的形參,然則不克不及作為函數的前往類型。
6)在指向函數的指針指向重載函數時,類型必需分歧。
第8章 尺度IO庫
1,尺度庫類型不許可做復制和賦值操作。由於只要支撐復制的元素類型可以存儲在vector中,所以流對象不克不及存儲在vector或容器中,別的函數的形介入前往類型也不克不及為流類型,假如須要則必需傳遞或前往指向該對象的援用或指針。普通來講,假如要傳遞IO對象以便對它停止讀 寫,可以用非const援用方法傳遞這個流對象。對IO對象的讀寫會轉變它的狀況,所以必需長短const的。
2,每一個IO對象都治理著一個緩沖區,有以下幾種方法可以刷新緩沖區(將緩沖區內容寫到裝備上)。
1)輸入緩沖區的刷新:flush刷新流但不添加任何字符;ends這個操作符在緩沖區中拔出空字符NULL,然後刷新它。endl換行並刷新。
2)unitbuf操作符:cout<<unitbuf<<”first”<<”second”<<nounitbuf;nounitbuf操作符將流恢復為正常的,由體系治理的緩沖區刷新方法。
3)法式瓦解時,不會刷新緩沖區。這一點在調試已瓦解的法式時須要特殊留意。
4)可以用tie函數將istream與ostream綁縛在一路,當應用任何IO操作時都邑刷會實參所聯系關系的緩沖區。
3,留意消除文件流的狀況,上面法式從一個vector中讀文件的名字,並對每一個文件內的內容停止處置,假如開端的流是界說在輪回外的,則須要在輪回停止時消除文件流的狀況。
ifstream input; // inPut是在輪回外界說
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(); // 消除文件流的狀況
++it;
}
下面法式中,每次讀文件,都邑以碰到文件停止符或其他毛病終止,這個點上input處於毛病狀況。假如封閉該流前沒有挪用clear清除流的狀況,接著在input上做的任何輸出運算都邑掉敗。
4,stringstream由iostream派生而來,供給讀寫string的功效。可以將一個字符串轉化為流用於輸出或輸入。這個類重要有兩種罕見的用途:
1)將必定格局的變量值構成一個字符串。 假定在一個輪回內,我們要保留中央數據到硬盤,那末須要文件名,且須要將輪回的索引寫入文件名,防止文件名的反復。
ostringstream filename;
string prefix = "file_";
string suffix = ".jpg";
for (int i = 0; i < 100; i++)
{
filename << prefix << i << suffix;
}
2)將一串有格局的字符串,按格局解析為一些根本類型數據。好比,須要將一行日記文件內容中的字符串與整數分離提掏出來:
string logContent = "20140225 C++Primer 42";
istringstream input(logContent.c_str());
string dump;
int price;
input >> dump >> dump >> price;