第二篇
1. 我們編寫的程式以及所儲存的程式資料在計算機的記憶體中是以二進制位序列的方式存放的,位(bit)是含有0或1值的一個單元。
2. 一個位元組由8位構成,而一個字由32位構成,或者說是4個位元組。
3. 類型抽象使我們能夠對一個定長的位序列進行有意義的解釋。
4. C++提供了一組預定義的資料類型,如字元型、整型、浮點型,以及一組基本的資料抽象,如string、vector和複數。它還提供了一組操作符(或稱運算符),如加、減、等于、小于操作符等來操縱這些類型。C++還為程式流控制提供了為數不多的一組語句,如while循環和if語句。這些要素構成了一個符号系統。
CH3
1. C++預定義了一組數值資料類型,可以用來表示整數、浮點數和單個字元。
2. 字元型char,通常用來表示單個字元和小整數;整型int、短整型short、長整型long,分别代表不同長度的整數值;浮點型float、雙精度double和長雙精度long double分别表示單精度浮點數、雙精度浮點數和擴充精度的浮點數值。
3. char、short、int和long稱為整值類型(integral type),整值類型可以有符号,也可以無符号;在有符号類型中,最左邊的位是符号位,餘下的位代表數值;在無符号類型中,所有的位都表示數值,如果符号位被置為1,數值被解釋成負數,如果是0,則為正數。
4. 當一個數值,例如1,出現在程式中時,它被稱為文字常量(literal constant)。文字常量是不可尋址的(nonaddressable)。
5. 整數文字常量可以被寫成十進制,八進制或者十六進制的形式。在預設情況下,整型文字常量被當作是一個int型的有符号值。
6. 可以在文字常量後面加一個L或l(字母L的大寫形式或者小寫形式),将其指定為long類型;可以在整型文字常量的後面加上u或U将其指定為一個無符号數;還可以指定無符号long型的文字常量。
7. 浮點型文字常量可以被寫成科學計數法形式或普通的十進制形式。使用科學計數法,指數可寫作“e”或“E”;浮點型文字常量在預設情況下被認為是double型,單精度文字常量由值後面的“f”或“F”來标示;類似地,擴充精度中值後面跟的“l”或“L”來訓示(注意,f、F、l、L字尾隻能用在十進制形式中)。
8. 單詞true和false是bool型的文字常量;可列印的文字字元常量可以寫成用單引号括起來的形式;一部分不可列印的字元、單引号、雙引号以及反斜杠可以用轉義序列來表示(轉義序列以反斜杠開頭)。
9. 字元文字前面可以加“L”,這稱為寬字元文字,類型為wchar_t。
10. 字元串文字常量由零個或多個用雙引号括起來的字元組成。不可列印字元可以由相應的轉義序列來表示,而一個字元串文字可以擴充到多行。在一行的最後加上一個反斜杠,表明字元串文字在下一行繼續。
11. 字元串文字的類型是常量字元數組,它由字元串文字本身以及編譯器加上的表示結束的空(null)字元構成。空字元是C和C++用來标記字元串結束的符号。
12. 在許多實際開發環境中,成功的主要評價标準是最後的結果,至于對處理過程的讨論則很可能被視為學術氣、不切實際,總是得不到重視。
13. 變量為我們提供了一個有名字的記憶體存儲區,可以通過程式對其進行讀、寫和處理;C++中的每個符号變量都與一個特定的資料類型相關聯,這個類型決定了相關記憶體的大小、布局、能夠存儲在該記憶體區的值的範圍以及可以應用其上的操作集。也可以把變量說成對象(object)。
14. 變量和文字常量都有存儲區,并且有相關的類型。差別在于變量是可尋址的(addressable),對于每一個變量,都有兩個值與其相關聯:一是它的資料值(存儲在某個記憶體位址中,右值),二是它的位址值——即存儲資料值的那塊記憶體的位址(左值)。
15. 變量的定義會引起相關記憶體的配置設定,因為一個對象隻能有一個位置,是以程式中的每個對象隻能被定義一次。
16. 對象聲明(declaration)的作用是使程式知道該對象的類型和名字,它由關鍵字extern以及跟在後面的對象類型和對象的名字構成。一個程式隻能包含一個對象的一個定義,但它可以包含任意數目的對象聲明。
17. 變量名,即變量的辨別符(identifier),可以由字母、數字以及下劃線字元組成。它必須以字母或下劃線開頭,并且區分大寫字母和小寫字母。
18. 命名對象的習慣:1)對象名一般用小寫字母;2)辨別符一般使用助記的名字(能夠對程式中的用法提供提示的名字);3)對于多個詞構成的辨別符,習慣上,一般在每個詞之間加一個下劃線,或内嵌的每個詞第一個字母大寫。
19. 一個簡單的對象定義由一個類型訓示符後面跟一個名字構成,以分号結束。當同類型的多個辨別符被定義的時候,我們可以在類型訓示符後面跟一個由逗号分開的辨別符清單。
20. 如果一個變量是在全局域(global scope)内定義的,那麼系統會保證給它提供初始值0;如果變量是在局部域(local scope)内定義的,或是通過new表達式動态配置設定的,則系統不會向它提供初始值0,這些對象被稱為是未初始化的(uninitialized)。
21. 一個被聲明了初始值的對象也被稱為已經初始化的(initialized),C++支援兩種形式的初始化:第一種形式是使用指派操作符的顯式文法形式;第二種形式是一種特殊的構造函數文法,可将對象初始化為0。
22. 不同資料類型的指針之間的差別之處在于指針所指的對象的類型上。指針的類型可以訓示編譯器怎樣解釋特定位址上記憶體的内容,以及該記憶體區域應該跨越多少記憶體單元。
23. 通過在辨別符前加一個解引用操作符(*)來定義指針。指針不能持有非位址值,指針不能被初始化或指派為其他類型對象的位址值。
24. 空(void*)類型指針可以被任何資料指針類型的位址值指派(函數指針不能指派給它)。void*表明相關的值是個位址,但該位址的對象類型不知道。
25. C++提供了解引用操作符(dereference operator)*來間接地讀和寫指針所指向的對象。
26. 指針可以讓它的位址值增加或減少一個整數值,這類指針操作被稱為指針的算術運算(pointer arithmetic)。
27. 字元串被存儲在一個字元數組中,一般通過一個char*類型的指針來操縱它。
28. 程式将永遠執行下去或者由系統終止它,這樣的循環被稱作無限循環(infinite loop)。
29. 像這樣的程式修正通常被稱作更新檔(patch)——把某些東西伸展開以便補上現有程式中的洞。
30. C++标準庫提供了字元串類抽象的一個公共實作:1)支援用字元序列或第二個字元串對象來初始化一個字元串對象;2)支援字元串之間的拷貝;3)支援讀寫通路單個字元;4)支援兩個字元串的相等比較;5)支援兩個字元串的連接配接;6)支援對字元串長度的查詢;7)支援字元串是否為空的判斷。
31. const類型限定修飾符把一個對象轉換成一個常量(constant)。在程式中任何改變這個值的企圖都将導緻編譯錯誤,是以它被稱為是隻讀的(read-only)。
32. 因為常量在定義後就不能被修改,是以它必須被初始化。未初始化的常量定義将導緻編譯錯誤。
33. const對象的位址隻能指派給指向const對象的指針,但是指向const對象的指針可以被賦以一個非const對象的位址。
34. 引用(reference),有時候又稱為别名(alias),它可以用作對象的另一個名字;通過引用我們可以間接地操縱對象,使用方式類似于指針。
35. 引用類型由類型辨別符和一個取位址操作符來定義,引用必須被初始化。一旦引用已經定義,它就不能再指向其他的對象。
36. 引用的所有操作實際上都被應用在它所指的對象身上,包括取位址操作符。每個引用的定義必須以取位址操作符開始。
37. const引用可以用不同類型的對象初始化(隻要能從一種類型轉換到另一種類型即可),也可以是不可尋址的值,如文字常量。
38. 編譯器為了實作引用,必須生成一個臨時對象,引用實際上指向該對象,但使用者不能通路它。
39. 指針和引用有兩個主要差別:引用必須總是指向一個對象(如果用一個引用給另一個引用指派,那麼改變的是被引用的對象而不是引用本身);引用之間的指派(指派之後,引用仍然指向原來的對象)。
40. 實際的C++程式很少使用指向獨立對象的引用類型,引用類型主要被用作函數的形式參數。
41. 布爾型對象可以被賦以文字值true或false。雖然布爾類型的對象也被看作是一種整數類型的對象,但是它不能被聲明為signed、unsigned short或long。
42. 當表達式需要一個算術值時,布爾對象和布爾文字都被隐式地提升成int。 false變成0,而true變成1。
43. 算術值和指針值也能隐式地被轉換成布爾類型的值,0或空指針被轉換成false,所有其他的值都被轉換成true。
44. 枚舉(enumeration)不但定義了整數常量,而且還把它們組成一個集合。枚舉成員(enumerator)代表了能用來初始化和指派變量的值的全集。
45. 不能做到的是列印枚舉成員的實際枚舉名,一種解決方案是定義一個由枚舉成員的值索引的字元串數組。不能使用枚舉成員進行疊代。
46. 枚舉類型用關鍵字enum,加上一個自選的枚舉類型名來定義,類型名後面跟一個用花括号括起來的枚舉成員清單,枚舉成員之間用逗号分開。在預設情況下,第一個枚舉成員被賦以值0,後面的每個枚舉成員依次比前面的大1。也可以顯式地把一個值賦給一個枚舉成員。
47. 可以定義枚舉類型的對象,它可以參與表達式運算,也可以作為參數傳遞給函數。枚舉類型的對象能夠被初始化,但是隻能被一個相同枚舉類型的對象或枚舉成員集中的某個值初始化或指派。
48. 在必要時,枚舉類型會自動被提升成算術類型。
49. 數組是一個單一資料類型對象的集合,其中單個對象并沒有被命名,但是我們可以通過它在數組中的位置對它進行通路。這種通路形式被稱作索引通路(indexing)或下标通路(subscripting)。
50. 數組定義由類型名、辨別符和維數組成;維數指定數組中包含的元素的數目,它被寫在一對方括号裡邊;維數值必須是常量表達式。
51. 數組可以被顯式地用一組數來初始化,這組數用逗号分開,放在大括号中;被顯式初始化的數組不需要指定維數值,編譯器會根據列出來的元素的個數來确定數組的維數。
52. 字元數組可以用一個由逗号分開的字元文字清單初始化,文字清單用花括号括起來,或者用一個字元串文字初始化;但是,注意這兩種形式不是等價的,字元串常量包含一個額外的終止空字元。
53. 一個數組不能被另外一個數組初始化,也不能被指派給另外一個數組;而且,C++不允許聲明一個引用數組(即由引用組成的數組)。要把一個數組拷貝到另一個中去,必須按順序拷貝每個元素。
54. C++沒有提供編譯時刻或運作時刻對數組下标的範圍檢查。
55. 可以定義多元數組,每一維用一個方括号對來指定;一個二維數組的第一維被稱作行(row)維,第二維稱作列(column)維。
56. 數組辨別符代表數組中第一個元素的位址,它的類型是數組元素類型的指針。
57. 數組元素周遊則可以通過下标操作符來實作,或者也可以通過直接操作指針來實作數組元素周遊。
58. 使用vector有兩種不同的形式,即所謂的數組習慣和STL習慣。
59. 可以用下标操作符通路vector的元素,vector的元素被初始化為與其類型相關的預設值,算術和指針類型的預設值是0;對于class類型,預設值可通過調用這類的預設構造函數獲得。
60. 對于内置數組,可以顯式地把數組的元素初始化為一組常量值;可以将vector初始化為一個已有數組的全部或一部分,隻需指定希望被用來初始化vector 的數組的開始位址以及數組最末元素的下一位置來實作例。
61. 複數(complex number)類是标準庫的一部分,每個複數都有兩部分:實數部分和虛數部分。
62. typedef機制為我們提供了一種通用的類型定義設施,可以用來為内置的或使用者定義的資料類型引入助記符号;這些typedef名字在程式中可被用作類型辨別符。
63. typedef定義以關鍵字typedef開始,後面是資料類型和辨別符;這裡的辨別符即typedef名字,它并沒有引入一種新的類型,而隻是為現有類型引入了一個助記符号。
64. 當一個對象的值可能會在編譯器的控制或監測之外被改變時,那麼該對象應該聲明成volatile。
65. pair類也是标準庫的一部分,它使得我們可以在單個對象内部把相同類型或不同類型的兩個值關聯起來。可以用成員通路符号(member access notation)通路pair中的單個元素。
66. 類的定義由關鍵字class開始,後面是一個辨別符,該辨別符也被用作類的類型訓示符。一個類包括公有的(public)操作部分和私有的(private)資料部分,這些操作被稱為該類的成員函數(member function)或方法(method),它們定義了類的公有接口(public interface)——即,使用者可以在該類對象上執行的操作的集合。
67. 根據被傳遞給構造函數的參數類型來判斷構造函數的應用,這種構造函數被稱為拷貝構造函數(copy constructor),因為它用另一個對象的拷貝來初始化一個對象。
68. 類的成員函數可以被定義在類的定義中,也可以定義在外面;在類定義之外定義的成員函數不但要告訴編譯器它們的名字、傳回類型、參數表,而且還要說明它們所屬的類。
69. 可能要頻繁調用的小函數應聲明成内聯(inline)函數,内聯函數在每個調用點上被展開,是以這樣做可以消除函數調用相關的額外消耗。
70. 析構函數由類名前面加一個波浪号(~)來辨別。