1.迭代器
所有標準庫容器都可以使用迭代器,但只有少數容器可以使用下標。
auto b=v.begin(),c=v.endl();//如果容器空,則be都指向尾後迭代器
迭代器支援的運算子,*iter iter->成員,++,--,==,!=//大多數不支援<
vector::iterator iter;
string::iterator it2;//iter可讀寫元素
vector::const_iterator it;
string::const_iterator it3;//iter不可讀寫元素
【使用了迭代器的迴圈體或範圍for的迴圈體都不要向所屬的容器新增元素】
支援的運算子+,-,+=,-=,>=,<=,>,<
2.陣列
定義時要指定長度
string s[get_size()];//當get_size()是constexpr時正確,否則錯誤
constexpr sz=42;
int *parr[sz];//含有42個整型指標的陣列
字元陣列的特殊性char a1=;//含有顯式空字元,沒有的話是隱式
【陣列不支援拷貝和賦值】
int *(&array)[10]=ptrd;//【由內向外解讀】,array是乙個引用,引用的物件是乙個大小為10的陣列
3.指標和陣列
string nums=;
string *p=nums;//與string *p=nums[0]等價,在很多用到陣列名字的地方,編譯器都會自動地將其替換為乙個指向陣列首元素的指標
int a=;
auto ia2(a);//相當於auto ia2(&a[0]),所以ia2的型別是乙個指標int*,指標也是迭代器
標準庫begin()和end()函式:int *beg=begin(a);//兩個指標相減是它們的距離,即元素數
使用陣列初始化vector物件 vectoriv(begin(a),end(a));//將a的元素全部賦給iv
vectoriv(a+1,a+4);//將a[1],a[2],a[3]賦給iv
4.多維陣列是陣列的陣列
【適用範圍for語句處理多維陣列,除了最內層的迴圈外,其他所有迴圈的控制變數都應該是引用型別】
int ia[3][4];
for(auto &row:ia)//對於外層陣列的每乙個元素,要用引用型別的迴圈變數
for(auto &col:row)
int (*p)[4]=ia;//p指向含有4個整數的陣列
可以適當使用型別別名是程式簡潔明瞭
typedef int int_array[4]
for(int_arrat *p=ia;p!=ia+3;p++)//外層迴圈
5.表示式
拿不準的時候盡量使用括號來確定優先順序
若改變了某個運算物件的值,在表示式的其他地方盡量不要再使用該物件
【bool型別不應該參與運算】bool b=true; bool b2=-b;//b2的值還是true!
賦值運算滿足右結合律,由右至左
a op=b;<==>a=a op b;
op->mem;<==>(*op).men;
移位運算子滿足左結合律
sizeof運算子滿足右結合律,不實際計算運算物件的值,返回表示式結果型別的大小
6.隱式型別轉換
在以下情況,編譯器自動進行型別轉換:大多數表示式中,比int型別小的整型值首先提公升為較大的整數型別/在條件中非bool值轉化為bool型別/初始話過程中初始值轉化為變數型別,賦值語句中右側運算物件轉換成左側運算物件型別/若算術運算或者關係運算的運算物件有多種型別,需要轉換為同一種型別/函式呼叫時
7.顯示型別轉換
使用const_cast去掉常量屬性
cast-name(expression);//當type是轉換的目標型別時expression是要轉換的值
//當type是引用型別時,結果是左值。【】
double slope=static_cast(j)/i;//進行強制型別轉換以便執行浮點數除法,int i,j;
8.switch語句
多個case標籤可以對應乙個語句:只用乙個break語句
switch(ch)
9.範圍for語句
for(auto &r:v)//對於v中的每乙個元素【範圍變數必須是引用型別】
10.異常處理
throw runtime_error(" ");
trycatch(異常宣告1)
catch(異常宣告2)
當程式在丟擲異常前已經經歷了多個try語句塊時,尋找處理**的過程與函式呼叫的過程剛好相反
標準異常有runtime_error執行時才有的異常 range_error執行時錯誤:生成的結果超出範圍
overflow_error執行時異常計算上溢 underflow_error執行時異常計算下溢
logic_flow程式邏輯錯誤 domain_error程式邏輯錯誤引數對應的結果不存在
invalid_argument邏輯錯誤:無效引數 length_error邏輯錯誤:試圖建立乙個超出該型別最大長度的物件
out_of_range邏輯錯誤,使用乙個超出有效範圍的值
11.函式呼叫
static變數在函式呼叫結束後依然有效
函式宣告也叫做函式原型
分離式編譯,如果修改了其中乙個原始檔那麼只需要重新編譯該檔案就可以
如果形參是引用型別,它將繫結到對應的實參上,否則將實參的值拷貝後賦給形參。【建議使用引用型別的形參代替指標】
有些型別不支援拷貝操作,可以用引用訪問,引用形參為一次返回多個結果提供了可能。
void fcn(const int i); 【fcn可以讀取但不能寫入i】
void fcn(int i);【錯誤,重複定義】
在定義函式形參和變數時將不會改變的型別定義位const
void print(const int[10]) //這裡的維度表示我們期望陣列含有多少個元素實際上不一定
防止陣列越界有三種常用技術:1使用標記指定陣列長度while(*cp) //cp不是空
2.使用標準庫規範 while(beg!=end)
3.顯式地傳遞乙個表示陣列長度地形參
main處理命令列選項
int main(int argc,char *ar**){}
或者int main(int argc,char **ar**){} //第乙個引數是陣列中字串的數量,第二個引數是字串陣列,當使用ar**中的實參時 要記得可選的實參從ar**[1]開始,ar**[0]儲存程式的名字
省略符形參initializer_list[定義在同名的檔案中]形參可以傳遞型別相同數量可變數量的形參,但是這種功能一般只用於與c函式互動的介面程式。大多數類型別的物件在傳遞給省略符形參時都無法正確拷貝。
eg:錯誤輸出函式
void error_msg(initializer_listil,int i)
【內聯機制用於優化規模較小流程直接頻繁呼叫的函式,內聯只是向編譯器發出的乙個請求,編譯器可以選擇忽略】
constexpr函式只能用於常量表示式的函式:函式的返回型別及所有形參的型別都必須是字面值型別比如 return 42;允許constexpr函式的返回值並非乙個常量,常量表示式也可以foo(2)ok,foo(i)不可
【內聯函式和constexpr函式通常定義在標頭檔案中】
13.assert巨集和ndebug預處理
#include
assert(表示式);//不需要using或者std::
如果定義了ndebug不會執行執行時檢查,此時arrset什麼也不做,可以輔助除錯
14.函式指標
要想宣告乙個可以指向某函式的函式指標,只需要用指標替換函式名即可
bool (*pf)(const string &,const string &);//【*pf兩端的括號不可省,沒有括號會被認為是bool*型別的函式】
pf=lengthcompare;//pf指向名為lengthcompare的函式,形參型別要匹配·
pf=&lengthcompare;//與上句等價,&是可選的
此外還可以直接使用指向函式的指標呼叫該函式,無需提前解引用指標,一下三個呼叫是等價的
bool b1=pf("he","gb");
bool b2=(*pf)("he","gb");
bool b3=lengthcompare("he","gb");
pf=0;//該指標未指向任意乙個函式
函式指標也可以作為另乙個函式的形參或者返回值,如果形參是函式名,會自動轉換為函式指標
c primer 讀書筆記三
2.2.2宣告和定義的關係 宣告使得名字為程式所知,乙個檔案如果想使用別處的定義的名字則必須包含對名字的宣告,而定義則負責建立與名字相聯的實體 extern int i 宣告而非定義 int i 宣告並且定義j 初始化的宣告等於定義 變數能被定義一次,但可以被多次宣告2.2.4名字的作用域 巢狀得的...
C primer 讀書筆記
第2 章 變數和基本型別 1 變數直接初始化和變數 複製初始化 int ival 1024 direct initialization int ival 1024 copy initialization 初始化不是賦值 2 內建型別復 制初始化和直接初始化幾乎沒有區別 但 對類型別物件來 說,有些初...
C Primer讀書筆記
前些日子開始看 c primer 順便做一些筆記,既有書上的,也有自己理解的。因為剛學c 不久,筆下難免有謬誤之處,行文更是凌亂 所幸不是用來顯配的東西,發在linuxsir只是為了方便自己閱讀記憶,以防只顧上網忘了正事。書看了不到一半,所以大約才寫了一半,慢慢補充。const要注意的問題 1 下面...