1.c++基礎(chǔ)(1)


2.變量和基本類型

c++的算術(shù)類型:

類 型 含 義 最小尺寸
bool 布爾類型 未定義
char 字符 8位
wchar_t 寬字符 16位
char16_t Unicode字符 16位
char32_t Unicode字符 32位
short 短整型 16位
int 整型 16位
long 長(zhǎng)整型 32位
long long 長(zhǎng)整型 64位
float 單精度浮點(diǎn)數(shù) 6位有效數(shù)字
double 雙精度浮點(diǎn)數(shù) 10位有效數(shù)字
long double 擴(kuò)展精度浮點(diǎn)數(shù) 10位有效數(shù)字

一個(gè)char和一個(gè)機(jī)器字節(jié)一樣斟薇,一個(gè)int至少和一個(gè)short一樣大,一個(gè)long至少和一個(gè)int一樣大加匈。

通常float以一個(gè)(32 bit)表示崖瞭,double以2個(gè)字來(lái)表示,分別有7個(gè)和16個(gè)有效位躏仇。

8位unsigned char 可以表示0到255的值,signed char可以表示-128 到 127腺办。

  • 多數(shù)平臺(tái)上int類型占32位焰手,取值范圍為-2147483648 至 2147483647

類型轉(zhuǎn)換

bool b = 42;           // b = true
int i = b;             // i = 1
i = 3.14;              // i = 3
double pi = i;         // pi = 3.0
unsigned char c = -1;  // 若char占8bit,則c = 255
signed char c2 = 256;  // 若char占8bit怀喉,c2的值是未定義的
  • 把非bool類型的算術(shù)值給bool類型時(shí)书妻,初始為0則結(jié)果為false,否則結(jié)果為true
  • 把bool類型賦值給非bool類型時(shí)躬拢,初始值為false則結(jié)果為0躲履,初始值為true則結(jié)果為1
  • 把浮點(diǎn)數(shù)賦值給整型時(shí),只保留整數(shù)部分
  • 整數(shù)給浮點(diǎn)數(shù)時(shí)估灿,小數(shù)部分記0
  • 給無(wú)符號(hào)類型一個(gè)超出其表示范圍的值時(shí)崇呵,結(jié)果的初始值對(duì)無(wú)符號(hào)類型表示數(shù)值總數(shù)取模后的余數(shù),例如給8bit的unsigned char(可以表示0到255)賦值-1馅袁,結(jié)果為-1%256=255
  • 給帶符號(hào)的類型賦值一個(gè)超出它表示范圍的值時(shí)域慷,結(jié)果是未定義(undefined)的,可能會(huì)出錯(cuò)

注意! 帶符號(hào)數(shù)與無(wú)符號(hào)數(shù)運(yùn)算時(shí)犹褒,會(huì)被轉(zhuǎn)化為unsigned抵窒,int a = -1可能會(huì)變成4294967295,切勿混用unsigned類型和signed類型叠骑!

字面值

O開(kāi)頭的數(shù)代表八進(jìn)制數(shù)李皇,0x開(kāi)頭的數(shù)表示十六進(jìn)制,例如整數(shù)20:

20   // 十進(jìn)制
O24  // 八進(jìn)制
0x14 // 十六進(jìn)制

一般復(fù)數(shù)的那個(gè)負(fù)號(hào)不會(huì)存儲(chǔ)在字面值內(nèi)宙枷,作用僅僅是對(duì)字面值取負(fù)

轉(zhuǎn)義序列:

:-:|:-:|:-:
換行符 \n| 橫向制表符 \t |報(bào)警符 \a
縱向制表符 \v| 退格符 \b| 雙引號(hào) "
反斜線\ |問(wèn)號(hào) ? |單引號(hào)'
回車符 \r |進(jìn)紙符 \f|

也可以通過(guò)添加前后綴來(lái)指定字面值的類型:

對(duì)于字符有:

前綴 含義 類型
u Unicode 16字符 char16_t
U Unicode 32字符 char32_t
L 寬字符 wchar_t
u8 UTF-8(僅用于字符串字面值常量) char

對(duì)于整型和浮點(diǎn)型有:

后綴 類型
u or U unsigned
l or L long
ll or LL long long
f or F float
l or L long double

變量

變量定義的基本形式:

類型說(shuō)明符 + 一個(gè)或多個(gè)變量名組成的列表(以逗號(hào)分隔掉房,分號(hào)結(jié)束)

  • 何為對(duì)象

    對(duì)象(object)是指一塊能存儲(chǔ)數(shù)據(jù)并具有某種類型的內(nèi)存空間

  • 對(duì)象初始化

    當(dāng)對(duì)象在創(chuàng)建時(shí)獲得了一個(gè)特定的值慰丛,那么這個(gè)對(duì)象被初始化了卓囚,在同一條語(yǔ)句中可以用先定義的變量值去初始化后定義的變量。

      double price = 100.1诅病, discount = price * 0.16;
    

    注意初始化不是賦值哪亿!初始化=創(chuàng)建變量的同時(shí)賦予其一個(gè)初值,賦值=擦除對(duì)象的當(dāng)前值以一個(gè)新的值來(lái)代替贤笆。

  • 默認(rèn)初始化

    變量將被初始化為默認(rèn)值蝇棉,也有可能定義在函數(shù)體內(nèi)部的內(nèi)置類型變量不被初始化

    建議初始化每一個(gè)內(nèi)置類型的變量!

聲明和定義的關(guān)系 *

c++采用分離式編譯機(jī)制芥永,允許將程序分割為若干個(gè)文件篡殷,每個(gè)文件可以被獨(dú)立編譯

為了支持分離式編譯,c++將聲明和定義區(qū)分開(kāi)

聲明(declaration)使名字為程序所知

定義(definition)負(fù)責(zé)創(chuàng)建與名字關(guān)聯(lián)的實(shí)體

變量聲明規(guī)定了變量的類型和名字恤左,定義在這方面也與之相同贴唇。但是定義還申請(qǐng)存儲(chǔ)空間,也可能會(huì)為變量賦一個(gè)初值飞袋。

如果想聲明一個(gè)變量而非定義它,需要用到extern關(guān)鍵字链患,而且不要顯示初始化變量。任何包含了顯示初始化的聲明即成為定義!并且變量只能被定義一次坠非,可以被多次聲明兼蕊。

extern int i;     //聲明 i 而非定義 i
int j;            //聲明并定義 j
extern int k = 1;//定義 k

贸毕!如果要在多個(gè)文件中使用同一個(gè)變量郑叠,就必須把聲明和定義分離。此時(shí)明棍,變量的定義必須出現(xiàn)在且只能出現(xiàn)在一個(gè)文件中乡革,而其他用到該變量的文件必須對(duì)其進(jìn)行聲明,不能重復(fù)定義。

  • c++是一種靜態(tài)類型語(yǔ)言沸版,其含義是在編譯階段檢查類型嘁傀。其中檢查類型的過(guò)程稱為類型檢查。我們?cè)谑褂媚硞€(gè)變量前必須聲明其類型视粮。

標(biāo)識(shí)符

由字母细办、數(shù)字、下劃線組成蕾殴。必須以字母和下劃線開(kāi)頭笑撞。

int somename, someName, SomeName, SOMENAME;

并且還有一些保留字。用戶自定義的標(biāo)識(shí)符中不能出現(xiàn)連續(xù)兩個(gè)下劃線钓觉,也不能以下劃線加大寫字母開(kāi)頭娃殖。定義在函數(shù)體外的標(biāo)識(shí)符不能以下劃線開(kāi)頭。

int _ = 1; //是正確的

名字的作用域

作用域以花括號(hào)分隔议谷。

定義在函數(shù)體之外的名字具有全局作用域炉爆,例如main。

相對(duì)的塊作用域

復(fù)合類型

基本數(shù)據(jù)類型 + 類型修飾符 + 變量名

int i = 1024, *p = &i, &r = i;

最好把類型修飾符和變量名寫在一起

  • 引用(左值引用)

    引用即別名卧晓, 引用必須被初始化

  • 指針

    定義多個(gè)指針時(shí)芬首,必須每個(gè)變量前面都有符號(hào) *

    指針存放某個(gè)對(duì)象的地址,要想獲取該地址逼裆,要使用取地址符(&)

      double dval;
      double *pd = &dval;
      double *pd2 = pd;
    
      int *pi = pd; //錯(cuò)誤郁稍,指針pi的類型和pd不匹配
      pi = &dval;   //錯(cuò)誤,指針pi的類型和dval不匹配
    

    通過(guò)解引用符(*)來(lái)得到指針?biāo)傅膶?duì)象胜宇。

    耀怜!對(duì)于符號(hào)(*, &),在定義時(shí)桐愉,作為聲明的一部分财破;同時(shí)也可以作為解引用符和取地址符。

    生成一個(gè)空指針

      int *p1 = nullptr;
      int *p2 = 0;
      int *p3 = NULL;
    

    建議初始化所有指針从诲!

    把指針用于條件表達(dá)式時(shí)左痢,任何非0指針的條件值都是true。

  • void * 指針

    可以用于存放任意對(duì)象的地址系洛,但也只能存儲(chǔ)地址俊性,不能訪問(wèn)內(nèi)存空間中的對(duì)象。

  • 指向指針的指針

    可以有指向指針的指針的...指針

  • 指向指針的引用

    相當(dāng)于對(duì)指針的引用

      int i = 42;
      int *p;
      int *&r = p;   // r 是對(duì)指針 p 的引用
    

    要理解 *&r 到底是什么描扯,應(yīng)該從右往左看類型修飾符定页,距離r最近的符號(hào)是&,那么r就是一個(gè)引用绽诚。其余的符號(hào)確定r引用的類型是什么典徊,符號(hào)*說(shuō)明r引用的是一個(gè)指針杭煎。最后int類型說(shuō)明r引用的是一個(gè)int類型的指針。

    從右往左看宫峦,很重要岔帽!

const限定符

const類型的對(duì)象一旦創(chuàng)建后其值就不能再改變,所以const對(duì)象必須初始化导绷。

可以用const對(duì)象去初始化其他對(duì)象犀勒,因?yàn)槌跏蓟僮鞑粫?huì)改變本身的值,只是拷貝了值妥曲。

int i = 42;
const int ci = i;
int j = ci;

贾费! 默認(rèn)狀態(tài)下const對(duì)象僅在文件內(nèi)有效,因?yàn)樵诰幾g過(guò)程中檐盟,會(huì)把會(huì)用到該變量的地方都替換成對(duì)應(yīng)的值褂萧。

當(dāng)在多個(gè)文件中,出現(xiàn)同名的const變量時(shí)葵萎,等同于在不同文件中分別定義了不同的變量导犹,都需要進(jìn)行初始化。

如果在多個(gè)文件中羡忘,都要用到同一個(gè)值的const變量谎痢,而且這一變量的初始值不是一個(gè)常量表達(dá)式,又確實(shí)有必要在文件間共享卷雕。一個(gè)解決辦法就是节猿,對(duì)于 const 變量不管聲明還是定義都添加 extern 關(guān)鍵字,這樣就只需要定義一次就夠了漫雕。

// file_1.cc中定義并初始化一個(gè)常量
extern cosnt int bufSize = fcn();
// file_1.h頭文件
extern cosnt int bufSize;

const的引用

稱為對(duì)常量的引用滨嘱,也不能修改它所綁定的對(duì)象。

const int ci = 100;
const int &r1 = ci;  //正確
r1 = 42;             //錯(cuò)誤浸间,不能修改const對(duì)象
int &r2 = ci;        //錯(cuò)誤太雨,試圖讓一個(gè)非常量引用指向一個(gè)常量對(duì)象

嚴(yán)格來(lái)講并不存在常量引用。

對(duì)const的引用可能引用一個(gè)并非const的對(duì)象发框。

int i = 42;
int &r1 = i;
const int &r2 = i; //r2綁定對(duì)象i躺彬,但是不允許通過(guò)r2修改i的值
r1 = 0;   // 通過(guò)r1改變了i的值,同時(shí)會(huì)引起r2的改變

r2 綁定非常量整數(shù) i 是合法的行為梅惯。

指針和const

要想存放常量對(duì)象的地址,只能用指向常量的指針仿野,也不能賦值铣减。

const double pi = 3.14159;
const double *ptr = π

同時(shí)指向常量的指針也能指向一個(gè)非常量。所謂指向常量的指針脚作,只是不能通過(guò)這個(gè)指針來(lái)改變對(duì)象的值葫哗,但是沒(méi)有規(guī)定那個(gè)對(duì)象的值不能通過(guò)其他途徑改變缔刹。

const指針

允許把指針本身定為常量,常量指針必須初始化劣针,而且一旦初始化完成它的值(存放的地址)就不能再改變了校镐。

int errNumb = 0;
int *const curErr = &errNumb;   //curErr一直指向errNumb
const double pi = 3.14159;
const double *const pip = *pi;  //指向常量對(duì)象的一個(gè)常量指針

指針本身是個(gè)常量,可以改變它指向的對(duì)象的值捺典!

頂層const

頂層const 表示指針本身是個(gè)常量

底層const 表示指針?biāo)傅膶?duì)象是個(gè)常量

指針也可以同時(shí)是底層和頂層const

int i = 0;
int *const p1 = &i;       //p1的值不能改變鸟廓,頂層const
const int ci = 42;        //ci的值不能改變,頂層const
const int *p2 = &ci;      //p2的值可以改變襟己,底層const
const int *const p3 = p2; //靠右的const是頂層引谜,靠左的cosnt是底層
const int &r = ci;        //用于聲明引用的const都是底層cosnt

在執(zhí)行拷貝操作時(shí),頂層cosnt不受影響擎浴。

另一方面员咽,拷入和拷出的對(duì)象必須具有相同的底層const資格,或兩個(gè)對(duì)象的數(shù)據(jù)類型必須能夠轉(zhuǎn)換(一般非常量可以轉(zhuǎn)換成常量)

就是說(shuō)可以用一個(gè) const int & 去綁定一個(gè)普通的int對(duì)象

類型別名

兩種方法定義類型別名:

typedef double wages;    //wages = double
typedef wages base, *p;  //base = double, p = double*

using SI = Sales_item;   //SI = Sales_item

注意不是簡(jiǎn)單的替換:

typedef char *pstring;
const pstring cstr = 0;  //cstr是指向char的**常量指針**
const pstring *ps;       //ps是一個(gè)指針贮预,它指向的對(duì)象是指向char的常量指針

但是上述語(yǔ)句不是簡(jiǎn)單的替換就行的贝室,不等于以下語(yǔ)句:

const char *cstr = 0;    //這是指向常量字符的指針,和上面的不同7峦獭;怠!

decltype

類型說(shuō)明符decltype茫藏,作用是返回操作數(shù)的數(shù)據(jù)類型(包括頂層const和引用在內(nèi))

const int ci = 0, &cj = ci;
decltype(ci) x = 0;       //正確误趴,x是一個(gè)const int類型
decltype(cj) y = x;       //正確,y是一個(gè)const int&务傲,綁定到x
decltype(cj) z;           //錯(cuò)誤凉当,z是一個(gè)const int&,必須初始化

注意decltype對(duì)括號(hào)很敏感售葡,如果decltype使用的是一個(gè)不加括號(hào)的變量看杭,得到的結(jié)果就是該變量的類型。如果給變量加上了一層括號(hào)挟伙,這個(gè)變量就變成了一個(gè)表達(dá)式楼雹,表達(dá)式是可以作為賦值語(yǔ)句左值的,因此是一個(gè)引用類型尖阔。

int i = 0;
decltype((i)) d;   //d是int&贮缅,必須初始化,報(bào)錯(cuò)
decltype(i) e;     //e是int類型

=槿础G垂!雙層括號(hào) decltype((i)) 得到的結(jié)果永遠(yuǎn)是一個(gè)引用齿坷,一層括號(hào)只有當(dāng)里面是引用的時(shí)候才是引用桂肌。

預(yù)處理器

  • 一項(xiàng)預(yù)處理功能 #include数焊,當(dāng)看到 #include 標(biāo)記時(shí),會(huì)用指定的頭文件內(nèi)容代替它崎场。

  • 頭文件保護(hù)符依賴于預(yù)處理變量佩耳,#define 把一個(gè)名字設(shè)定為預(yù)處理變量,#ifdef谭跨, #ifndef分別當(dāng)且僅當(dāng)變量已定義時(shí)干厚、未定義時(shí)為真,這兩個(gè)if直到#endif 指令為止饺蚊。

      #ifndef SALES_DATA_H
      #define SALES_DATA_H
      #include <string>
      struct Sales_data{
          ...;
      }
      #endif
    

F加铡!預(yù)處理變量無(wú)視作用域規(guī)則





3.字符串污呼、向量和數(shù)組

命名空間

使用using聲明

using namespace::name;  
//例如 using std::cin;  
      using std::endl;

作用域操作符 :: 裕坊,含義是編譯器從操作符左側(cè)名字所示的作用域中尋找右側(cè)的那個(gè)名字。例如 std::cin 就是使用命名空間 std 中的名字 cin 燕酷。

一般來(lái)說(shuō)籍凝,頭文件不應(yīng)該包含 using 聲明

標(biāo)準(zhǔn)庫(kù)類型string

#include<string>

定義和初始化:

string s1;             //默認(rèn)初始化,s1是一個(gè)空串
string s2 = s1;        //兩種拷貝初始化
string s22(s1);
string s3 = "hiya";    //s3是該字符串字面值的副本
string s33("hiya");
string s4(10, 'c');    //s4是10個(gè)字符c組成的字符串

string的操作:

os<<s               //流操作苗缩,將s寫到輸出流os中饵蒂,返回os
is>>s               //從is中讀取字符串賦給s,字符串以空白分隔酱讶,返回is
getline(is, s)      //從is中讀取一行賦給s退盯,返回is
s.empty()
s.size()            //返回字符的個(gè)數(shù)!!!!用size
s[n]                //返回第n個(gè)字符的引用
s1 + s2             //返回s1與s2連接后的結(jié)果
s1 = s2
s1 == s2
s1 != s2
<, >, <=, >=

如果使用 cin>>str 時(shí),會(huì)自動(dòng)忽略開(kāi)頭的空白(空格泻肯,換行渊迁,制表符等),從第一個(gè)真正字符開(kāi)始灶挟,直到遇見(jiàn)下一個(gè)空白為止琉朽。!稚铣!以空格為分界O淙!

例如輸入" Hello world "惕医,會(huì)得到"Hello"

讀取未知數(shù)量的string對(duì)象:

string word;
while(cin >> word){
    cout << word << endl;
}

讀取一整行:

string line;
while(getline(cin, line)){
    cout << line << endl;
}

getline 得到的一行中不包括換行符耕漱,得手動(dòng)加上 endl。 觸發(fā)getline函數(shù)返回的那個(gè)換行符實(shí)際被丟掉了抬伺。

  • size()函數(shù)返回的是一個(gè) size_type 類型孤个,無(wú)符號(hào)數(shù)!

    E婕颉F肜稹!注意椒楣,如果表達(dá)式中已經(jīng)有了 size() 類型给郊,就不要用帶符號(hào)的 int 類型了,否則會(huì)轉(zhuǎn)化成無(wú)符號(hào)數(shù)產(chǎn)生意想不到的后果捧灰。

    或者可以:

      auto len = line.size(); 
    

string 的大小比較是對(duì)字典序進(jìn)行比較淆九,對(duì)大小寫敏感,'A' = 65, 'a' = 97

當(dāng)把字符串和字面值相加時(shí)毛俏,必須保證每個(gè) '+' 兩側(cè)至少有一個(gè)是 string 類型炭庙! 字符串字面值string 是兩種不同的類型!;涂堋焕蹄!

  • 處理 string 中的字符

    使用cctype頭文件

      isalnum(c) //是字母或數(shù)字
      isalpha(c) //是字母
      iscntrl(c) //是控制字符
      isdigit(c) //是數(shù)字
      islower(c) //是小寫字母
      isupper(c) //是大寫字母
      ispunct(c) //是標(biāo)點(diǎn)符號(hào)
      ...
      tolower(c)
      toupper(c)
    
  • c++ 版本的C標(biāo)準(zhǔn)庫(kù)頭文件

    c語(yǔ)言的頭文件形如 name.h ,而c++則將這些名字去掉了 .h 阀溶,相應(yīng)的增加了 c 字母前綴腻脏,變成 cname 。 例如:

      #include <cmath>
      #include <cctype>
    
  • 處理字符

    c++11 新的范圍for語(yǔ)句:

      for (declaration : expression)
          statement;
    
      for (auto c : str)
          cout<< c <<endl;
    
      for (auto &c : str)  // 如果要修改字符银锻,必須要引用
          c = toupper(c);
    

    下標(biāo)操作([ ]):

    第一個(gè)字符 s[0] , 最后一個(gè)字符 s[s.size() - 1]

    e.g. 把字符串 s 的第一個(gè)詞改成大寫形式:

      for(decltype(s.size()) index = 0; index != s.size() && !isspace(s[index]); ++index)
          s[index] = toupper(s[index]);
    
      //s = "some string", 結(jié)果s = "SOME string"
    
  • reverse() 函數(shù)

    c++中永品, reverse() 函數(shù)是在 <algorithm> 中定義的,用于反轉(zhuǎn)在 [first,last) 范圍內(nèi)的順序击纬。

    可以用于反轉(zhuǎn) vector 類型鼎姐,或者 string 類型等。

      vector<int> v={1,2,3,4,5};
      reverse(v.begin(),v.end());//v的值為5更振,4炕桨,3,2殃饿,1
    
      string str="C++REVERSE";
      reverse(str.begin(),str.end());//str結(jié)果為ESREVER++C
    

標(biāo)準(zhǔn)庫(kù)類型 vector

vector(向量)谋作,有時(shí)也被稱為容器(container)。vector 實(shí)際是一個(gè)類模板乎芳,編譯器根據(jù)模板創(chuàng)建類或者函數(shù)的過(guò)程稱為實(shí)例化遵蚜,通過(guò)在模板名字后加上尖括號(hào),在尖括號(hào)內(nèi)填放信息奈惑。

vector<int> ivec;
vector<Sales_item> Sales_vec;
vector<vector<string>> file; // 在早期版本中吭净,要在后面的兩個(gè)>>中加上一個(gè)空格,寫成下列形式:
vector<vector<string> > file;

初始化:

vector<T> v1;
vector<T> v2(v1);
vector<T> v2 = v1;
vector<T> v3(n, val);
vector<T> v4(n); // v4包含了n個(gè)重復(fù)地執(zhí)行了值初始化的對(duì)象
vector<T> v5{a, b, c...};  //列表初始化
vector<T> v5 = {a, b, c...};  //效果同上肴甸,這是c++11的新標(biāo)準(zhǔn)

可以進(jìn)行默認(rèn)初始化寂殉,不含任何元素。

在進(jìn)行值初始化時(shí)原在,可以不加值具體是什么友扰,只寫入數(shù)字彤叉,例如 vector<T> v4(n)

當(dāng)使用的模板是 int 時(shí),元素初值自動(dòng)設(shè)為0村怪。

;嘟健!注意使用花括號(hào)和圓括號(hào)甚负,這兩個(gè)影響非常大柬焕。花括號(hào)是進(jìn)行列表初始化梭域,圓括號(hào)是按提供的 (n, val) 來(lái)構(gòu)造 vector 對(duì)象斑举。

  • 添加元素

    push_back(..) 把元素添加到尾端

    !病涨!注意富玷,雖然vector對(duì)象能高效增長(zhǎng),定義vector對(duì)象的時(shí)候設(shè)定其大小也就沒(méi)什么必要了没宾,但事實(shí)上這么做性能可能更差凌彬!

    在創(chuàng)建vector時(shí),預(yù)先設(shè)定其容量是最好的循衰。

    2病! 范圍for語(yǔ)句體內(nèi)不應(yīng)改變其所遍歷的序列的大小会钝,不能在里面對(duì)vector進(jìn)行添加元素等操作伐蒋。

  • 對(duì)vector的操作

      v.empty()
      v.size()   // 返回vector中的元素個(gè)數(shù),size和empty操作和string類的一樣
      v.push_back(t)
      v[n]
      v1 = v2 
      v1 = {a, b, c, ...}   //同列表中的元素拷貝替換v1中的元素
      v1 == v2
      v1 != v2
      <, <=, >, >=     //按**字典序**進(jìn)行比較
    

    size() 返回的是由 vector 定義的 size_type 類型迁酸,注意要使用

      vector<int>::size_type  // 正確
      vector::size_type       // 錯(cuò)誤先鱼,要指定類型
    

    只能對(duì)確知已存在的元素執(zhí)行下標(biāo)操作!

迭代器

所有標(biāo)準(zhǔn)庫(kù)容器都可以使用迭代器訪問(wèn)奸鬓,但是只有少數(shù)才同時(shí)支持下標(biāo)運(yùn)算符焙畔。string和vector都同時(shí)支持這兩種訪問(wèn)方式。

嚴(yán)格來(lái)講string不屬于容器類型串远,但是很多容器類型的操作string都支持宏多。

獲取迭代器使用 begin 和 end 成員。 其中 begin 指向第一個(gè)元素澡罚,end 表示尾元素的下一個(gè)元素的位置伸但,如果為空,則有 begin == end留搔。 end 稱為尾后迭代器更胖,簡(jiǎn)稱尾迭代器

  • 迭代器的運(yùn)算符(類似于指針):

      *iter
      iter->mem   //解引用 iter 并獲取該元素的名為 mem 的成員,等價(jià)于 (*iter).mem
      ++iter
      --iter
      iter1 == iter2
      iter1 != iter2
    

    盡量習(xí)慣使用迭代器以及!=運(yùn)算符却妨,不是所有的標(biāo)準(zhǔn)庫(kù)容器都支持<運(yùn)算的饵逐,但是都支持迭代器和!=操作。

  • 迭代器類型:

    那些擁有迭代器的標(biāo)準(zhǔn)庫(kù)類型使用 iterator 和 const_iterator 來(lái)表示迭代器的類型管呵。

      vector<int>::iterator it;
      string::iterator it2;
          
      vector<int>::const_iterator it3;  // it3 只能讀取元素梳毙,不能寫元素
      string::const_iterator it4;       // it4 只能讀取元素,不能寫元素
    

    const_iterator 類型和常量指針差不多捐下,能讀取但不能修改它所指的元素值。

    如果 vector 對(duì)象或 string 對(duì)象是一個(gè)常量萌业,只能使用 const_iterator 坷襟。

    !生年! 對(duì)于常量的容器類型婴程,begin 和 end 運(yùn)算符得到的是一個(gè) const_iterator ,要用對(duì)應(yīng)的 const_iterator 接住抱婉。如果一定要從非常量容器中得到常量迭代器档叔,可以使用 cbegincend 這兩個(gè)運(yùn)算符。

  • 箭頭運(yùn)算符 ->

    it -> mem 的含義是 (*it).mem 包含了對(duì) it 進(jìn)行解引用蒸绩,以及點(diǎn)運(yùn)算符衙四。

    例如一個(gè) vector<string> 類型的 text ,用迭代器訪問(wèn)遍歷 text患亿,直到遇到空白字符串為止:

      for(auto it = text.cbegin(); it != text.cend() && !it -> empty(); ++it)
          cout << *it << endl;
    

    其中 !it -> empty() 等價(jià)于 !(*it).empty()传蹈。先解引用得到 string 類型,再判斷這個(gè)字符串是否為空步藕。

5虢纭! 但凡使用了迭代器的循環(huán)體咙冗,都不要向迭代器所屬的容器添加元素沾歪。

  • string 和 vector 的迭代器的其他運(yùn)算

      iter + n
      iter - n
      iter1 += n
      iter1 -= n
      iter1 - iter2   //相減得到迭代器之間的距離
      >, >=, <, <=
    

    也可以進(jìn)行一些算術(shù)運(yùn)算,例如得到中間元素:

      auto mid = vi.begin() + vi.size() / 2;
    

    這個(gè)距離是一個(gè) difference_type 雾消,帶符號(hào)整數(shù)灾搏,因?yàn)榫嚯x可正可負(fù)。

數(shù)組

數(shù)組的大小確定不變

數(shù)組的聲明形如 a[d] 仪或,其中a是數(shù)組名字确镊,d是數(shù)組維度,維度必須是一個(gè)常量表達(dá)式范删。不允許使用 auto 關(guān)鍵字蕾域,必須指定數(shù)組的類型。和vector一樣,數(shù)組的元素為對(duì)象旨巷,不存在引用的數(shù)組巨缘。

初始化數(shù)組時(shí)可以忽略維度,根據(jù)初始值數(shù)量計(jì)算并推測(cè)出維度采呐。

顯式初始化:

const unsigned sz = 3;
int ia1[sz] = {0, 1, 2};
int a2[] = {0, 1, 2};
int a3[5] = {0, 1, 2};  // 等價(jià)于 a3[5] = {0, 1, 2, 0, 0}
string a4[3] = {"hi", "bye"}; // 等價(jià)于 a4[3] = {"hi", "bye", ""}
int a5[2] = {0, 1, 2};  // 這句錯(cuò)誤若锁,初始值過(guò)多

對(duì)于字符數(shù)組,還可以用字符串來(lái)進(jìn)行初始化:

char a3[] = "c++";  // 等價(jià)于 char a3[] = {'c', '+', '+', '\0'}

8隆又固!注意這里有一個(gè) '\0' 結(jié)尾存放空字符,a3的實(shí)際大小為4煤率。

數(shù)組不允許拷貝和賦值 (也有一些編譯器能支持仰冠,但是最好不要使用這些非標(biāo)準(zhǔn)特性)

  • 復(fù)雜數(shù)組的聲明

    類型修飾符遵循從右向左結(jié)合的原則。

      int *ptrs[10];             // ptrs是含有10個(gè)整型指針的數(shù)組
      int &refs[10] = ...;       // 錯(cuò)誤蝶糯,不存在引用的數(shù)組
      int (*Parray)[10] = &arr;  // Parray指向一個(gè)含有10個(gè)整數(shù)的數(shù)組
      int (&arrRef)[10] = arr;   // arrRef引用一個(gè)含有10個(gè)整數(shù)的數(shù)組
    

    對(duì)于 ptrs洋只,首先[10],它是一個(gè)大小為10的數(shù)組昼捍,其次 * 表示它存放的是指針识虚,int 是存放的指針指向的類型;

    對(duì)于 Parray妒茬,最好由內(nèi)向外地去理解它的含義担锤。圓括號(hào)內(nèi)的 *Parray 表示 Parray 是一個(gè)指針,接下來(lái)右邊的 [10] 可以知道 Parray 這個(gè)指針指向大小為 10 的數(shù)組郊闯,最左邊的 int 表示數(shù)組的數(shù)據(jù)類型妻献。

    對(duì)于 arrRef,同理团赁,它是一個(gè)引用育拨,引用的內(nèi)容是一個(gè)含有10個(gè)整數(shù)的數(shù)組。

    更復(fù)雜的:

      int *(&arry)[10] = ptrs;
    

    arry 是一個(gè)對(duì)數(shù)組的引用欢摄,引用的數(shù)組大小為10熬丧,存放的int類型的指針。

  • 訪問(wèn)數(shù)組元素

    下標(biāo)訪問(wèn)方式怀挠,數(shù)組的下標(biāo)是一個(gè) size_t 類型析蝴,它是一種機(jī)器相關(guān)的無(wú)符號(hào)類型,足夠大以便能表示內(nèi)存中任意對(duì)象的大小绿淋。

    其他的下標(biāo)操作類似于 vector

  • 指針和數(shù)組

    使用數(shù)組的時(shí)候編譯器一般都會(huì)把它轉(zhuǎn)換成指針闷畸,可以用取地址符來(lái)得到指向數(shù)組元素的指針:

      string nums[] = {"one", "two", "three"};
      string *p = &nums[0];  // p 指向 nums 的第一個(gè)元素
      string *p = nums;      // 等價(jià)于上面一句
    

    在大多數(shù)表達(dá)式中,使用數(shù)組類型的對(duì)象實(shí)際是使用一個(gè)指向該數(shù)組首元素的指針吞滞。

    一般數(shù)組名 nums 都會(huì)被轉(zhuǎn)化成 &nums[0]佑菩,除了使用 decltype(nums) 的時(shí)候盾沫,會(huì)返回一個(gè) string[3] 類型。

    對(duì)于空指針殿漠,允許給它加上或減去一個(gè)值為 0 的整型常量表達(dá)式赴精,兩個(gè)空指針也允許彼此相減,當(dāng)然結(jié)果為 0

  • 標(biāo)準(zhǔn)庫(kù)函數(shù) begin 和 end

    數(shù)組不是類型绞幌,因此 begin 和 end 不能作為成員函數(shù)蕾哟。使用方法:

      int ia[] = {0,1,2,3,4,5,6,7,8,9};
      int *beg = begin(ia);
      int *last = end(ia);
    

    begin 函數(shù)返回指向 ia 首元素的指針, end 函數(shù)返回指向 ia 尾元素的下一位置的指針莲蜘。

!! 標(biāo)準(zhǔn)庫(kù)類型的下標(biāo)運(yùn)算符使用的索引值必須是無(wú)符號(hào)類型谭确,而內(nèi)置的下標(biāo)運(yùn)算符不同,可以是負(fù)值菇夸。例如:

int ia[] = {0, 2, 4, 5, 8};
int *p = &ia[2];     // p指向索引為2的元素
int i = *(p + 2);
int k = p[-2];       // k為ia[0]琼富,索引值可以為負(fù)

多維數(shù)組

多維數(shù)組 = 數(shù)組的數(shù)組..

定義一個(gè)數(shù)組元素任然為數(shù)組的數(shù)組時(shí),用兩個(gè)維度來(lái)定義它庄新,一個(gè)表示數(shù)組本身大小,一個(gè)表示其元素的大小薯鼠。

int ia[3][4];  // 大小為3的數(shù)組择诈,每個(gè)元素含有4個(gè)整數(shù)
int arr[10][20][30] = {0};

對(duì)于二維數(shù)組,第一個(gè)維度成為行出皇,第二個(gè)維度稱為列羞芍。

int ia[3][4] = {
    {0, 1, 2, 3},
    {4, 5, 6, 7},
    {8, 9, 10, 11}       // 注意內(nèi)部是逗號(hào),括號(hào)都是花括號(hào)
};

也可以寫成一行的形式:

int ia[3][4] = {0, 1, 2, 3, 4, 5, 6,..., 11};

只初始化每一行的第一個(gè)元素:

int ia[3][4] = {{0}, {4}, {8}};

初始化第一行:

int ix[3][4] = {0, 3, 6, 9}; // 加不加花括號(hào)差別很大郊艘,對(duì)比上面一句
  • 下標(biāo)引用

    如果給出的下標(biāo)和維度一樣多荷科,那么就是這一點(diǎn)的元素值。如果缺少纱注,就是給定索引處的一個(gè)內(nèi)層數(shù)組畏浆。

      int (&row)[4] = ia[1];   // row 是一個(gè)4個(gè)int的數(shù)組的一個(gè)引用,綁定 ia 的第二個(gè)4元數(shù)組上狞贱,也就是第二行刻获。
    

    !瞎嬉! 對(duì)于 ia[1]蝎毡,因?yàn)?ia 是一個(gè) int [3][4] 的類型,從左往右看氧枣,ia[1]應(yīng)該是一個(gè) int [4] 的類型沐兵,是一個(gè)四元數(shù)組。

    在使用范圍 for 語(yǔ)句處理二維數(shù)組時(shí)便监,對(duì)于外層數(shù)組一定要寫引用符號(hào)扎谎,否則無(wú)法通過(guò)編譯:

      for(auto row : ia)
          for(auto col : row)  //無(wú)法通過(guò)編譯
    
      for(const auto &row : ia)
          for(auto col : row)  //可以運(yùn)行
    

    !! 除了最內(nèi)層循環(huán)外簿透,其他所有循環(huán)的控制變量都應(yīng)該是引用類型

  • 指針和多維數(shù)組

    由多維數(shù)組名轉(zhuǎn)化來(lái)的指針實(shí)際上是指向第一個(gè)內(nèi)層數(shù)組的指針移袍。

      int ia[3][4];
      int (*p)[4] = ia;   // p 指向含有4個(gè)整數(shù)的數(shù)組
      p = &ia[2];         // p 指向 ia 的尾元素
    

    使用指針遍歷:

      for(auto p = ia; p != ia + 3; ++p){
          for(auto q = *p; q != *p + 4; ++q)
              cout << *q;
          cout << endl;
      }
      // 也可以更簡(jiǎn)潔:
      for(auto p = begin(ia); p != end(ia); ++p){
          for(auto q = begin(*p); q != end(*p); ++q)
              cout << *q;
          cout << endl;
      }
      // 這里 auto 等價(jià)于 int[4] * 
    




4.表達(dá)式

重載運(yùn)算符可以改變運(yùn)算對(duì)象的類型和返回值的類型,但是運(yùn)算對(duì)象的個(gè)數(shù)老充、運(yùn)算符的優(yōu)先級(jí)和結(jié)合律無(wú)法改變葡盗。

  • 左值和右值

    rvalue 和 lvalue 左值可以位于賦值語(yǔ)句的左側(cè),而右值不能啡浊。

    當(dāng)一個(gè)對(duì)象被用作右值的時(shí)候觅够,用的是對(duì)象的值(內(nèi)容);當(dāng)對(duì)象被用作左值的時(shí)候巷嚣,用的是對(duì)象的身份(在內(nèi)存中的位置)

    在需要用右值的地方可以用左值代替喘先,但是不能把右值當(dāng)成左值使用。

    • 賦值運(yùn)算符左側(cè)需要一個(gè)(非const)左值作為運(yùn)算對(duì)象廷粒,得到的結(jié)果仍然是一個(gè)左值窘拯。
    • 取地址符作用于一個(gè)左值對(duì)象,返回一個(gè)指向該運(yùn)算對(duì)象的指針坝茎,這個(gè)指針是個(gè)右值涤姊。
  • 求值順序

    4種明確規(guī)定了運(yùn)算對(duì)象求值順序的運(yùn)算符:

    • 邏輯與(&&) 先求左側(cè)運(yùn)算對(duì)象的值,只有左側(cè)運(yùn)算對(duì)象的值為真時(shí)才繼續(xù)求右側(cè)運(yùn)算對(duì)象的值
    • 邏輯或(||) 先求左側(cè)嗤放,左側(cè)為假時(shí)才求右側(cè)表達(dá)式
    • 條件運(yùn)算符(?:)
    • 逗號(hào)運(yùn)算符(,)

算術(shù)運(yùn)算符

一元正負(fù)號(hào)具有最高優(yōu)先級(jí)思喊,其次* / %,最低的是+ -,.

c++11中次酌,除了 -m 導(dǎo)致溢出的情況恨课,其他時(shí)候都有 (-m)/n 和 m/(-n) 都等于 -(m/n),m%(-n) 等于 m%n岳服, (-m)%n 等于 -m%n

也就是: (-21)%(-8) = (-21)%8 = -21%8 = -5

邏輯運(yùn)算符

邏輯與和邏輯或都遵循先計(jì)算左側(cè)表達(dá)式的原則(短路求值)剂公。他們的左側(cè)運(yùn)算對(duì)象一般用來(lái)保證右側(cè)求值過(guò)程中的正確性和安全性,例如:

index != s.size() && !isspace(s[index])

s.empty() || s[s.size() - 1] == '.'  // 遇到空字符串或以句號(hào)結(jié)束的字符串

!!在進(jìn)行比較運(yùn)算時(shí)除非比較的對(duì)象是布爾類型派阱,否則就不要用布爾類型的字面值 true 和 false 作為運(yùn)算對(duì)象诬留。

賦值運(yùn)算符

賦值運(yùn)算符的優(yōu)先級(jí)比較低,在表達(dá)式中盡量加上括號(hào)贫母。

允許使用花括號(hào)括起來(lái)的初始值列表作為賦值語(yǔ)句的右側(cè)運(yùn)算對(duì)象:

int k = {3.14};   // 錯(cuò)誤文兑,進(jìn)行了窄化轉(zhuǎn)換
vector<int> vi = {0,1,2,3,4}; // 正確, vi 包含 5 個(gè)元素

賦值語(yǔ)句滿足右結(jié)合律,賦值語(yǔ)句返回的是左側(cè)運(yùn)算對(duì)象:

int ival, jval;
ival = jval = 0;  // 都被初始化為0

其他復(fù)合賦值運(yùn)算符:(都等價(jià)于a = a op b)

+=  -=  *=  /=  %=
<<= >>= &=  ^=  |=

遞增和遞減運(yùn)算符

++和--有前置和后置之分腺劣。

int j, i = 0;
j = i++;   // 后置版本得到遞增之前的值绿贞, j=0, i=1
j = ++i;   // 前置版本得到遞增之后的值, j=2, i=2

前置版本將對(duì)象本身作為左值返回橘原,后置版本則將對(duì)象原始值的副本作為右值返回籍铁。

!! 除非必須涡上,否則不用后置版本的遞增遞減運(yùn)算符。因?yàn)楹笾冒姹就瑫r(shí)存儲(chǔ)了修改前后的兩個(gè)值拒名,如果不需要用修改前的值的話吩愧,后置的遞增、遞減就造成一種浪費(fèi)增显。

后置的++也可以用來(lái)輸出前一個(gè)元素雁佳,例如循環(huán)輸出一個(gè)vector對(duì)象內(nèi)容直至遇到(但不包括)第一個(gè)負(fù)值為止:

auto pbeg = v.begin();
while(pbeg != v.end() && *beg >= 0)
    cout << *pbeg++;   // 后置++,每次解引用輸出的都是迭代器的前一個(gè)

++ 的優(yōu)先級(jí)比解引用 * 高同云,因此 *pbeg++ 等價(jià)于 *(pbeg++)

后置的 ++ 操作返回值是未自增前的那個(gè) pbeg糖权,因此 pbeg 自增后,解引用的仍然是原來(lái)沒(méi)自增的那個(gè)迭代器炸站。

P前摹!注意 *pbeg++ 這種寫法旱易,常用禁偎。

成員訪問(wèn)運(yùn)算符

ptr->mem 等價(jià)于 (*ptr).mem

解引用運(yùn)算符的優(yōu)先級(jí)低于點(diǎn)運(yùn)算符!所以上式必須加括號(hào)阀坏。

箭頭運(yùn)算符作用于一個(gè)指針類型的運(yùn)算對(duì)象届垫,結(jié)果是一個(gè)左值。點(diǎn)運(yùn)算符的結(jié)果則根據(jù)成員所屬的對(duì)象是左值和右值而定全释。

條件運(yùn)算符

簡(jiǎn)單的 if-else 語(yǔ)句可以用條件運(yùn)算符(?:)實(shí)現(xiàn)

條件運(yùn)算符可以嵌套:

finalgrade = (grade > 90) ? "high pass" 
                          : (grade < 60) ? "fail" : "pass";

最好不要嵌套太多層。

N笳浸船!在輸出表達(dá)式中,由于條件運(yùn)算符的優(yōu)先級(jí)非常低寝蹈,因此兩邊一般要加上括號(hào)李命。

cout<< ((grade < 60) ? "fail" : "pass") <<endl;

位運(yùn)算符

運(yùn)算符 功能
~ 位求反
<< 左移
>> 右移
& 位與
^ 位異或
| 位或

!箫老!對(duì)符號(hào)位的處理沒(méi)有規(guī)定封字,因此強(qiáng)烈建議僅對(duì)無(wú)符號(hào)類型進(jìn)行位運(yùn)算

sizeof運(yùn)算符

兩種形式:

sizeof(type)
sizeof expr

sizeof 滿足右結(jié)合律,且優(yōu)先級(jí)和 * 一樣耍鬓。有 sizeof *p 也就是 sizeof(*p)阔籽。

因?yàn)閟izeof實(shí)際不會(huì)去求表達(dá)式的值,所以即使 p 是一個(gè)無(wú)效(未初始化)指針也無(wú)所謂牲蜀。

  • 對(duì) char 類型或者類型為 char 的表達(dá)式執(zhí)行 sizeof 運(yùn)算笆制,結(jié)果得 1
  • 對(duì)引用類型執(zhí)行 sizeof 運(yùn)算,得到被引用對(duì)象所占空間的大小
  • 對(duì)指針執(zhí)行 sizeof 運(yùn)算涣达,得到指針本身所占空間大小
  • 對(duì)解引用指針執(zhí)行 sizeof 運(yùn)算在辆,得到指針指向的對(duì)象所占空間的大小证薇,指針不需要有效
  • 對(duì)數(shù)組執(zhí)行 sizeof,得到整個(gè)數(shù)組所占空間的大小匆篓,sizeof不會(huì)把數(shù)組轉(zhuǎn)化為指針處理
  • 對(duì) string 對(duì)象或 vector 對(duì)象運(yùn)算只返回該類型固定部分的大小浑度,不會(huì)計(jì)算對(duì)象中的元素占用了多少空間

類型轉(zhuǎn)換

如果兩種類型可以相互轉(zhuǎn)換,那么他們就是關(guān)聯(lián)的鸦概。

  • 隱式轉(zhuǎn)換:

    • 在大多數(shù)表達(dá)式中箩张,比 int 類型小的整型值首先提升為較大的整數(shù)類型
    • 在條件中,非布爾值轉(zhuǎn)換成布爾值
    • 初始化過(guò)程中完残,初始值轉(zhuǎn)化成變量的類型咖城;賦值語(yǔ)句中抒钱,右側(cè)的對(duì)象類型轉(zhuǎn)換成左側(cè)的
    • 算術(shù)運(yùn)算和關(guān)系運(yùn)算中,多種類型都轉(zhuǎn)換成同一種類型
    • 函數(shù)調(diào)用也會(huì)發(fā)生類型轉(zhuǎn)換
    • 數(shù)組轉(zhuǎn)換成指針,但是在 &梦皮、sizeof、decltype下不會(huì)轉(zhuǎn)化
  • 整型提升:

    負(fù)責(zé)把小整數(shù)類型轉(zhuǎn)換成較大的整數(shù)類型腌歉。對(duì)于bool稽鞭、char、signed char二蓝、unsigned char誉券、short和unsigned short,只要他們所有可能的值都能存在 int 里刊愚,他們就會(huì)被提升成 int 類型踊跟。

    較大的 char 類型(wchar_t、char16_t鸥诽、char32_t)提升成int商玫、unsigned int、long牡借、unsigned long拳昌、long long和unsigned long long 中最小的一種類型。

    在計(jì)算時(shí)钠龙,首先進(jìn)行整型提升炬藤,如果類型匹配則進(jìn)行計(jì)算,如果提升后的兩個(gè)運(yùn)算對(duì)象一個(gè)帶符號(hào)一個(gè)無(wú)符號(hào)碴里,且無(wú)符號(hào)類型不小于帶符號(hào)的沈矿,則帶符號(hào)的會(huì)被轉(zhuǎn)化成無(wú)符號(hào)的,例如unsigned int 和 int 會(huì)使 int 轉(zhuǎn)化成無(wú)符號(hào)的并闲。

  • 顯示轉(zhuǎn)換:

    一個(gè)命名的強(qiáng)制類型轉(zhuǎn)換具有如下形式:

      cast-name<type>(expression);
    

    cast-name有四種:

    • static_cast: 任何不包含底層const的都可以使用

        double slope = static_cast<double>(j) / i;
      
    • const_cast: 只能改變運(yùn)算對(duì)象的底層const细睡,“去掉const性質(zhì)”,一般用于有函數(shù)重載的上下文中

        const char *pc;
        char *p = const_cast<char*>(pc); // 正確帝火,但是不能通過(guò) p 寫值
      
    • dynamic_cast

    • reinterpret_cast:通常為運(yùn)算對(duì)象的位模式提供較低層次上的重新解釋

    A镝恪湃缎!盡量不要使用強(qiáng)制類型轉(zhuǎn)換





5.語(yǔ)句

  • 空語(yǔ)句:只包含一個(gè)單獨(dú)的分號(hào),最好加上注釋

    也可以寫一個(gè)空塊

      while(cin >> s && s != sought)
      { }  // 空塊
    
      while(cin >> s && s != sought)
          ; // 空語(yǔ)句
    
  • 懸垂 else :

    當(dāng)一個(gè)if語(yǔ)句嵌套在另一個(gè)if語(yǔ)句中時(shí)蠢壹,可能if分支會(huì)多于else分支嗓违。c++規(guī)定else與離它最近的尚未匹配的if匹配,這點(diǎn)和python不同图贸!

    最好用花括號(hào)控制執(zhí)行路徑:

      if(grade % 10 >= 3) {   // 花括號(hào)必不可少蹂季!
          if(grade % 10 > 7)
              lettergrade += '+';
      } else
          lettergrade += '-';
    
  • switch 語(yǔ)句:

      switch (ch) {
          case 'a':
              ++aCnt;
              break;
          case 'b':
              ++bCnt;
              break;
          ...
          default:
              ++otherCnt;
              break;
      }
    

    如果某個(gè) case 標(biāo)簽匹配成功,將從該標(biāo)簽往后順序執(zhí)行所有 case 分支疏日,如果不 break偿洁,直到 switch 結(jié)束時(shí)才會(huì)停下來(lái)。

    或者把他們都寫在一行里也是一種合法的語(yǔ)句沟优。

      switch (ch) {  // 只要是5個(gè)字母中的任意一個(gè)都會(huì)執(zhí)行后面的++
          case 'a':
          case 'e':
          case 'i':
          case 'o':
          case 'u':
              ++vowelCnt;
              break;
      }
    
      switch (ch) {
          case 'a': case 'e': case 'i': case 'o': case 'u':
              ++vowelCnt;
              break;
      }  // 一般不要省略分支后面的break語(yǔ)句涕滋,如果要省略,最好加上注釋挠阁!
    

    如果需要為某個(gè) case 分支定義并初始化一個(gè)變量宾肺,應(yīng)該把變量定義在塊內(nèi),加上一個(gè) { }

  • 跳轉(zhuǎn)語(yǔ)句

    break 語(yǔ)句負(fù)責(zé)終止離他最近的 while侵俗、 do while锨用、 for 或 switch 語(yǔ)句。僅限于最近的一個(gè)循環(huán)或者 switch隘谣,只跳出一層循環(huán)增拥。

    continue 語(yǔ)句終止最近的循環(huán)的當(dāng)前迭代,并立即開(kāi)始下一次循環(huán)寻歧。

  • try 語(yǔ)句塊

    異常處理包括: throw 表達(dá)式跪者,引發(fā)異常; try 語(yǔ)句塊熄求,處理異常,以關(guān)鍵字 try 開(kāi)始逗概,以一個(gè)或多個(gè) catch 子句結(jié)束弟晚,稱為異常處理代碼;一套異常類逾苫,用于在 throw 表達(dá)式和相關(guān)的 catch 子句之間傳遞異常的具體信息卿城。

    拋出異常:

      if(item1.isbn() != item2.isbn())
          throw runtime_error("Data must refer to same ISBN");
      cout << item1 + item2 <<endl;
    

    異常處理代碼:

      try {
          ...
          if(item1.isbn() != item2.isbn())
              throw runtime_error("Data must refer to same ISBN");
          ...
      } catch(runtime_error err) {
          cout << err.what() << "\nTry again? Enter y or n: " <<endl;
          char c;
          cin >> c;
          if(!cin || c == 'n')
              break;
      }
    

    一個(gè) try 語(yǔ)句塊拋出多個(gè)異常,后面接多個(gè) catch 子句進(jìn)行處理

    標(biāo)準(zhǔn)異常:<stdexcept>定義的異常類

    exception 最常見(jiàn)的問(wèn)題
    runtime_error 只有在運(yùn)行時(shí)才能檢測(cè)出的問(wèn)題
    range_error 運(yùn)行時(shí)錯(cuò)誤:結(jié)果超出了有意義的值域范圍
    overflow_error 運(yùn)行時(shí)錯(cuò)誤:計(jì)算上溢
    underflow_error 運(yùn)行時(shí)錯(cuò)誤:計(jì)算下溢
    logic_error 程序邏輯錯(cuò)誤
    domain_error 邏輯錯(cuò)誤:參數(shù)對(duì)應(yīng)的結(jié)果值不存在
    invaild_argument 邏輯錯(cuò)誤:無(wú)效參數(shù)
    length_error 邏輯錯(cuò)誤:試圖創(chuàng)建一個(gè)超出該類型最大長(zhǎng)度的對(duì)象
    out_of_range 邏輯錯(cuò)誤:使用一個(gè)超出有效范圍的值
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末铅搓,一起剝皮案震驚了整個(gè)濱河市瑟押,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌星掰,老刑警劉巖多望,帶你破解...
    沈念sama閱讀 221,331評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嫩舟,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡怀偷,警方通過(guò)查閱死者的電腦和手機(jī)家厌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)椎工,“玉大人饭于,你說(shuō)我怎么就攤上這事∥桑” “怎么了掰吕?”我有些...
    開(kāi)封第一講書人閱讀 167,755評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)颅痊。 經(jīng)常有香客問(wèn)我殖熟,道長(zhǎng),這世上最難降的妖魔是什么八千? 我笑而不...
    開(kāi)封第一講書人閱讀 59,528評(píng)論 1 296
  • 正文 為了忘掉前任吗讶,我火速辦了婚禮,結(jié)果婚禮上恋捆,老公的妹妹穿的比我還像新娘照皆。我一直安慰自己,他們只是感情好沸停,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,526評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布膜毁。 她就那樣靜靜地躺著,像睡著了一般愤钾。 火紅的嫁衣襯著肌膚如雪瘟滨。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,166評(píng)論 1 308
  • 那天能颁,我揣著相機(jī)與錄音杂瘸,去河邊找鬼。 笑死伙菊,一個(gè)胖子當(dāng)著我的面吹牛败玉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播镜硕,決...
    沈念sama閱讀 40,768評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼运翼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了兴枯?” 一聲冷哼從身側(cè)響起血淌,我...
    開(kāi)封第一講書人閱讀 39,664評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎财剖,沒(méi)想到半個(gè)月后悠夯,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體癌淮,經(jīng)...
    沈念sama閱讀 46,205評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,290評(píng)論 3 340
  • 正文 我和宋清朗相戀三年疗疟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了该默。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,435評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡策彤,死狀恐怖栓袖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情店诗,我是刑警寧澤裹刮,帶...
    沈念sama閱讀 36,126評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站庞瘸,受9級(jí)特大地震影響捧弃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜擦囊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,804評(píng)論 3 333
  • 文/蒙蒙 一违霞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瞬场,春花似錦买鸽、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,276評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至彤灶,卻和暖如春看幼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背幌陕。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工诵姜, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人搏熄。 一個(gè)月前我還...
    沈念sama閱讀 48,818評(píng)論 3 376
  • 正文 我出身青樓茅诱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親搬卒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,442評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容