《C++ Primer》Learning Note
程序實例下載地址:http://www.informit.com/title/0321714113
第一章 開始
本章介紹C++的大部分基礎內容:類型、變量、表達式、語句及函數。在這個過程中,我們會簡要介紹如何編譯及運行程序,以期指導讀者具備編寫、編譯及運行簡單程序的能力。
1.關於main():
每個C++程序包含一個或多個函數,其中一個必須命名為main,操作系統通過調用main來運行C++程序。main函數的返回類型必須為int,即整數類型,int類型是一種內置類型(built-in type),即語言自身定義的類型。
return 0;
給操作系統返回一個值,int類型。在大多數系統中,main的返回值用來指示狀態。返回值0表明成功,非0的返回值的含義由系統定義,通常用來指出錯誤類型。
2.關於ostream:
std::cout << ”Enter two numbers : ” << std::endl;
<<運算符接受兩個運算對象,左側的運算對象必須是一個ostream對象,右側的運算對象是要打印的值。此運算符將給定的值寫到給定的ostream對象中。輸出運算符的計算結果就是其左側運算對象,也就是我們寫入給定值的ostream對象。(ostream為輸出流,一個流就是一個字符序列,是從IO設備讀出IO設備的。“stream”想要表達的是,隨着時間的推移,字符是順序生成或消耗的)
這條輸出語句使用了兩次<<運算符。因此運算符將返回其左側的運算對象,因此第一個運算符的結果成了第二個運算符的左側運算對象。
第一個輸出運算符給用戶打印了一條消息。這串消息是一個字符串字面值常量(string literal),是用一對雙引號包圍的字符序列,在雙引號之間的文本被打印到標准輸出。
第二個運算符打印endal,這是一個被稱為操作符(manipulator)的特殊值。寫入endl的結果是結束當前行,並將與設備關聯的緩沖區(buffer)中的內容刷到設備中。緩沖刷新操作可以保證到目前為止程序所產生的所有輸出都真正寫入輸出流中,而不是僅僅停留在內存中等待寫入流。
我們在調試時經常添加打印語句,這類語句應該保證“一直”刷新流。否則,如果程序崩潰,輸出可能還留在緩沖區中,從而導致關於程序崩潰位置的錯誤推斷。
std::指出cout和endl是定義在名為std的命名空間(namespace)中的。命名空間可以幫助我們避免不經意的名稱定義沖突,以及使用庫中相同名字導致的沖突,標准庫定義的所有名字都在命名空間std中。通過命名空間使用標准庫有一個副作用:那就是每一次使用標准庫名字時,都需要顯式說明我們想使用來自命名空間std中的名字。比如使用作用域運算符(::)指出我們想使用定義在命名空間std中的名字cout。
3.關於istream:
std::cin >> v1>> v2;
輸入運算符(<<)和輸出運算符類似,它接受一個istream作為其左側運算對象,接受一個對象作為其右側運算對象。它從給定的istream中讀入數據,並存入給定的對象中。與輸出運算符類似,輸入運算符返回其左側運算對象作為計算結果。
4.關於文件結束符問題:
參見:https://blog.csdn.net/huanbia/article/details/50543163
參見:https://bbs.csdn.net/topics/390265495
c++文件結束標志是EOF (the end of file),EOF是宏常量,定義在stdio.h中。
若干標准函數的返回值等於EOF , 表示文件結束,表示文件輸入流數據讀完了。EOF可被理解為是一個整型常數表達式,
一般編譯器定義為-1,或等於十六進制0xffffffff。
視窗系統可用Ctrl+Z組合鍵產生EOF。unix / Linux用Ctrl+D組合鍵產生。
while(cin>>word)
一般不要這么寫。要那樣寫的話,在windows上用CTRL+X,在Linux用CTRL+D可結束輸入。
通常while(cin>>word)可改寫為:
while(true)
{
cin >> word;
if(word == 退出的條件) break;
}
第二章 變量和基本類型
本章主要講述內置類型(如字符、整型、浮點數等)。
1.字符和字符串字面值:
由單引號括起來的一個字符稱為一個char型字面值,雙引號括起來的零個或多個字符稱為字符串型字面值。字符串型字面值實際上是由常量字符構成的數組,編譯器在每個字符串結尾處添加一個空字符('\0’),因此字符串字面值的實際長度比它的內容多1。
2.關於對象:
通常情況下,對象是指一塊能存儲數據並具有某種類型的內存空間。一些人僅在與類有關的場景下才使用“對象”這個詞。另一些人則把已命名的對象和未命名的對象區分開來,他們把命名了的對象叫做變量。還有一些人把對象和值區分開來,其中對象指能被程序修改的數據,值指只讀的數據。本書認為對象是具有某種數據類型的內存空間,我們在使用對象這個詞時,並不嚴格區分是類還是內置類型,也不區分是否命名或只讀。
3.關於對象初始化:
初始化不是賦值,初始化的含義是創建變量時賦予它一個初始值,而賦值的含義是把對象的當前值擦除,而以一個新值來替代。建議初始化每一個內置類型的變量。
4.變量聲明和定義的關系:
C++支持分離式編譯(separate compilation)機制,該機制允許將程序分割成若干個文件,每個文件可以被獨立編譯。變量在文件之間得以共享的關鍵在於C++語言將聲明和定義區別開來。聲明(declaration)使得名字為程序所知,定義(definition)則負責創建與名字關聯的實體。
變量聲明規定了變量的類型和名字,這一點上與定義相同。但除此之外,定義還申請了存儲空間,也可能會為變量賦一個初始值。如果想聲明一個變量而非定義它,就要在變量名前面添加關鍵字extern,且不要顯式地初始化變量。
變量能且只能被定義一次,但是可以被多次聲明。
5.關於靜態類型:
C++是一種靜態類型(statically typed)語言,其含義是在編譯階段檢查類型。檢查類型的過程被稱為類型檢查(type checking)。對象的類型決定了對象所能參與的運算,編譯器負責檢查數據類型是否支持要執行的運算,如果試圖執行類型不支持的運算,編譯器將報錯且不會生成可執行文件。
6.復合類型:
一條聲明語句由一個基本數據類型(base type)和緊隨其后的一個聲明符(declarator)列表組成。每一個聲明符命名了一個變量並指定該變量為與基本數據類型有關的某種類型。之前我們接觸的聲明語句中聲明符就是變量名,變量各類型就是聲明的基本數據類型,其實還可能有更復雜的聲明符,它基於基本數據類型得到更復雜的類型,並把它指定給變量。
引用(reference)給對象起了另外一個名字,引用類型引用另外一種類型,通過將聲明符寫成&d的形式來定義引用類型,其中d是聲明的變量名。引用必須被初始化。一般在初始化變量中,初始值會被拷貝到新建的對象中,然而在定義引用時,程序把引用和它的初始值綁定在一起,而不是將初始值拷貝給引用。
引用並非對象,相反的,它只是為一個已經存在的對象所起的另外一個名字。定義一個引用之后,對其進行的操作都是在與之綁定的對象上進行的。引用類型的初始值必須是一個對象,且除特例外,引用類型要與對象類型嚴格匹配。
指針(pointer)是“指向”另外一種數據類型的復合類型。與引用類似,指針也實現了對其他對象的間接訪問,然而指針與引用有諸多不同:一、指針本身就是一個對象,允許對指針賦值和拷貝,而且在指針的生命周期內它可以先后指向不用的對象;二、指針無須再定義時賦初值。和其他內置類型一樣,在塊作用域內定義的指針如果沒有被初始化,也將擁有一個不確定的值。
定義指針類型的方法是將聲明符寫成*d的形式,其中d是變量名。指針存放某個對象的地址,要想獲取該地址,需要使用取地址符(操作符&)。由於引用不是對象,沒有實際地址,所以不能定義指向引用的指針。在這里取地址符明顯和引用操作有所區別,如取地址符往往在等號右邊,而引用初始化符號在等號左邊。
如果指針指向了一個對象,則允許使用解引用符(操作符*)來訪問該對象。建議初始化所有指針,並且在可能的情況下,盡量等定義了對象之后再定義指向它的指針。
7.const對象在文件之間共享:
必須在變量定義之前添加extern關鍵字。
8.引用類型必須同引用對象類型一致的第一個特例(對const的引用):
P81。
9.指針類型必須與所指對象類型保持一致的第一個特例(pointer to const)
P82。
10.頂層const與底層const:
頂層const可以表示任意的對象是常量(指出對象的值是不變的),底層const則與指針和引用等復合類型的基本類型部分有關(指出引用或者指針本身是不變的,對常量的引用或者常量指針不能想修改該引用或該指針所綁定的對象)。
11.關於decltype和引用(P89):
decltypr(*p) c ;
由於通過p可以對i進行賦值,所以*p實際上是i的一種引用,*p是i的一個別名,而p是i的地址。
12:decltype中括號的影響:
decltype((variable))(注意是雙層括號)的結果永遠是引用,而decltype(variable)結果只有當variable本身就是一個引用時才是引用。
第三章 字符串、向量和數組
本章將分別介紹數組以及標准庫類型string和vector。
1.命名空間的using聲明:
目前為止,我們用到的庫函數基本上都屬於命名空間std,using聲明(using declaration)可以讓我們無需前綴(形如命名空間::)也能使用所需的名字,using聲明具有以下的格式:using namespace::name
另一種寫法是:using namespace std;
這樣命名空間std內定義的所有標識符都有效(曝光),就好像它們被聲明為全局變量一樣
2.標准庫類型string:
標准庫類型string表示可變長的字符序列,使用string類型必須首先包含string頭文件,作為標准庫的一部分,string定義在命名空間std中。本節還介紹了string對象的初始化(直接初始化和拷貝初始化),string對象操作(讀寫與未知數量string對象讀寫,empty和size操作,大小比較),處理string對象中的字符(檢索,大小寫轉換等)。
1.關於size()函數需要注意的一點:如果一條表達式中有size()函數就不要在使用int了,這樣可以避免混用int和unsigned導致的問題,int整型的負值在與size()函數返回值判斷大小的時候會自動轉換成一個比較大的無符號值。
2.關於字面值與字符串相加:當把string對象和字符字面值及字符串字面值混在一條語句中使用時,必須確保每個加法運算符(+)的兩側的運算對象至少有一個是string(如果出現沖突可以使用()來調整優先級)。
注:字符串字面值與string對象不是一個類型。
3.建議使用C++版本的C標准庫頭文件:即在使用C語言標准庫時,C++將形如name.h的頭文件明明為cname,名為cname的頭文件中定義的名字從屬於命名空間std,而定義在名為.h的頭文件中的則不然。
4.使用范圍for語句改變字符串中的字符:如果要改變string對象中字符的值,必須把循環變量定義成引用類型。當使用引用作為循環控制變量時,這個變量實際上被依次綁定到了序列的每個元素上,從而改變元素對應的字符。
5.訪問string對象單個字符的方式:一種是適用下標,另外一種是使用迭代器。下標運算符([])接收的輸入參數是string::size_type類型的值,這個參數表示要訪問的字符的位置,返回值是該位置上字符的引用。下標的值稱作“下標”或“索引”,任何表達式只要它的值是一個整型值就能作為索引,不過,如果某個索引是帶符號類型的值將自動轉換成string::size_type表達的無符號類型。
使用下標時必須確保其在合理范圍內,也就是說,下標必須大於等於0而小於字符串的size()值,一種簡單易行的方法是,總是設下標的類型為string::size_type,因為此類型是無符號數,可以確保下標不會小於0,這時只要保證下標小於size()的值就可以了。
3.標准庫類型vector:
標准庫類型vector表示對象的集合,其中所有對象的類型都相同。集合中的每個對象都有一個與之對應的索引,索引用於訪問對象。因為vector“容納着”其他對象,所以它也常被稱作容器(container)。
C++中既有類模板,也有函數模板,其中vector是一個類模板。模板本身不是類或函數,相反可以將模板看作為編譯器生成類或函數編寫的一份說明。編譯器根據模板創建類或函數的過程稱為實例化(instantiation),當使用模板時,需要指出編譯器應把類或函數實例化成何種類型。
對於類模板來說,我們通過提供一些額外的信息來制定模板到底實例化成什么樣的類,需要提供哪些信息由模板決定。提供信息的方式總是這樣:即在模板名字后面跟一對尖括號,在括號內放上信息。以vector為例,提供的額外信息是vector內所存放對象的類型:
vector<int> ivec; //ivec保存int類型的對象
vector<Sales_item> Sales_vec; //保存Sales_item類型的對象
vector<vector<string>> file; //該向量的元素是vector對象
vector是模板而非類型,由vector生成的類型必須包含vector中元素的類型。vector能容納絕大多數類型的對象作為其元素,但是因為引用不是對象,所以不存在包含引用的vector。除此之外,其他大多數(非引用)內置類型和類類型都可以構成vector對象,甚至組成vector的元素也可以是vector。
本節還介紹了vector對象的定義和初始化、元素增減(vector對象能高效增長,即我們可以高效便捷地向vector對象中添加元素)、vector操作(push_back等)、
如果vector定義中用的是圓括號,說明提供的值是用來構造vector對象的,先后說明了vector元素的數量和元素值;如果用的是花括號,說明我們想列表初始化(list initialize)該vector對象,也就是說,初始化過程會盡可能把花括號內的值當成是元素初始值的列表來處理,只有無法執行列表初始化時才會考慮其他初始化方式。
一旦初始化時使用了花括號的形式但是提供的值又不能用來列表初始化,就要考慮用這樣的值來構造vector對象了。比如vector要求各元素的類型相同,如果使用語句vector<string> v8{10, “hi”};那么很明顯此時不能使用列表初始化,確定無法執行列表初始化后,編譯器會考慮用給定的值來構造vector對象,即用“hi”初始化這十個元素。
4.迭代器介紹:
類似於指針類型,迭代器(iterator)提供了對對象的間接訪問。就迭代器而言,其對象是容器中的元素或者string對象中的字符。使用迭代器可以訪問某個元素,迭代器也能從一個元素移動到另一個元素。迭代器分為有效和無效,有效迭代器或者指向某個元素,或者指向容器中尾元素的下一位置,其他所有情況都屬於無效。
本節主要介紹了迭代器的使用(運算符、迭代器在元素間的移動、迭代器類型、begin和end運算符、結合解引用和成員訪問操作:->)、迭代器運算。
注:謹記!但凡是使用了迭代器的循環體,都不要向迭代器所屬的容器添加元素,這樣會使迭代器失效。
5.數組:
數組是一種類似於標准庫類型vector的數據結構,但是在性能和靈活性的權衡上又與vector有所不同,數組的大小確定不變,不能隨意向數組中添加元素。在不確定元素的確切個數時,推薦使用vector。
本節主要介紹了定義和初始化內置數組、數組元素的訪問、指針和數組、指針也可以作為迭代器(尾后指針是數組尾元素之后那個並不存在的元素的地址)、數組對應的標准庫函數begin和end、數組指針運算、C風格字符串、與舊代碼的接口、多維數組。
在C++語言中,指針和數組有非常緊密的聯系,使用數組的時候編譯器一般會把它轉換為指針。對數組的元素使用取地址符就嫩能夠得到指向該元素的指針。在很多用到數組名字的地方,編譯器都會自動地將其替換為一個指向數組首元素的指針。在大多數表達式中,使用數組類型的對象其實是使用一個指向該數組首元素的指針。所以我們使用數組作為一個auto變量的初始值時,推導得到的類型是指針而非數組。不過,當使用decltype關鍵字時上述轉換不會發生,decltype(ia)返回的類型是數組。
盡管C++支持C風格字符串,在C++程序中最好還是不要使用它們。這是因為C風格字符串不僅使用起來不太方便,而且極易引發程序漏洞,是諸多安全問題的根本原因。對於大多數應用來說,使用標准庫string要比使用C風格字符串更安全,更高效。
注:嚴格來說,C++語言中沒有多維數組,通常所說的多維數組實際上是數組的數組。因此對於多維數組來講,由多維數組名轉換得來的指針實際上是指向第一個內層數組的指針。
第四章 表達式
表達式由一個或多個運算對象(operand)組成,對表達式求值將得到一個結果。字符串和變量是最簡單的表達式(expression),其結果就是字面值和變量的值。把一個運算符(operator)和一個或多個運算對象組合起來可以生成較復雜的表達式。
注:除非必須,否則不用遞增遞減運算符的后置版本,前置版本的遞增運算符避免了不必要的工作,它把值增加1后直接返回改變了的運算對象,而后置版本需要將原始值存儲下來以便返回這個為修改的內容,這種操作實際上是一種浪費。
第五章 語句
1.范圍for語句:
C++11新標准中引入了一種更簡單的for語句,可以遍歷容器或者其他序列的所有元素,范圍for語句(range for statement)的語法形式是:
for (declaration : expression) : statement
expression表示的是一個序列,比如用花括號括起來的初始值列表、數組或者vector或string等類型的對象,這些類型的共同特點是擁有能返回迭代器的begin或end成員。declaration定義一個變量,序列中的每個元素都得能轉換成該變量的類型。確保類型相容最簡單的辦法是使用auto類型說明符,這個關鍵字可以令編譯器幫助我們制定合適的類型。如果需要對序列中的元素執行寫操作,循環變量必須聲明成引用類型。
2.跳轉語句:
跳轉語句中斷當前的執行過程。C++語言提供了4中跳轉語句:break、continue、goto和return。本節介紹前三種跳轉語句。
break語句(break statement)負責終止離它最近的while、d0 whie、for或switch語句,並從這些語句之后的第一條語句開始執行。break語句只能出現在迭代語句或者swich語句內部(包括嵌套在此類循環里的語句或者塊的內部)。
continue語句(continue statement)終止最近的循環中的當前迭代並立即開始下一次迭代。continue語句只能出現在for、while和do while循環的內部,或者嵌套在此類循環里的語句或塊的內部。和break語句類似的是,出現在嵌套循環中的continue語句也僅作用於離它最近的循環。和break語句不同的是,只有當switch語句嵌套在迭代語句的內部時,才能在switch里使用continue。
goto語句(goto statement)的作用是從goto語句無條件跳轉到同一個函數內的另一條語句。goto語句的語法形式是
goto label ;
其中,label是用於標識一條語句的標示符。帶標簽語句(labeled statement)是一類特殊的語句,在它之前有一個標示符和一個冒號:
end : return ; //帶標簽語句,可以作為goto的目標。
標簽標示符獨立於變量或其他標示符的名字,因此,標簽標示符可以和程序中其他實體標示符使用同一個名字而不會相互干擾。goto語句和控制權轉向的那條帶標簽的語句必須位於同一函數之內。和switch語句類似,goto語句也不能將程序的控制權從變量的作用域之外轉移到作用域之內。
3.try語句塊和異常處理:
異常是指存在於運行時的反常行為,這些行為超出了函數正常功能的范圍。典型的異常包括失去數據庫連接以及遇到意外輸入等。異常處理機制為程序中異常檢測和異常處理這兩部分的協作提供支持。在C++語言中,異常處理包括:
1.throw表達式(throw expression),異常檢測部分使用throw表達式來表示它遇到了無法處理的問題。我們說throw引發(raise)了異常。
throw表達式包含關鍵字throw和緊隨其后的一個表達式,其中表達式的類型就是拋出的異常類型。throw表達式后面通常緊跟一個分號,從而構成一條表達式語句。
2.try語句塊(try block),異常處理部分使用try語句塊處理異常。try語句塊以關鍵字try開始,並以一個或多個catch子句(catch clause)結束。try語句塊中代碼拋出的異常通常會被某個catch子句處理。因為catch子句“處理”異常,所以它們也被稱作異常處理代碼(exception handler)。
try語句塊的通用語法形式是:
try{
program-statements
}catch (exception-declaration){
handler-statements
}catch (exception-declaration){
handler-statements
}
try語句塊一開始是關鍵字try,隨后緊跟一個塊,這個塊就像大多數使用那樣是花括號括起來的語句序列。跟在try塊之后的是一個或多個catch子句。catch子句包括三部分:關鍵字catch、括號內一個(可能未命名的)對象的聲明(稱作異常聲明,exception declaration)以及一個塊。當選中某個catch子句處理異常之后,執行與之對應的塊。catch一旦完成,程序跳轉到try語句塊最后一個catch子句之后的那條語句繼續執行。
3.一套異常類(exception class),用於在throw表達式和相關的catch子句之間傳遞異常的具體信息。
第六章 函數
本章首先介紹函數的定義和聲明,包括參數如何傳入函數以及函數如何返回結果、重載函數的放大,以及編譯器如何從函數的若干重載形式中選取一個與調用匹配的版本、以及函數指針的相關知識。
1.局部靜態對象:
為使函數內部局部變量的生命周期貫穿函數調用及之后的時間,可以將局部變量定義成static類型獲得局部靜態對象(local static object)。局部靜態對象在程序的執行路徑第一次經過對象定義語句時被初始化,並且直到程序終止時才被銷毀。
2.函數聲明:
函數聲明與函數的定義非常類似,唯一的區別就是函數聲明無須函數體,用一個分號替代即可。函數聲明了函數的三要素(返回類型、函數名、形參類型),描述了函數的接口,說明了調用該函數所需的全部信息。函數聲明也稱作函數原型。函數應該在頭文件中聲明,在源文件中定義。
3.參數傳遞:
當形參是引用類型時,我們說它對應的實參被引用傳遞(passed by reference)或者函數被傳引用調用(called by reference),引用形參是它對應的實參的別名。當實參的值被拷貝給形參時,形參和實參是兩個相互獨立的對象。我們說這樣的實參被值傳遞(passed by value)或者函數被傳值調用(called by value)。
4.返回類型和return語句:
return語句終止當前正在執行的函數並將控制權返回到調用該函數的地方。return語句有兩種形式:
return;
return expression;
沒有返回值的return語句只能用在返回類型是void的函數里。返回void的函數不要求非得有return語句,因為在這類函數的最后一句后面會隱式地執行return。通常情況下,void函數要想在它的中間位置提前退出,可以使用return語句。有返回值的return語句提供了函數的結果。
我們允許main函數沒有return語句直接結束,如果控制到達了main函數的結尾處而沒有return語句,編譯器將隱式地插入一條返回0的return語句。main函數非0返回值的具體含義由機器決定,為了使返回值與機器無關,cstdlib頭文件定義了兩個預處理變量EXIT_FAILURE和EXIT_SUCCESS。
4.內聯函數:
內聯機制用於優化規模較小、流程直接、頻繁調用的函數。很多編譯器都不支持內聯遞歸函數。
5.constexpr函數:
constexpr函數是指能用於常量表達式的函數。定義constexpr函數時要注意:函數的返回類型及所有形參的類型都得是字面值類型,而且函數體有且只有一條return語句。
6.函數指針:
函數指針指向的是函數而非對象。和其他指針一樣,函數指針指向某種特定類型。函數的類型由它的返回類型和形參類型共同決定,與函數名無關。
第七章 類
在C++語言中,我們使用類定義自己的數據類型。通過定義新的類型來反映待解決問題中的各種概念,可以使我們更容易編寫、調試和修改程序。本章是第2章關於類的話題的延續,主要關注數據抽象的重要性。數據抽象能幫助我們將對象的具體實現與對象所執行的操作分離開來。
類的基本思想是數據抽象(data abstraction)和封裝(encapsulation)。數據抽象是一種依賴於接口(interface)和實現(implementation)分離的編程技術。類的接口包括用戶所能執行的操作;類的實現則包括類的數據成員、負責接口實現的函數體以及定義類所需的各種私有函數。
類要想實現數據的抽象和封裝,需要首先定義一個抽象數據類型(abstract data type)。在抽象類型中,由類的設計者負責考慮類的實現過程,使用該類的程序員則只需要抽象地思考類型做了什么,而無需了解類型的工作細節。
1. 內聯函數:
(1)什么是內聯函數?
內聯函數是指那些定義在類體內的成員函數,即該函數的函數體放在類體內。
(2)為什么要引入內聯函數?
引入內聯函數的主要目的是:解決程序中函數調用的效率問題。
函數調用原理
"編譯過程的最終產品是可執行程序--由一組機器語言指令組成。運行程序時,操作系統將這些指令載入計算機內存中,因此每條指令都有特定的內存地址。計算機隨后將逐步執行這些指令。有時(如有循環和分支語句時),將跳過一些指令,向前或向后跳到特定地址。常規函數調用也使程序跳到另一個地址(函數的地址),並在函數結束時返回。下面更詳細地介紹這一過程的典型實現。執行到函數調用指令時,程序將在函數調用后立即存儲該指令的內存地址,並將函數參數復制到堆棧(為此保留的內存塊),跳到標記函數起點的內存單元,執行函數代碼(也許還需將返回值放入寄存器中),然后跳回到地址被保存的指令處(這與閱讀文章時停下來看腳注,並在閱讀完腳注后返回到以前閱讀的地方類似)。來回跳躍並記錄跳躍位置意味着以前使用函數時,需要一定的開銷。"
內聯函數
內聯函數提供了另一種選擇。編譯器將使用相應的函數代碼替換函數調用。因此,內聯函數的運行速度比常規函數稍快,但代價是需要占用更多內存。
2. size_t:
size_t在C語言中就有了。它是一種“整型”類型,里面保存的是一個整數,就像int, long那樣。這種整數用來記錄一個大小(size)。size_t的全稱應該是size type,就是說“一種用來記錄大小的數據類型”。