- 現代C++編程:從入門到實踐
- (美)喬什·洛斯皮諾索
- 2798字
- 2024-04-15 11:40:43
2.2 數組
數組是相同類型變量的序列。數組的類型包括它所包含的元素的類型和數量。在聲明語法中可以把這些信息組織在一起:元素類型在方括號前面,數組大小在方括號中間。
例如,下面的代碼聲明了一個包含100個int對象的數組:

2.2.1 數組初始化
有一種使用大括號初始化數組值的快捷方式:

我們可以省略數組的長度,因為它可以在編譯時從大括號中的元素數量推斷出來。
2.2.2 訪問數組元素
使用方括號包圍所需的索引即可訪問數組元素。在C++中,數組的索引是從零開始的,所以第一個元素的索引是0,第十個元素的索引是9,以此類推。代碼清單2-9說明了讀寫數組元素的方法。
代碼清單2-9 一個索引數組的程序

這段代碼聲明了一個名為arr的四元素數組,包含元素1、2、3和4?。在下一行?,它打印了第三個元素。然后,它將第三個元素賦值為100?,所以當重新打印第三個元素?時,其值是100。
2.2.3 for循環簡介
for循環可以重復(或迭代)執行某些語句特定次數。我們可以規定一個起點和其他條件。init-statement(初始化語句)在第一次迭代之前執行,所以它可以初始化for循環中使用的變量。conditional是一個表達式,在每次迭代前被求值。如果它被評估為true,迭代繼續進行。如果為false,for循環就會終止。iteration-statement在每次迭代后執行,這在必須遞增變量以覆蓋一個數值范圍的情況下很有用。for循環的語法如下:

例如,代碼清單2-10顯示了如何使用for循環來尋找數組的最大值。
代碼清單2-10 尋找數組中包含的最大值

首先把maximum初始化為可能的最小值?;這里是0,因為它是無符號的。接下來,初始化數組的值?,用for循環?遍歷這些值。迭代器變量i的范圍從0到4(包括4)。在for循環中,訪問數組values的每個元素,并檢查該元素是否大于當前的maximum?。如果大于,就把maximum設置為新的值?。循環結束后,maximum等于數組中的最大值,打印出maximum的值?。
注意 如果你以前用C或C++編程過,你可能想知道為什么代碼清單2-10采用size_t而不是int作為i的類型。這是因為考慮到values理論上可以占用最大可用存儲。size_t可以保證在數組內部對任何值進行索引,int卻不能。在實踐中,這其實沒有區別,但從技術上講,size_t是正確的。
1.基于范圍的for循環
代碼清單2-10展示了如何使用for循環?來迭代數組中的元素。我們可以通過基于范圍(range-based)的for循環來消除迭代器變量i。對于像數組這樣的特定對象,for知道如何在對象中的值的范圍內進行迭代。下面是基于范圍的for循環的語法:

聲明迭代器變量element-name?的類型為element-type?。element-type必須與要迭代的數組內的元素類型相匹配。要迭代的數組就是array-name?。
代碼清單2-11用基于范圍的for循環重構了代碼清單2-10。
代碼清單2-11 用基于范圍的for循環重構代碼清單2-10

注意 第7章將介紹表達式的知識。現在,暫且把表達式看作對程序產生影響的一些代碼。
代碼清單2-11大大改進了代碼清單2-10。一目了然,一看就知道for循環迭代了數組values?。因為拋棄了迭代器變量i,所以for循環的主體得到了簡化,可以直接使用values的每個元素??。
請善用基于范圍的for循環。
2.數組中元素的數量
使用sizeof運算符可以獲得數組的總大小(以字節為單位)。我們可以使用一個簡單的技巧來確定數組的元素數:用數組的大小除以單個元素的大小。

在大多數系統上,sizeof(array)?將計算為16字節,sizeof(short)?將計算為2字節。不管short的大小如何,n_elements總是初始化為8,因為因子會抵消。這個計算發生在編譯時,所以以這種方式評估數組的長度沒有運行時成本。
sizeof(x)/sizeof(y)構造太過于偏重技巧,但它被廣泛用于舊代碼中。第二部分將探討其他存儲數據的方法,這些方法不需要對數據長度進行外部計算。如果必須使用數組,則可以使用<iterator>頭文件中的std::size函數安全地獲得元素的數量。
注意 好的是,std::size可以與任何暴露了size方法的容器(見第13章)一起使用。這在編寫泛型代碼(見第6章)時特別有用。此外,如果不小心傳遞了一個不支持的類型,如指針,它將拒絕編譯。
2.2.4 C風格字符串
字符串是由字符組成的連續序列。C風格的字符串或null結尾字符串會在末尾附加一個零(null),以表示字符串結束了。因為數組元素是連續的,所以我們可以在字符類型的數組中存儲字符串。
1.字符串字面量
用引號("")括住文本即可聲明字符串字面量。像字符字面量一樣,字符串字面量也支持Unicode:只要在前面加上適當的前綴,如L。以下示例將字符串字面量賦給english和chinese數組:

注意 其實,我們一直都在使用字符串字面量:printf語句的格式化字符串便是字符串字面量。
這段代碼產生了兩個變量:english(包含A book holds a house of gold.)和chinese(包含“書中自有黃金屋”的Unicode字符)。
2.格式指定符
窄字符串(char*)的格式指定符是%s。例如,可以將字符串納入格式化字符串,如下所示:

注意 將Unicode打印到控制臺出乎意料得復雜。通常情況下,我們需要確保選擇了正確的代碼頁,而這個話題遠遠超出了本書的范圍。如果需要將Unicode字符嵌入字符串字面量,請看<cwchar>頭文件中的wprintf。
連續的字符串字詞會被串聯在一起,任何中間的空白或換行符都會被忽略。因此,可以在源代碼中將字符串字面量分多行放置,編譯器會將它們視為一個整體。例如,上述例子可如下重構:

通常情況下,只有當字符串字面量很長,在源代碼中會跨越多行時,這樣的結構才有利于提高可讀性。生成的程序是相同的。
3.ASCII
美國信息交換標準代碼(American Standard Code for Information Interchange,ASCII)表將整數與字符一一匹配。表2-4顯示了ASCII表。對于十進制(0d)和十六進制(0x)的整數值,表中都給出了控制代碼或可打印字符。
ASCII代碼0~31是控制設備的控制代碼字符。這些大多是不合時宜的。當美國標準協會在20世紀60年代正式確定ASCII時,當時的現代設備包括電傳打字機、磁帶閱讀器和點陣打印機。目前仍在普遍使用的一些控制代碼有:
? 0(NULL),被編程語言用作字符串的結束符。
? 4(EOT),EOT意指End Of Transmission,即傳輸結束,終止shell會話和與PostScript打印機的通信。
? 7(BELL),使設備發出聲音。
? 8(BS),BS意指BackSpace,即退格,使設備擦除最后一個字符。
? 9(HT),HT意指Horizontal Tab,即水平制表符,將光標向右移動幾個空格。
? 10(LF),LF意指Line Feed,即換行,在大多數操作系統中被用作行末標記。
? 13(CR),CR意指Carriage Return,即回車,在Windows系統中與LF結合使用,作為行末標記。
? 26(SUB),指替代字符(SUBstitute character)、文件結束和<Ctrl+Z>,在大多數操作系統上暫停當前執行的交互式進程。
ASCII表的其余部分(從32到127)是可打印字符。這些代表英文字符、數字和標點符號。
在大多數系統中,char類型的表示方法是ASCII。雖然它們之間的這種關系沒有得到嚴格的保證,但它的確是一個標準。
表2-4 ASCII表

現在是時候將char類型、數組、for循環和ASCII表結合起來使用了。代碼清單2-12顯示了如何用字母構建數組,如何打印結果,以及如何將數組轉換成大寫字母的數組并再次打印。
代碼清單2-12 使用ASCII打印小寫和大寫的英文字母

首先,我們聲明一個長度為27的char數組來存放26個英文字母和一個null結尾符?。接下來,采用for循環,使用迭代器變量i從0到25進行迭代。字母a的ASCII值為97。在迭代器變量i上添加97,我們可以生成小寫字母表alphabet?。要使alphabet成為以null結尾的字符串,需要將alphabet[26]設置為0?。然后打印出結果?。
接下來,我們來打印大寫字母表。字母A的ASCII值是65,所以相應地重置了字母表的每個元素?,并再次調用printf?。
- Java程序設計與開發
- 國際大學生程序設計競賽中山大學內部選拔真題解(二)
- 移動UI設計(微課版)
- PHP 編程從入門到實踐
- C程序設計案例教程
- Kinect for Windows SDK Programming Guide
- 零基礎入門學習Python
- Apache Spark 2.x for Java Developers
- PHP+MySQL+Dreamweaver動態網站開發從入門到精通(第3版)
- C#開發案例精粹
- Frank Kane's Taming Big Data with Apache Spark and Python
- Mastering Python Design Patterns
- Learning Grunt
- ROS機器人編程實戰
- 分布式數據庫HBase案例教程