劉昊 方歡 袁水蓮
摘要:數(shù)組是編程語言中應(yīng)用最為廣泛、功能強(qiáng)大的一種數(shù)據(jù)結(jié)構(gòu)。該文分析和探討了C++語言中常見的不同類型數(shù)組長(zhǎng)度的獲取方法與機(jī)理,將數(shù)組分為靜態(tài)數(shù)組和動(dòng)態(tài)數(shù)組,從兩種不同的構(gòu)造結(jié)構(gòu)出發(fā),結(jié)合程序?qū)嵗謩e闡釋了其中數(shù)值型、字符型和一維及多維數(shù)組長(zhǎng)度的獲取方法,并進(jìn)行了具體方法的原理探究。其次,對(duì)所總結(jié)的幾種方法進(jìn)行了比較,給出操作過程中常見的出錯(cuò)及解決方案,以便于掌握數(shù)組長(zhǎng)度應(yīng)用中的操作技巧。
關(guān)鍵詞:數(shù)組;長(zhǎng)度獲??;C++語言;錯(cuò)誤處理
中圖分類號(hào):G642.0 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2018)19-0089-04
Abstract: Array is the most powerful data structure and widely used in programming languages. This paper analyzes and discusses the methods and mechanisms for the acquisition of different types of array lengths commonly found in the C++ language. The arrays are divided into static arrays and dynamic ones. Starting from two different structural structures, combined program examples, the methods for obtaining lengths of numeric, character, one-dimensional and multi-dimensional arrays are respectively illustrated. And this paper carries out the principle of the specific method. Then, the methods summarized in the paper are compared, and the common mistakes and solutions are given in order to grasp the operating skills in array length applications.
Key words: Array; Length acquisition; C++ language; Error handling
1 背景
在C++程序設(shè)計(jì)中,為了可以高效處理大量數(shù)據(jù),同時(shí)縮短和簡(jiǎn)化程序,將具有相同類型的若干元素按照有序的形式組織起來,這些按序排列的同類數(shù)據(jù)元素的集合即可稱為數(shù)組[1]。經(jīng)過C和C++語言的學(xué)習(xí),筆者發(fā)現(xiàn)書中僅對(duì)數(shù)組的定義和相關(guān)基本操作進(jìn)行了簡(jiǎn)單概述,沒有對(duì)獲取數(shù)組長(zhǎng)度的方法等數(shù)組應(yīng)用細(xì)節(jié)進(jìn)行深入闡釋。數(shù)組的實(shí)際應(yīng)用范圍十分廣泛,在對(duì)指針、字符串、循環(huán)語句等操作過程中,程序設(shè)計(jì)人員常常需要獲取數(shù)組長(zhǎng)度來解決相關(guān)程序問題[2]。在相關(guān)程序設(shè)計(jì)語言中,如Java語言中給出了.length作為數(shù)組屬性來直接獲取數(shù)組長(zhǎng)度,Python中給出了len函數(shù)來獲取長(zhǎng)度,而C++中并未定義相關(guān)可直接獲取數(shù)組長(zhǎng)度的屬性和函數(shù)。鮮少有文獻(xiàn)全面總結(jié)了C++語言中獲取不同類型數(shù)組的不同方法,因此該文首先闡述了常見的不同類型數(shù)組長(zhǎng)度的獲取方法和機(jī)理,在ANSI C2.0環(huán)境下分析了操作過程中可能出現(xiàn)的數(shù)組越界等出錯(cuò)情況,并進(jìn)行相關(guān)對(duì)比和區(qū)分,該文所給代碼均經(jīng)過DEV-C++5.4.0編譯通過。
2 常見的不同類型數(shù)組及其長(zhǎng)度獲取方法
在C++中,靜態(tài)數(shù)組是指在聲明數(shù)組時(shí),就用常量表達(dá)式明確指定數(shù)組的大小,且運(yùn)行時(shí)的長(zhǎng)度不可改變,數(shù)組只在定義它的塊語句內(nèi)存在。靜態(tài)數(shù)組中常見的有靜態(tài)字符型數(shù)組和靜態(tài)數(shù)值型數(shù)組,利用sizeof()運(yùn)算符返回類型或數(shù)據(jù)對(duì)象的長(zhǎng)度(單位為字節(jié))可以間接獲取數(shù)組的長(zhǎng)度,同時(shí)C++中還給出了strlen()函數(shù)來計(jì)算給定靜態(tài)字符型數(shù)組的長(zhǎng)度。動(dòng)態(tài)數(shù)組則是在運(yùn)行時(shí)動(dòng)態(tài)分配數(shù)組空間,雖然數(shù)組長(zhǎng)度是固定的,但不必在定義時(shí)確定其長(zhǎng)度,且動(dòng)態(tài)數(shù)組在程序中會(huì)一直存在,直到顯式將其釋放。C++中創(chuàng)建動(dòng)態(tài)數(shù)組可以采取用new來申請(qǐng)空間和利用vector模板來創(chuàng)建。因此下面從靜態(tài)數(shù)組的不同類型和動(dòng)態(tài)數(shù)組的不同創(chuàng)建方法,分別闡述數(shù)組長(zhǎng)度的獲取方法和機(jī)理。
2.1 靜態(tài)數(shù)組
2.1.1 靜態(tài)數(shù)值型數(shù)組
C++中未提供可以直接獲取靜態(tài)數(shù)值型數(shù)組長(zhǎng)度的函數(shù)和相關(guān)數(shù)組屬性,利用sizeof()操作符可以間接解決該類數(shù)組的長(zhǎng)度獲取問題。sizeof()是一個(gè)可以返回操作數(shù)所占的內(nèi)存字節(jié)數(shù)的操作符,sizeof(a)/sizeof(a[0])可以獲取一維靜態(tài)數(shù)值型數(shù)組的長(zhǎng)度。對(duì)于二維靜態(tài)數(shù)值型數(shù)組,可利用sizeof(a),sizeof(a[0]),sizeof(int)進(jìn)行組合來表示二維數(shù)組的行數(shù)列數(shù)以及總元素的數(shù)目。由靜態(tài)一維和二維數(shù)組的獲取數(shù)組長(zhǎng)度方法可延伸至靜態(tài)多維數(shù)組獲取數(shù)組長(zhǎng)度的方法。
1)一維靜態(tài)數(shù)值型數(shù)組
[分析] sizeof()可以返回操作數(shù)所占的內(nèi)存字節(jié)數(shù),因此sizeof(a)返回的是一維數(shù)組a所占的總內(nèi)存,sizeof(a[0])返回的是數(shù)組第一個(gè)元素即該數(shù)組每個(gè)元素所占的內(nèi)存,因此sizeof(a)/sizeof(a[0])則表示的是數(shù)組a的元素個(gè)數(shù)即數(shù)組長(zhǎng)度。在C++語言中,習(xí)慣上在程序的開頭將sizeof(a)/sizeof(a[0])定義成一個(gè)宏,之后在程序中可直接調(diào)用。
2)二維靜態(tài)數(shù)值型數(shù)組
[分析] 對(duì)于圖3程序中的二維數(shù)組int a[2][4],sizeof(a)表示二維數(shù)組中所有元素所占的字節(jié)數(shù),由于a[0]指向首行地址,因此sizeof(a[0])表示該二維數(shù)組中每行元素所占字節(jié)數(shù),sizeof(int)則表示該數(shù)組元素類型(int)所占的字節(jié)數(shù),在ANSI C2.0環(huán)境下每個(gè)int類型元素所占字節(jié)為6。因此可利用sizeof(a)/sizeof(int)來求二維數(shù)組中數(shù)組元素的總數(shù),數(shù)組列數(shù)可用sizeof(a[0])/sizeof(int)來獲得,數(shù)組行數(shù)可表示為(sizeof(a)/sizeof(int))/( sizeof(a[0])/sizeof(int)),其中sizeof(int)也可以用表示數(shù)組中首個(gè)元素所占字節(jié)的sizeof(a[0][0])替換。
2.1.2 靜態(tài)字符型數(shù)組
字符型數(shù)組是指用來存放字符或字符串的數(shù)組。在C++中,給出了strlen()函數(shù)來計(jì)算給定字符串的長(zhǎng)度。該函數(shù)定義在頭文件cstring.h中,參數(shù)為C風(fēng)格字符串的頭指針,返回值是不包含空字符‘\0的字符串長(zhǎng)度,它的計(jì)算原理是順著頭指針向后掃描,直到碰到第一個(gè)字符串結(jié)束符‘\0。字符數(shù)組除了可以使用strlen()函數(shù)外,還可以使用sizeof()操作符獲取數(shù)組長(zhǎng)度。
1)字符串?dāng)?shù)組
[分析]若數(shù)組為存儲(chǔ)字符串的字符數(shù)組,即以雙引號(hào)括起來的字符串整體初始化的字符數(shù)組。在使用時(shí)可以事先定義一個(gè)比較大的數(shù)組,再用strlen()函數(shù)返回實(shí)際用到的數(shù)組元素個(gè)數(shù)。通過圖1,可以發(fā)現(xiàn)當(dāng)定義一個(gè)長(zhǎng)度為10,但實(shí)際長(zhǎng)度為6的字符串?dāng)?shù)組,strlen()函數(shù)返回的是字符串?dāng)?shù)組的實(shí)際長(zhǎng)度。原因是編譯器自動(dòng)地以‘\0來填補(bǔ)字符串?dāng)?shù)組后面的空白處。
2)字符數(shù)組
[分析] 通過對(duì)兩道程序的對(duì)比,事先定義的字符數(shù)組長(zhǎng)度不同,所產(chǎn)生的結(jié)果不同。char a[5]={‘1, ‘2, ‘3, ‘4, ‘5}在內(nèi)存的某處存在結(jié)束符‘\0,strlen()函數(shù)遇‘\0停止計(jì)算長(zhǎng)度,因此算出來的長(zhǎng)度并不是字符數(shù)組的真實(shí)長(zhǎng)度,且值是隨機(jī)的。而char a[6]={‘1, ‘2, ‘3, ‘4, ‘5}可以輸出正確的實(shí)際長(zhǎng)度的原因同字符串?dāng)?shù)組中敘述的相同,編譯器會(huì)自動(dòng)以‘\0來填補(bǔ)字符串?dāng)?shù)組后面的空白處,我們也可以寫成char a[6]={‘1, ‘2, ‘3, ‘4, ‘5, ‘\0}。
2.2 動(dòng)態(tài)數(shù)組
在C++中,動(dòng)態(tài)創(chuàng)建數(shù)組的方法主要有兩種,一種是使用new運(yùn)算符在程序運(yùn)行階段創(chuàng)建數(shù)組,還有一種是利用vector模板創(chuàng)建動(dòng)態(tài)數(shù)組。其中若使用new運(yùn)算符創(chuàng)建動(dòng)態(tài)數(shù)組,需要首先將數(shù)組的元素類型和元素?cái)?shù)目告訴new,此種情況下討論獲取數(shù)組長(zhǎng)度就沒有了意義。vector是C++中STL容器中的一個(gè)模板類,它相當(dāng)于一個(gè)動(dòng)態(tài)的數(shù)組,當(dāng)程序設(shè)計(jì)人員無法知道自己需要的數(shù)組規(guī)模是多大時(shí),可以利用vector來解決以達(dá)到最大節(jié)約空間目的。所有的STL容器都提供了一些基本方法,其中就包括size()——返回當(dāng)前vector所容納元素的數(shù)目。
2.2.1 一維動(dòng)態(tài)數(shù)組
[分析]在圖7程序中,首先建立了一個(gè)未聲明確定長(zhǎng)度的double類型的一維動(dòng)態(tài)數(shù)組,利用push_back()向數(shù)組末尾添加元素,最后利用.size()返回?cái)?shù)組中元素個(gè)數(shù)即此一維動(dòng)態(tài)數(shù)組的長(zhǎng)度。
2.2.2 二維動(dòng)態(tài)數(shù)組
[分析]由圖8中程序可以看出,創(chuàng)建一個(gè)二維動(dòng)態(tài)數(shù)組b,則該數(shù)組行數(shù)可用b.size()表示,列數(shù)可用b[0].size()表示,即:
vector
int rowCount=b.size() //行數(shù)
int colCount=b[0].size() //列數(shù)
3 有關(guān)的獲取數(shù)組長(zhǎng)度方法比較
4 常見的出錯(cuò)及解決方案
4.1 sizeof()與strlen()處理字符數(shù)組的邊界問題
[分析]對(duì)于字符串?dāng)?shù)組a,sizeof()運(yùn)算符返回的是操作數(shù)所占的內(nèi)存字節(jié)數(shù),包括字符串結(jié)束符‘\0‘,因此結(jié)果為6,而strlen()遇到結(jié)尾的結(jié)束符便返回,因此結(jié)果為5;字符數(shù)組b,聲明數(shù)組的長(zhǎng)度為6,故sizeof()返回的便是聲明中的內(nèi)存空間,而strlen()統(tǒng)計(jì)的是“\0”之前的字符數(shù),返回字符數(shù)組的實(shí)際長(zhǎng)度;對(duì)于常量字符數(shù)組c,sizeof()返回所有字符實(shí)際所占的內(nèi)存空間,而strlen()同上所述遇‘\0‘便返回。
[解決方案]在獲取字符型數(shù)組長(zhǎng)度的過程中,程序設(shè)計(jì)人員應(yīng)明確strlen()與sizeof()對(duì)于字符型數(shù)組的結(jié)束符的邊界問題。其本質(zhì)不同在于sizeof()忽略結(jié)束符的影響,將其看作一個(gè)普通字符所占字節(jié)數(shù),計(jì)算的是變量的大小,而strlen()則是將字符數(shù)組中的結(jié)束符作為長(zhǎng)度判定的依據(jù),遇‘\0‘便返回當(dāng)前結(jié)果。
4.2 數(shù)組名稱傳參問題
[分析] 通過傳遞數(shù)組名稱參數(shù)到子函數(shù)來求數(shù)組長(zhǎng)度的辦法不可行,該數(shù)組會(huì)退化為一個(gè)指針,獲取到的是一個(gè)指針的長(zhǎng)度。
[解決方案]如果想多次獲取不同數(shù)組的長(zhǎng)度,為了避免重復(fù)寫代碼,可利用C++中的template關(guān)鍵詞定義一個(gè)求數(shù)組長(zhǎng)度的模板。程序代碼如圖10所示。
5 結(jié)束語
該文總結(jié)了C++中獲取不同類型數(shù)組長(zhǎng)度方式,并利用程序?qū)嵗M(jìn)行了較為詳細(xì)的說明,有助于在以后的程序設(shè)計(jì)過程中熟練地使用數(shù)組解決相關(guān)問題。C++語言編程技術(shù)作為C語言編程的延伸和發(fā)展,能夠更好地為計(jì)算機(jī)編程服務(wù),更好地滿足現(xiàn)代化發(fā)展需求。在程序設(shè)計(jì)過程中,利用數(shù)組可以實(shí)現(xiàn)許多其他高級(jí)語言難以實(shí)現(xiàn)的功能,其中數(shù)組長(zhǎng)度更是一大靈活使用點(diǎn)。該文通過實(shí)例進(jìn)行分析與總結(jié),有助于為以后編程打下堅(jiān)實(shí)基礎(chǔ)。
參考文獻(xiàn):
[1] 許淑華. C語言中數(shù)組應(yīng)用總結(jié)[J]. 科技廣場(chǎng), 2011, 12(3): 254-256.
[2] 沈慧娟, 吳曉英. C++中指針與數(shù)組間關(guān)系探秘[J]. 信息技術(shù)與信息化, 2017, 12(4): 131-133.
[3] 鄭莉. C++語言程序設(shè)計(jì)[M]. 北京: 清華大學(xué)出版社, 2010.
[4] 李文明, 陳哲, 李緒蓉. C程序數(shù)組越界的運(yùn)行時(shí)驗(yàn)證技術(shù)研究與實(shí)現(xiàn)[J]. 計(jì)算機(jī)工程與應(yīng)用, 2015, 5(11): 190-195.
[5] 王文龍. JAVA和C++實(shí)現(xiàn)面向?qū)ο蠓椒ǖ姆治鲅芯縖J]. 喀什大學(xué)學(xué)報(bào), 2017, 5(7): 56-59.