C++primer(第四版)複習筆記—第一篇:基礎語言

來源:互聯網
上載者:User

標籤:c++primer   c++基礎   

再次閱讀primer一方面是為了查漏補缺,另一方面也是更加深入的理解C++的思想精髓。在此記錄複習中記錄的各知識細節及理解,以便後續溫故之用。

第一張:快速入門
1. for語句: for(初始化語句;條件測試語句;條件修改運算式){ 語句體 } 。執行順序:初始化語句在最開始執行一次,然後執行條件測試語句,若成立則執行語句體;然後再執行條件修改運算式,再執行條件測試語句,成立則繼續,反之則退出for語句。
2. if else語句縮排:

if(0==i){        cout<<"i==0"<<endl;    }else{        cout<<"i!=0"<<end;    }

3、讀入未知數目的輸入:

int value; while{std::cin >> value}     sum+=value;//將輸入的所有值相加(個數未知)。

while{std::cin >> value}語句中std::cin>>value返回輸入資料流本身,while通過測試該流的狀態來判斷條件是否成立。如果狀態有效則測試成功。輸入資料流當遇到檔案結束符或無效輸入(此處比如輸入的不是一個整數)時,則流對象的狀態時無效的。
4、而檔案結束符:Windows下按CTRL+Z,Unix下按Ctrl+D。
5、cin:用於從標準輸入中讀入的istream對象(cin>>value:從標準輸入中通過istream對象cin,將輸入讀入到標量value)
Cout:用於寫入到標準輸出的ostream對象(cout>>value:將變數值通過osteam對象out輸出到標準輸出)
標準輸入:和程式執行視窗相關聯的輸入資料流,這種關聯由作業系統設定
標準輸出:和程式執行視窗相關聯的輸出資料流,這種關聯由作業系統設定。
6、函數實參:被傳遞給調用函數的值。 函數形參:函數定義的組成部分,指明可用什麼參數來調用該函數。

第2章: 變數和基本類型
1、電腦將儲存空間中的每一個位元組和一個地址關聯。可以用地址表示從該地址開始的任何幾個不同大小的位集合,比如可以說地址為0x….的字(4個位元組)或地址為0x的位元組。要讓某個位元組(8個bit位)具有意義,必須要知道儲存在該地址上的值的類型。(該類型由額外的4個位元組的系統開銷來指定),從而根據該地址內容的類型來解釋其中的資料,這才使得該地址的內容具有實際意義(否則只是由0、1組成的位串)。
2、BOOL與bool FALSE/TRUE與false/true的區別:
BOOL是通過#define BOOL int 得到的,因此BOOL為整型,同樣FALSE/TRUE也是#define得到的整型,其大小與具體編譯環境有關(整型一般為4位元組大小,具體看環境)。其取值:BOOL是微軟定義的typedef int BOOL(在windef.h中)。它是一個三值邏輯,TRUE/FALSE/ERROR,傳回值為大於0的整數時為TRUE,傳回值為0時候,為FALSE,傳回值為-1時為ERROR。
而bool則是C++中新增的資料類型(C中沒有),大小為一個位元組,取值為true或false,大小為一個位元組。bool取值false和true,是0和1的區別
3、有符號整型:以一個位元組的來說明,取值為-8—7:正數,即除了最高位的符號位(為0)低三位的值(0—7);負數(最高位為1)時,轉換為補碼錶示(正數的原碼 反碼 補碼都一樣,負數的反碼為原碼除最高位符號位外其他的取反,而補碼為反碼加1),因此1000,即表示-8:(反碼為1111,補碼為1111+1=符號位為1,此外還剩1111,即為8,因此結果為-8);同理1001為-7,1111為-1。
計算補碼: 變數A用N位來儲存(N不算符號位),當其為負數時計算其補碼的方法是A=-(A+2^N);
4、整型的賦值:當把一個超出其範圍的值賦值一個變數時,編譯器必須調整時期滿足要求——將該值對該unsigned類型的可能取值的數目求模,然後求得其值。如將336賦值給unsigned char(一個位元組),結果為336%256=80; 在C++中將一個負值賦給unsigned 類型是合法的,其結果也是模數。如將-1賦值給8位的unsigned cahr 結果為:-1%256=255;(模的符號與除數一致,求餘結果與被除數一致)
5、模數:任何一個整數a都可以表示成a=k*b+r,歸納:當a和b符號一致時,求模運算和求餘運算所得的c的值一致,因此結果一致 ; 當符號不一致時,結果不一樣。求模運算結果的符號和b一致,求餘運算結果的符號和a一致。(-7 mod 4=1,-7%4=-3)。
6、為了與C語言相容,C++的所有字串字面值都由編譯器自動在末尾添加一個Null 字元。
7、變數提供了有名字的儲存區,因此可用變數名來引用對應儲存空間的值。變數名只能有字母、底線、數字組成,不能以數字開頭。
左值:可以出現在指派陳述式的左邊或右邊,如變數
右值:只能出現在指派陳述式的右邊,如字面常量:5 、”abc”。
8、兩種初始化方式:複製初始化(int i=10;),直接初始化(int i(10);)。直接初始化效率更高(但對內建類型基本無區別)。
9、當沒有指定初始化值時,系統有時會自動初始化。
內建類型自動初始化:在函數體外定義的變數都初始化為0(進程空間中未初始化資料區段的所有變數,如全域未指定值的變數、全域和局部未指定值得靜態變數,都自動初始化為0或者NULL指標),函數體內未指定初始值的變數(棧中的資料 如自動變數不進行自動初始化,其值未定義,可能為隨機值:殘留在所在記憶體位址中的資料值)不進行自動初始化。
類類型的變數的初始化:對於有預設建構函式的類型,可以不顯示初始化;而對於沒有預設建構函式的類型,必須提供顯示的初始化。
10、變數定義:用於為變數分配儲存空間,還可以指定初始值。在一個程式中變數有且有一個定義。定義包含聲明。
變數聲明:用於表明變數類型和名稱,不是定義,也不分配空間。用關鍵字extern int I ;對i進行聲明。注意包含初始化式的聲明認為是定義(在此之前沒有定義該變數,且在此之後不能再定義改變了) extern int i=10;被認為是定義。
11、const:定義非字面值常量:const int bufsize=512; bufsize為仍然為左值變數,但是其值不能再被修改。定義是必須初始化。 Const對象預設為檔案局部變數,即在一個檔案中定義的const變數在其他檔案中是不能使用的,除非定義時申明為全域變數:(file1.cc)extern const int bufsize =512//定義並聲明為全域變數;在其他檔案中聲明(file2.cc)extern const int bufszie;//聲明。
12、引用:引用是定義另一變數的別名。(只能是對變數定義別名,不能是字面值 如 int &val=10;//錯誤 int i; int & val=I;//對,但const引用可以:const int &ref=512;對的),因為引用只是一已有變數的別名,因此引用不會給引用額外分配空間。
13、const 引用:const int val=1024; const int & refval=val;(int & refval2=val;//錯誤)(對const變數,必須綁定到const 引用上,而不能綁定到非const引用,否則就允許通過引用來改變原const變數值,這是不合法的)。const 引用是指向const對象的引用。 可以對非const變數定義const的引用,此時只能通過變數名修改其值(當然此時const引用的值也變數了!),而不能通過引用名來修改。
14、typefef:定義已有類型的同義字編譯時間處理,並沒有引入新的類型。Typedef int INT;(原名在前);#define則是宏定義,其實是替代,在先行編譯時簡單替代,不進行正確性檢查。

#define int_ptr int *  (源在後)int_ptr a, b; //相當於int * a, b; 只是簡單的宏替換typedef int* int_ptr;  (源在前)int_ptr a, b; //a, b 都為指向int的指標,typedef為int* 引入了一個                    新的助記符

15、枚舉類型(整數常量集)enum:enum Point{ a, b ,c};(a預設賦值為0,其後遞增1)//定義了新的類型Point; Point p1=a;//定義Point類型的變數(注意枚舉類型變數只能用其類型的枚舉成員來賦值,或者用同類型的枚舉變數賦值,而不能用其他任何方式賦值),(枚舉成員a b c本身是一整形常量,可用於需要常量運算式的任意地方,如數組定義的維數 :int array[c];//則定義了一個2個元素的數組,const定義的整形也可作為數組長度)
16.類: 類定義資料成員時不能直接初始化,需要用建構函式初始化資料成員。 Private的資料成員只能通過其成員函數來訪問,public的資料成員可以通過對象名訪問。
17、calss與struct的區別僅在於預設存取層級不同。
18、標頭檔用於聲明而不是定義:因為標頭檔包含在多個源檔案中,所以標頭檔不應包含變數或函數的定義(例外:標頭檔可以定義類 const對象和inline函數,因為編譯器需要他們的定義來產生代碼)(注意為使const變數具有所有檔案全域可用,定義是需要加上extern關鍵字)
19、標頭檔避免多重包含:#ifnfef AAA #define AAA #endif

第3章:標準庫類型
標準庫String類型:
1、 從標準輸入讀取sting時,讀取並忽略開始的所有空白字元(空格 換行 定位字元);讀取字元指導在此遇到空白字元,讀取終止。cin>>str;輸入:“ Hello World! ”,則str實際是”Hello”,開頭的空白被忽略,後面的空白已終止。
2、 String IO操作:getline(istream cin,string str);該函數從輸入資料流中讀取一行,並儲存到sting中,只要遇到分行符號就停止並返回(如果第一個字元就是分行符號,則string對象為空白,注意與cin讀取一個string時的區別),傳回值為流對象如cin,當while(getline(cin,str));作為條件陳述式時,與前面的cin>>str一樣,測試返回的流對象狀態。 (CTRL+Z結束輸入)
3、 將一個字串字面常量賦值給一個string對象時,不包含字串中末尾自動添加的Null 字元,如string str=”abc”;則str只包含abc三個字元。
4、 不可用int代替strng::size_type類型(strng::size_type定義為無符號整型,因此其長度是int的兩倍,如果用int來接受size_type的值,可能會造成溢出:int i=str.size();//可能返回的size_type值大於int的最大值而出錯(正確:size_type size_t=str.size();)。
5、 String對象的賦值:string str1,str2=”aaa”; str1=str2;//(給str1賦值:先釋放掉str1的記憶體,然後再給str1分配足夠存放str2副本的空間,再將str2的字元複製到str1的空間),因此這種賦值方式是低效的。
6、 String和子面值字串的串連: string str; str=”aa”+”bb”;//錯誤:串連+號的左右運算元至少有一個必須為string類型。
7、 String中單個字元的處理函數:標頭檔< cctype >中包含了大量處理單個字元的函數:例如toupper(str[2]);//將字元st[2]轉化為大寫字母,並返回大寫字母; ispunct(str[2]);//測試字元是否為標點。等等!

標準庫vector:
1、 下標操作符[],僅能對已經存在的元素進行操作。 該操作符返回對應元素的引用,因此vector vec(10,2); vec[2]=100;//使得vec的第三個元素為100,。對sting一樣。
2、 所有的標準庫容器都定義了相應的迭代器,而只有少數定義了下標操作符。
3、 注意迭代器失效問題。任何改變vector長度的操作(如push_back)都會使原來的迭代器失效。
4、 Const_iterator迭代器:vector::const_iterator const_iter;//不能通過該迭代器修改其指定元素的值。(但可以改變其指向的元素)
5、 兩個同類型的迭代器相減得到其差值(類型為difference_type,被vector定義為signed的別名,類似於size_type為unsigned)。但是不能對兩個迭代器相加,(兩個指標相加,未定義)。

標準庫bitset類型

第四章:數組和指標
數組:
1、 數組維數必須為大等於1的常量變運算式(字面常值、枚舉常量、const常量:const常量+字面常量,還是常量)。
2、 當用字面值字串來初始化字元數組,不能忘了給字串末尾的NULL預留空間。
3、 不允許對數組直接複製和賦值:int a[]={1,2,3}; int b[3]=a; //錯誤(原因在於:數組名是不可修改的左值:常量指標)
4、 取地址操作符只能用於左值
5、 C++使用將一個表示符聲明為一個指標。風格:int a; 與 int a;都對,但應使用後者,如:int a, b;//實際上只有a為指標,b為int。(會誤解為a b都為指標); 而int *a,*b;//才定義了兩個指標。
6、 指標值為0,表明指標不指向任何對象,避免使用未初始化指標。如果定義指標時不能指定所指對象,則應將指標初始化為0.(只能把字面值0給指標,而不能把值為0的整型變數賦給指標)(預先處理變數null為0)
7、 Void*指標能接收任何非const類型對象的地址,但是不提供所指地址上對象的類型資訊,因此不能對void指標所指的對象進行直接操作,如解引用等。可做比較、函數參數等
8、 指標的算數操作:當指標指向數組中的某個元素時,對該指標進行加減n操作,得到一個新的指標,該新指標指向原元素的前面或後面的第n個元素。(注意:加減n不能使得新指標越界。 允許指向數組最後一個元素的下一個位置,即超尾,但不能對超尾進行解引用,而只能作為哨兵,作用與vector的end()迭代器一樣)。
9、 指向同一數組中元素的兩指標相減(包括超尾指標): 得到兩指標間的間距,類型為ptrdiff_t (signed)。 兩個指標相加,是無意義的!!
10、 下標和指標: 使用下標訪問數組實質是由下標+原指標得到一個指向新元素位置的 新指標。 如:int a[10]={}; a[5]即為首指標a加上5得到指向第6個元素的新指標; 而int* p=&(a[5]); p[-2];//由於p初始指向第6個元素,然後又後退一2個,因此p[-2]及為a[3];
11、 數組名指向首元素的常量指標: 不能對其進行++,–等操作來改變其指到其他元素上去。
12、 數組末尾的下一個單位的指標為數組的超尾: 超尾起哨兵作用,用於比較,防止越界。但不能對其解引用。 不能計算超尾以後和首地址以前的地址。
13、 (指標常量)指標const對象的指標:const int *p;(可以不初始化) 理解為指向常量。 即所在對象的值不能改變,但可以改變指標指到其他對象。可以給指標常量賦非const對象的地址(此時仍不能通過該指標常量來改變其值,因為始終假設其指向的對象為const對象)。
14、 (常量指標)cosnt指標: int *const p=&a;//必須初始化。指標本身為常量,不能改變該指標使其指向其他的對象。 但所指對象的值是否改變,取決於對象本身是否為const對象。
15、 指向const對象的const指標:const int *const p=&a;//必須初始化。所指對象和所指對象的值都不能改變。
16、 Const修飾緊接其後的標識符。
17、 字串字面值的類型就是const char 數組。時刻注意末尾的NULL
18、 處理C風格字串的標準函數庫(string.h的c++版本)cstring。

19、 初始化new動態分配的數組:如果元素類型為類類型,則預設建構函式初始化。 若為內建類型,則無初始化值。

String *str=new string[10];//10個元素都初始化為空白Int *p=new int[10];//10個元素都未初始化Int *p1=new int[10]();//在後面跟上括弧,要求編譯器將其元素都初始化為0.

20、 String 和C風格的字串混用:
(1)、可以用C風格字串對string進行初始化和賦值(忽略末尾的NULL)。
(2)、反之不成立:不能用string直接對C風格字串進行初始化或賦值。可用string的成員函數c_str將string轉為C風格字串。注意:c_str()函數返回一個指標常量,該指標指向string的字串(在末尾加NULL)。
例:string str(“aaa”); const char *c=str.c_str();//此時c指標指向“aaa”(末尾有NULL) 然後修改str:str=”bbb”; 則c的值也被改變為“bbb”末尾加NULL。
21、 多維陣列:理解為數組的數組。
(1)、int *p[4];//定義指標數組:p為包含4個指標的數組。
(2)、int (*p)[4];//p為一個指向有4個元素的數組的指標。

第五章:運算式
1、 %求餘或模數。其運算元只能為整型。 兩整數相除,結果為整數,小數被截去。
2、 兩個運算式求與或運算,僅當第一個運算式不能確定整個結果為false或、true時才需要計算第二個運算式的值,或者不會計算第二個的值。
3、 注意string也有迭代器:string::iterator it=s.end();
4、 不應串接使用關係操作符: 關係操作符(< <= > >=)具左結合性: if(i

void func(int  &a[10]);//元素為引用的數組void func(int  (&a)[10]);//這才是數組的引用,括弧不可少類似: int *a[10];//表示10個指標的數組Int  (*a)[10];//表示數組的指標;括弧不可少

可理解為:*和&向前結合。
3、 多維陣列即數組的數組: 多維陣列形參除了第一位的長度可不指定(與一維一樣,編譯器自動忽略),其他維長度必須明確指定。 實際傳入的時一個指向數組的指標。
4、 返回引用、返回常引用。 千萬不可返回局部對象的引用或指標。
5、 函式宣告:傳回型別、函數名、參數列表 ,這三個元素稱為函數原型,描述了函數介面。
6、 函數預設實參:在聲明或定義時,如果個其中一個參數指定了預設實參,則其後的所有參數都要指定預設實參; 相反,在調用時若給其中一個參數傳入了實參,則該參數之前的所有都應該顯示傳入實參,預設實參值能填補末尾空缺的形參。 既可以在函式宣告時也可以在函數定義時指定函數預設實參,但是不同同時指定。 通常在聲明中指定。
7、 內嵌函式:避免函數調用的開銷,但這隻是提供給編譯器的建議。 內嵌函式必須放在標頭檔中定義。
8、 類的成員函數:函數體既可以在類中定義,也可以在類外定義。編譯器隱式的將在類內部定義的成員函數當做內嵌函式。
9、 每個成員函數隱含一個額外的參數:this指標,即指向調用該函數的對象的指標。比如在該函數中使用其對象的其他成員變數等都是通過該隱含參數來調用的。
10、 常量成員函數:即在函數的聲明的形參表後加上關鍵字 const。這使得調用該成員函數的對象為const對象,即this指標為指標常量,指向const對象,因此在該成員函數中不能改變對象的成員。注意:聲明與定義必須一致,聲明時有const,則定義時也必須有。
11、 注意:const對象、指標向const對象的指標或引用,只能用於調用const成員函數,如果嘗試調用非const成員函數則是錯誤的。(因為他們表示不修改對象的任何成員,如果調用非const成員函數則可能修改對象)
12、 This指標:在成員函數的形參表中不能顯示的包含this指標參數,在函數體中任何沒有首碼的使用其對象的成員被假定是通過this指標調用的。 (在函數體中可以顯示的使用this指標來調用自身對象的成員,是合法的:this->member;)
13、 建構函式:建構函式放在public部分,沒有傳回值,可帶初始化列表(參數列表與函數體的大括弧之間,以:開頭)
(1)、預設建構函式:指明沒有顯示提供初始化時該怎麼辦預設調用,不用提供任何初值。(如果沒有為類顯示定義任何建構函式,編譯器會自動產生一個預設建構函式,這種建構函式一般只適用於僅包含類類型成員的類,含有內建類型成員的類,應該自己定義預設建構函式)
(2)、建構函式的初始化列表:為類的一個或多個資料成員指定初值。如類A: 建構函式:A():intmemb(0),doubmemb(0.0){ };//沒有給定初值的資料成員,調用其自身的預設建構函式進行初始化。
14、 函數重載:在同一範圍中的多個函數,具有相同的函數名,而形參表不同,則成為重載函數(main函數不可重載)(注意內部範圍的名稱會覆蓋外部範圍的函數或變數)
15、 函數不能僅僅基於傳回型別的區別來重載(如果兩個函數的參數列表相同,只是傳回型別不同,則第二個函式宣告是錯誤的)
16、 選擇確定重載函數的三個步驟: 尋找候選函數集、選擇所有可行函數(包括精確匹配的、類型轉換匹配的)、尋找首選。(如果確定不出首選的一個,則調用具有二義性,出錯)(型別提升 優於 標準轉換
17、 僅當形參為引用或指標時,形參是否為const才有影響,此時才可以通過是否為const來重載。(如參數:引用 與常引用 可用來重載; 非引用 和const非引用 不可以,因為兩者都是實參的拷貝,實參均可為const或非const) 對指標同理:(f(const int )與f(int )是重載;; f(int *)與f(int *const );不是重載,二者都可接受常量或非常量指標,都為拷貝)
18、 函數指標: 和其他指標一樣,函數指標也某個特定的類型,函數類型由其傳回型別和參數列表確定,與函數名無關。
19、 返回指向函數的指標:int (func(int))(int ,int);
由內到外理解: 內:func(int):func是一個帶有一個int參數的函數。 該函數的傳回值(外層)為: int()(int, int);這樣的一個函數指標。
可通過typedef來使得簡單易懂:
Typedef int (pf) (int , int);//定義了一個函數指向帶兩個參數(一個整型指
//針,一個整型)且傳回值為int的 類型 的函數指標。
Pf ff(int);//ff為參數為int,傳回值為pf這種類型的函數。

第八章:標準IO流 (標準輸入輸出資料流 檔案流 字串流)
1、 IO標準對象不可複製或賦值: 當需要傳遞IO對象時必須傳遞io的引用或指標。 由於對IO流對象的讀寫會改變其狀態,因此不能傳遞const的引用。
2、 輸出緩衝區的管理:一下幾種情況將導致輸出緩衝區被重新整理,即寫入到真是的輸出裝置或檔案:
(1) 程式正常結束:main返回工作的一部分,將清空所有的緩衝區。
(2) 在一些不確定的時候,緩衝區已滿
(3) 顯示調用重新整理緩衝區的操作符:enl flush ends 等。
3、 需要注意: 程式崩潰時,不會重新整理緩衝區,因此在根據輸出來偵錯工具時,需要確保每次輸出的都成功的重新整理輸出到裝置上。 因此在每次輸出時都使用endl來重新整理輸出。
4、 當輸入與輸出資料流關聯在一起時,任何讀輸入資料流的嘗試都將首先重新整理輸出緩衝區。標準庫將cin cout關聯在一起。 Cin>>ival;導致cout關聯的緩衝區被重新整理。 可用函數tie來將輸出資料流 輸入資料流關聯。
5、 檔案流對象的使用:(需要自己定義兩個檔案輸入輸出資料流對象)頭文

#include <fstream>ifstream ifile;//檔案輸入資料流對象(沒關聯到檔案)//輸出資料流,初始化關聯到給定路徑檔案(C風格)ofstream ofile("C:Desktop\\test(2).txt");        ifile.open("C:Desktop\\test(2).txt");//關聯ofile<<"where are you? "<<endl;//向檔案寫資料 string str;   ifile>>str;//從檔案讀資料:與cin一樣,遇到空白止getline(ifile,str);//從檔案輸入資料流關聯的檔案讀入一行到strcout<<str;   //輸出到標準輸出裝置

注意:在open開啟檔案後,要記得檢查是否開啟成功
if(!ifle)//若不成功則提示。 另外,fstream一旦開啟,就保持與指定檔案關聯,若要把檔案流對象關聯到其他檔案,則必須先關閉close當前檔案,然後再open其他檔案,且在再次open之前需要調用clear函數清除流狀態標識。
6、 Open開啟檔案時注意設定開啟模式。如要用ofstream開啟檔案時保留已有內容,則必須顯示的將檔案設定為app開啟模式。 Ofile(“filename”,ofstrream::app);
7、 Fstream流對象,既可以讀也可以寫開啟的檔案。
8、 字串流: 將流對象sstream(需要包含標頭檔sstream)與string對象綁定,從而通過sstream讀寫string字串

C++primer(第四版)複習筆記—第一篇:基礎語言

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.