while(cin >> x)中會一直循環檢測cin是否輸入,始終無法跳出,如果while函數外有cout函數則按ctrl+C會輸出cout中想要輸出的前兩個字符。
有時候沒有編譯成功看看是否有導入頭文件
VS2015中指針不賦初值無法輸出到屏幕
未賦值的string int類型變量在VS2015中無法編譯通過,如果在定義變量之後再定義一個引用則編譯可以通過。int類型在main()外定義得到結果為0,在main()中定義則顯示結果是-858993460
C語言中經常使用NULL當做空指針,在C++中常使用nullptr來當做預處理變量,盡量避免使用NULL
關於void*指針,拿來和別的指針比較、作為函數的輸入或輸出,或者賦給另外一個void*指針。不能直接操作void*指針所指的對象,因為我們並不知道這個對象到底是什麼類型,也就無法確定能在這個對象上做哪些操作(VS2015中可以聲明定義,但是只能輸出地址,無法輸出地址中的值)
引用使用std::cout的時候直接輸入變量值即可不用再前面加&
數據類型 *&變量名即生成了一個關於指針的引用
Const 類型 & a = b,可以通過改變b來改變a,反之則不行。如果a 和b的類型不同則也不可以通過改變b來改變a。(類型不同涉及到臨時量的問題)
一般引用無法直接賦值,在前面加上const基本數據類型就可以為常量引用綁定字面值。
constexpr把它所定義的對象置為了頂層const
一個constexpr指針的初始值必須是nullptr或者0,或者是存儲於某個固定地址中的對象
函數體內定義的變量一般來說並非存放在固定地址中,因此constexpr指針不能指向這樣的變量
std::cin>>int i;在輸入中這樣定義是無法編譯成功的
直接用unsigned對變量賦值,變量的類型是無符號的整型數值
頭文件一旦改變,相關的源文件必須重新編譯以獲取更新過的聲明
定義指針之後賦值整數給它的地址無法通過編譯
Auto一般會忽略掉頂層const
設置一個類型為auto的引用時,初始值中的頂層常量屬性仍然保留
Auto * 變量名= 引用和auto 變量名 = 引用出來的效果類似
假使const inti =某整數,如auto a = i,則a為整型,如果想利用auto生成整型常量的話只需要在auto之前加上const即可;而如果用auto &a = i,則a為整型常量引用
auto一次性定義多個變量,必須使每個變量的類型都是同一種數據類型,否則編譯無法通過
對於decltype類型指示符來說,如果表達式的內容是解引用操作,則decltype將得到引用類型
使用decltype初始化指針即decltype(x)y=&z;
decltype((variable))(注意是雙層括號)的結果永遠是引用,而decltype(variable)結果只有當variable本身就是一個引用時才是引用
在for循環中的第一個表達式中不能同時聲明兩個不同類型的變量
是否為為空字符串可利用字符串是否等於"\0"來判斷
<標識>在理論上說可以是自由命名的,但每個頭文件的這個“標識”都應該是唯一的。標識的命名規則一般是頭文件名全大寫,前後加下劃線,並把文件名中的“.”也變成下劃線,如:stdio.h=_STDIO_H_
getline只要一遇到換行符就結束讀取操作並返回結果,哪怕輸入的一開始就是換行符也是如此
getline函數的對象需要是string類型的
當把string對象和字符字面值及字符串字面值混在一條語句中使用時,必須確保每個加法運算符(+)的兩側的運算對象至少有一個是string
字符串字面值與string是不同的類型
字符中的空格用' '表示即可
使用break可以從當前的for、while循環中跳出
對邏輯運算符(&&)來說,C++語言規定只有當左側對象為真時才會檢查右側運算對象的情況
如果循環體內部包含有向vector對象添加元素的語句,則不能使用范圍for循環
范圍for語句體內不應改變其所遍歷序列的大小
vector對象(以及string對象)的下標運算符可用於訪問已存在的元素,而不能用於添加元素
vector容器輸出可以利用范圍for循環和數組的方式輸出
迭代器中因為end返回的迭代器並不實際指示某個元素,所以不能對其進行遞增或解引用的操作
右側的迭代器向前移動多少位置就能追上左側的迭代器,其類型是名為difference_type的帶符號整型數,因為這個距離可正可負
但凡是使用了迭代器的循環體,都不要向迭代器所屬的容器添加元素
如果利用字符串形式給字符數組賦值需要空出一個空間存放空字符
對數組聲明定義的理解,由內向外閱讀要比從右向左好多了
在使用數組下標的時候,通常將其定義為size_t類型
在cstddef頭文件中定義了size_t類型(無符號),這個文件是C標准看見stddef.h頭文件的C++語言版本
關於auto和decltype,例:inti[]={0,1,2,3,4,5};auto a(i);decltype(i) b={1,2,3,4,5,6};auto導出的類型是整型指針,decltype導出的是整型數組。
指向數組位置的begin函數和end函數定義在iterator頭文件中
兩個指針相減的結果的類型是一種名為ptrdiff_t的標准庫類型(帶符號),和size_t一樣,ptrdiff_t也是一種定義在cstddef頭文件中的機器相關的類型
尾後指針不能執行解引用和遞增操作
char a[]=[Hello]與charb="Hello"的尾指針的元素值是不同的char b="Hello"是以空字符結束的
VS2015中應用strcat_s函數時需要知道其中一個具體的長度否則會報錯,例:strcat_s(a,sizeof(a),b)
編程時如果直接聲明數組未定義不能直接使用strcat_s函數
關於混用string對象和C風格字符串,允許以空字符結束的字符數組來初始化string對象或者為其賦值,反過來則不行。如果要使用string類型的值當右值的話需要使用.c_str()的成員函數
使用指針的迭代器begin(a)、end(a)的時候需要聲明在std空間內
嚴格來說C++語言中沒有多維數組,通常說的多維數組其實是數組的數組
typedef取別名的范圍只包括(int、char這些類型)而如果我們想為int[4]這樣的類型取別名的話就只能使用using 例:typedef intwoshinidie; using woshinibaba=int[4];
參與取余運算的對象必須是整數類型
因為執行sizeof運算能得到整個數組的大小,所以可以用數組的大小除以單個元素的大小得到數組中元素的個數
非零整數轉換成布爾值都是true
求余:分母負即正,分母負必負
if(i1該式必成立
If(a==true) 如果a不是布爾值,那麼進行比較之前會首先把true轉換成a的類型
case中不能初始化,初始化是非法行為。
Switch case中不能判定字符串
Case後面不能跟變量,不能加逗號
在范圍for語句中,預存了end()的值。一旦在序列中添加(刪除)元素,end函數的值就可能變得無效了
局部靜態對象在程序的執行路徑第一次經過對象定義語句時初始化,並且直到程序終止才被銷毀,在此期間即使對象所在的函數結束執行也不會對它有什麼影響
如果函數無須改變引用形參的值,最好將其聲明為常量引用
C++中,建議使用引用類型的形參替代指針
如果函數無須改變引用形參的值,最好將其聲明為常量引用
Initializer_list列表中的元素全部都是const
一個返回類型是void的函數也能使用return語句的第二種形式(returnexpression;),不過此時return語句中的expression必須是另一個返回void的函數。強行令void函數返回其他類型的表達式將產生編譯錯誤
在含有return語句的循環後面應該也有一條return語句,如果沒有的話該程序就是錯誤的。很多編譯器都無法發現此類錯誤
不要返回局部對象的引用或指針
cstdlib頭文件定義了兩個預處理變量(EXIT_FAILURE和EXIT_SUCCESS)
因為數組不能被拷貝,所以函數不能返回數組
數組指針:Type(*function(parameter_list))[dimension]
尾置返回類型:autofunc(int i)->int(*)[10] //func接收一個int類型的實參,返回一個指針,該指針指向含有10個整數的數組
main函數不能重載
不允許兩個函數除了返回類型外其他所有的要素都相同,假設有兩個函數,它們的形參列表一樣但是返回類型不同,則第二個函數的聲明是錯誤的
重載函數無法區分是否頂層const但是可以區分底層const
當我們傳遞一個非常量對象或者指向非常量的對象的指針時,編譯器會優先選用非常量版本的函數
C++語言中,名字查找發生在類型檢查之前
一旦某個形參被賦予了默認值,它後面的所有形參都必須有默認值
關於形參賦予默認值,函數後續聲明即在此聲明只能為之前那些沒有默認值的形參添加默認實參,而且該形參右側的所有形參必須都有默認值
局部變量隱藏外層變量不能傳遞給函數的默認實參
內聯說明只是向編譯器發出的一個請求,編譯器可以選擇忽略這個請求
constexpr函數的返回類型及所有形參的類型都得是字面值類型,而且函數體中必須有且只有一條return語句
constexpr函數不一定返回常量表達式
在指向不同函數類型的指針間不存在轉換規則
函數指針的返回類型需要跟函數的類型以及形參的類型一致才能進行賦值
decltype作用於某個函數時,它返回函數類型而非指針類型
類定義最後需要加上分號
定義在類內部的函數是隱式的inline函數
盡管所有成員都必須在類的內部聲明,但是成員函數體可以定義在類內也可以定義在類外
this是一個常量指針
->類似於用在加入p是一個指針指向對象a,而a中存在變量b,則可以利用p->b來調用b,類似於(*p).b
默認情況下,this的類型是指向類類型非常量版本的常量指針
編譯器分兩步處理類:首先編譯成員的聲明,然後才輪到成員函數體(如果有的話)。
一般來說非成員函數時接口的組成部分,則這些函數的聲明應該與類在同一個頭文件內
IO類屬於不能被拷貝的類型,所以我們只能通過引用來傳遞他們
執行輸出任務的函數應該盡量減少對格式的控制
構造函數不能被聲明成const的,當我們創建類的一個const對象時,直到構造函數完成初始化過程,對象才能真正取得其“常量”屬性。因此,構造函數再const對象的構造過程中可以向其寫值
如果類包含有內置類型或者復合類型的成員,則只有當這些成員全都被賦予了類內的初始值時,這個類才適合於使用合成的默認構造函數
當我們創建類的一個const對象時,直到構造函數完成初始化過程,對象才能真正取得其“常量”屬性
如果=default在類的內部,則默認是內聯的;如果它在類的外部,則該成員默認情況下不是內聯的
構造函數不應該輕易覆蓋掉類內的初始值,除非新賦的值與原值不同。如果你不能使用類內初始值,則所有構造函數都應該顯示地初始化每個內置類型的成員
如果我們使用struct關鍵字,則定義在第一個訪問說明符之前的成員是public的;相反,如果我們使用class關鍵字,則這些成員是private的
使用class和struct定義類唯一的區別就是默認的訪問權限
在類中,用來定義類型的成員必須先定義後使用,因此,類型成員通常出現在類開始的地方
類內初始值必須使用=的初始化形式或者花括號括起來的直接初始化形式
我們希望能修改類的某個數據成員,即使是在一個const成員函數內。可以通過在變量的聲明中加入mutable關鍵字做到這一點P245
非常量版本的函數對於常量對象是不可用的
友元聲明的作用使影響訪問權限,它本身並非普通意義上的聲明
在類中,如果成員使用了外層作用域中的某個名字,而該名字代表一種類型,則類不能再之後重新定義該名字,即使重新定義是一樣的也是錯誤的
explicit關鍵字只允許出現在類內的構造函數聲明出
不能將explicit構造函數用於拷貝形式的初始化過程(Sale_data A = null_book),即使用直接初始化(Sale_data A(null_book))
靜態成員函數不能聲明成const的,而且我們也不能在static函數體內使用this指針
當在類的外部定義靜態成員時,不能重復static關鍵字,該關鍵字只出現在類內部的聲明語句
靜態數據成員定義在任何函數之外,一旦它被定義,就一直存在於程序的整個生命周期中
即使一個常量靜態數據成員在類內部被初始化了,通常情況下也應該在類的外部定義一下該成員
不能通過類名來調用類的非靜態成員函數
靜態成員函數中不能引用非靜態成員(因為靜態成員函數屬於整個類,在類實例化對象之前就已經分配空間了,而類的非靜態成員必須在類實例化對象後才有內存空間)
類的靜態成員變量必須先初始化再使用
std::flush刷新緩沖區;std::ends先輸出一個空字符,然後刷新緩沖區
unitbuf操作符使接下來的每次寫操作之後都進行一次flush操作(cout<
如果程序崩潰,輸出緩沖區不會被刷新
保留被ofstream打開的文件中已有數據的唯一方法是顯式指定app或in模式
forward_list迭代器不支持遞減運算符
assign操作不適用於關聯容器
賦值相關運算會導致指向左邊容器內部的迭代器、引用和指針失效。而swap操作將容器內容交換不會導致指向容器的迭代器、引用和指針失效(容器類型為array和string的情況除外)
對一個string調用swap會導致迭代器、引用和指針失效
swap兩個array會真正交換它們的元素。因此,交換兩個array所需的時間與array中元素的數目成正比
向一個vector、string或deque插入元素會使所有指向容器的迭代器、引用和指針失效
vector不支持push_front
at和下標操作只適用於string、vector、deque和array,back不適用於forward_list
不能遞減forward_list迭代器
對一個空容器調用front和back,就像使用一個越界的下標一樣,是一種嚴重的程序設計錯誤
forward_list不支持pop_back;vector和string不支持pop_front
刪除deque中除首尾位置之外的任何元素都會使所有迭代器、引用和指針失效。指向vector或string中刪除點之後位置的迭代器、引用和指針都會失效
刪除元素的成員函數並不檢查其參數。在刪除元素之前,程序員必須確保它是存在的
string搜索函數返回string::size_type值,該類型是一個unsigned類型。因此,用一個int或其他帶符號類型來保存這些函數的返回值不是一個好主意
每一個適配器都定義兩個構造函數
默認情況下,stack和queue是基於deque實現的,priority_uqeue是在vector之上實現的
所有適配器都要求容器具有添加和刪除元素的能力
算法用於不會改變底層容器大小
謂詞是一個可調用的表達式,其返回結果是一個能用作條件的值
分別用sort和stable_sort排序x,你會發現sort之後,相等的x的順序和原始順序可能發生變化,而stable_sort保證相同的一定是原始順序
使用類形參的時候申明成const
如果要對類使用==或者<、>得使用operator對類函數進行重載(例:bool operator==(Person const &p1,Person const &p2))
一個almbda只有在其捕獲列表中捕獲一個它所在函數中的局部變量,才能在函數體中使用該變量
捕獲列表只用於局部非static變量,lambda可以直接使用局部static變量和在它所在函數之外聲明的名字
lambda中采用值捕獲的前提是變量可以拷貝
被捕獲的變量的值是在lambda創建時拷貝,而不是調用時拷貝
由於被捕獲變量的值是在lambda創建時拷貝,因此隨後對其修改不會影響到lambda內對應的值
當以引用方式捕獲一個變量時,必須保證在lambda執行時變量時存在的
如果可能的話,應該避免捕獲指針或引用
&告訴編譯器采用捕獲引用方式,=則表示采用值捕獲方式
當我們混合使用隱式捕獲和顯式捕獲時,捕獲列表中的第一個元素必須是一個&或=。
當混合使用隱式捕獲和顯式捕獲時,顯式捕獲的變量必須使用與隱式捕獲不同的方式。
如果我們希望能改變一個被捕獲的變量的值,就必須在參數列表首加上關鍵字mutable
名字_n都定義在一個placeholders的命名空間中(例:using namespace std::placeholders)
使用bind遇到引用或者const類型的可以使用ref和cref函數(P357)
使用bind的形參都是使用的拷貝,若遇到引用則需要用到函數ref,函數ref返回一個對象,包含給定的引用,此對象是可以拷貝的,還有一個cref函數,生成一個保存const引用的類。
unique函數支持剔除相鄰之間字符重復的
除了forward_list之外的標准庫容器都有反向迭代器
對於一個綁定到流的迭代器,一旦其關聯的流遇到文件尾或遇到IO錯誤,迭代器的值就與尾後迭代器相等
accumulate函數中序列的迭代器類型需要是const類型的
流迭代器不支持遞減運算
將反向迭代器轉換成正向迭代器使用reverse_iterator中的base成員函數
一個高層類別的迭代器支持底層類別迭代器的所有操作
對於向一個算法傳遞錯誤類別的迭代器的問題,很多編譯器不會給出任何警告或提示
向輸入迭代器寫入數據的算法都假定目標空間足夠容納寫入的數據
關聯容器不支持順序容器的位置先關的操作,關聯容器也不支持構造函數或插入操作這些接受一個元素值和一個數量值的操作
關聯容器的迭代器都是雙向的
pair的構造函數對數據成員進行值初始化
當解引用一個關聯容器迭代器時,我們會得到一個類型為容器的value_type的值的引用
一個map的value_type是一個pair,我們可以改變pair的值,但不能改變關鍵字成員的值
通常不對關聯容器使用泛型算法
當對一個map進行下標操作時,會獲得一個mapped_type對象;但當解引用一個map迭代器時,會得到一個value_type對象
對動態分配的對象進行值初始化,只需在類型名之後跟一對空括號
如果我們提供了一個括號包圍的初始化器,就可以使用auto,只有當括號中僅有單一初始化器時才可以使用auto
默認情況下,如果new不能分配所要求的內存空間,它會拋出一個類型為bad_alloc的異常,如果要阻止異常的發生->(int *p2 = new( nothrow ) int ; //如果分配失敗,new返回一個空指針)
空懸指針:指向一塊曾經保存數據對象但現在已經無效的內存的指針
使用一個內置指針來訪問一個智能指針所負責的對象是很危險的,因為我們無法知道對象何時會被銷毀
永遠不要用get初始化另一個智能指針或者為另一個智能指針賦值(P414)
當我們定義一個unique_ptr時,需要將其綁定到一個new返回的指針上,初始化unique_ptr必須采用直接初始化形式
unique_ptr不支持普通的拷貝或賦值操作
auto_ptr具有unique_ptr的部分特性,我們不能再容器中保存auto_ptr,也不能從函數中返回auto_ptr
動態數組並不是數組類型
關於動態數組,如果我們在delete一個數組指針時忘記了方括號,或者在delete一個單一對象的指針時使用了方括號,編譯器很可能不會給出警告。我們的程序可能在執行過程中再沒有任何警告的情況下行為異常。
vector接收單一大小參數的構造函數是explicit
拷貝構造函數的第一個參數必須是一個引用類型