C++ Primer 多維數(shù)組的使用
多維數(shù)組
嚴格來說,C++語言沒有多維數(shù)組,通常所說的多維數(shù)組其實是數(shù)組的數(shù)組。謹記這一點,對今后理解和使用多維數(shù)組大有益處。
當一個數(shù)組的元素仍然是數(shù)組時,通常使用兩個維度來定義它:一個維度表示數(shù)組本身大小,另外一個維度表示其元素(也是數(shù)組)大小:
int ia[3][4];//大小為3的數(shù)組,每個元素是含有4個整數(shù)的數(shù)組 //大小為10的數(shù)組,它的每個元素都是大小為20的數(shù)組, //這些數(shù)組的元素是含有30個整數(shù)的數(shù)組 int arr[10][20][30]={0};//將所有元素初始化為0
按照由內(nèi)而外的順序閱讀此類定義有助于更好地理解其真實含義。在第一條語句中,我們定義的名字是ia,顯然ia是一個含有3個元素的數(shù)組。接著觀察右邊發(fā)現(xiàn),ia的元素也有自己的維度,所以ia的元素本身又都是含有4個元素的數(shù)組。再觀察左邊知道,真正存儲的元素是整數(shù)。因此最后可以明確第一條語句的含義:它定義了一個大小為3的數(shù)組,該數(shù)組的每個元素都是含有4個整數(shù)的數(shù)組。
使用同樣的方式理解arr的定義。首先arr是一個大小為10的數(shù)組,它的每個元素都是大小為20的數(shù)組,這些數(shù)組的元素又都是含有30個整數(shù)的數(shù)組。實際上,定義數(shù)組時對下標運算符的數(shù)量并沒有限制,因此只要慈意就可以定義這樣一個數(shù)組:它的元素還是數(shù)組,下一級數(shù)組的元素還是數(shù)組,再下一級數(shù)組的元素還是數(shù)組,以此類推。
對于二維數(shù)組來說,常把第一個維度稱作行,第二個維度稱作列。
多維數(shù)組的初始化
允許使用花括號括起來的一組值初始化多維數(shù)組,這點和普通的數(shù)組一樣。下面的初始化形式中,多維數(shù)組的每一行分別用花括號括了起來:
int ia[3][4] = { // 三個數(shù)組,每個元素都是大小為4的數(shù)組 {0,1,2,3}, // 第一行的初始值 {4,5,6,7}, // 第二行的初始值 {8,9,10,11} // 第三行的初始值 }
其中內(nèi)層套著的花括號并非必需的,例如下面的初始化語句,形式上更為簡潔,完成的功能和上面這段代碼完全一樣:
//沒有標識每行的花括號,與之前的初始化語句是等價的 int ia[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
類似于一維數(shù)組,在初始化多維數(shù)組時也并非所有元素的值都必須包含在初始化列表之內(nèi)。如果僅僅想初始化每一行的第一個元素,通過如下的語句即可:
//顯式地初始化每行的首元素 int ta[3][4] = {{0},{4},{8}};
其他未列出的元素執(zhí)行默認值初始化,這個過程和一維數(shù)組一樣。在這種情況下如果再省略掉內(nèi)層的花括號,結(jié)果就大不一樣了。下面的代碼
//顯式地初始化第1行,其他元素執(zhí)行值初始化 int ix[3][4]={0,3,6,9};
含義發(fā)生了變化,它初始化的是第一行的4個元素,其他元素被初始化為0。
多維數(shù)組的下標引用
可以使用下標運算符來訪問多維數(shù)組的元素,此時數(shù)組的每個維度對應(yīng)一個下標運算符。
如果表達式含有的下標運算符數(shù)量和數(shù)組的維度一樣多,該表達式的結(jié)果將是給定類型的元素;反之,如果表達式含有的下標運算符數(shù)量比數(shù)組的維度小,則表達式的結(jié)果將是給定索引處的一個內(nèi)層數(shù)組:
//用arr的首元素為ia最后一行的最后一個元素賦值 ia[2][3]=arr[0][0][0]; int(&row)[4]=ia[1];//把row綁定到ia的第二個4元素數(shù)組上
在第一個例子中,對于用到的兩個數(shù)組來說,表達式提供的下標運算符數(shù)量都和它們各自的維度相同。在等號左側(cè),ia[2]得到數(shù)組ia的最后一行,此時返回的是表示ia最后一行的那個一維數(shù)組而非任何實際元素;對這個一維數(shù)組再取下標,得到編號為[31的元素,也就是這一行的最后一個元素。
類似的,等號右側(cè)的運算對象包含3個維度。首先通過索引0得到最外層的數(shù)組,它是一個大小為20的(多維)數(shù)組;接著獲取這20個元素數(shù)組的第一個元素,得到一個大小為30的一維數(shù)組;最后再取出其中的第一個元素。
在第二個例子中,把row定義成一個含有4個整數(shù)的數(shù)組的引用,然后將其綁定到ia的第2行。
再舉一個例子,程序中經(jīng)常會用到兩層嵌套的for循環(huán)來處理多維數(shù)組的元素:
constexpr size_t rowCnt=3,colCnt二4; intia[rowCnt][colCnt];//12個未初始化的元素 //對于每一行 for(size_t i = 0;i!=rowCnt;++i) { //對于行內(nèi)的每一列 for(stze_t j=0;j!=colCnt;++j) { //將元素的位置索引作為它的值 ia[i][j]= i *colCnt + j; } }
外層的for循環(huán)遍歷ia的所有元素,注意這里的元素是一維數(shù)組;內(nèi)層的for循環(huán)則遍歷那些一維數(shù)組的整數(shù)元素。此例中,我們將元素的值設(shè)為該元素在整個數(shù)組中的序號。
使用范圍for語句處理多維數(shù)組
由于在C++11新標準中新增了范圍for語句,所以前一個程序可以簡化為如下形式:
size_t cnt = 0; for(auto& row:ia) //對于外層數(shù)組的每一個元素 for(auto&col:row){//對于內(nèi)層數(shù)組的每一個元素 col=cnt;//將下一個值賦給該元素 ++cnt;//將cnt加1 }
這個循環(huán)賦給ia元素的值和之前那個循環(huán)是完全相同的,區(qū)別之處是通過使用范圍for語句把管理數(shù)組索引的任務(wù)交給了系統(tǒng)來完成。因為要改變元素的值,所以得把控制變量row和col聲明成引用類型。第一個for循環(huán)遍歷ia的所有元素,這些元素是大小為4的數(shù)組,因此row的類型就應(yīng)該是含有4個整數(shù)的數(shù)組的引用。第二個for循環(huán)遍歷那些4元素數(shù)組中的某一個,因此col的類型是整數(shù)的引用。每次迭代把cnt的值賦給ia的當前元素,然后將cnt加1。
在上面的例子中,因為要改變數(shù)組元素的值,所以我們選用引用類型作為循環(huán)控制變量,但其實還有一個深層次的原因促使我們這么做。舉一個例子,考慮如下的循環(huán):
for(const auto&row:ia) // 對于外層數(shù)組的每一個元素 for(auto col:row) // 對于內(nèi)層數(shù)組的每一個元素 cout<<col<<endl;
這個循環(huán)中并沒有任何寫操作,可是我們還是將外層循環(huán)的控制變量聲明成了引用類型,這是為了避免數(shù)組被自動轉(zhuǎn)成指針。假設(shè)不用引用類型,則循環(huán)如下述形式:
for(auto row : ia) for(auto col:row)
程序?qū)o法通過編譯。這是因為,像之前一樣第一個循環(huán)遍歷ia的所有元素,注意這些元素實際上是大小為4的數(shù)組。因為row不是引用類型,所以編譯器初始化col時會自動將這些數(shù)組形式的元素(和其他類垣的數(shù)組一樣)轉(zhuǎn)換成指向該數(shù)組內(nèi)首元素的指針。這樣得到的row的類型就是int*,顯然內(nèi)層的循環(huán)就不合法了,編譯器將試圖在一個int*內(nèi)遍歷,這顯然和程序的初衷相去甚遠。
要使用范圍for語句處理多維數(shù)組,除了最內(nèi)層的循環(huán)外,其他所有循環(huán)的控制變量都應(yīng)該是引用類型。
指針和多維數(shù)組
當程序使用多維數(shù)組的名字時,也會自動將其轉(zhuǎn)換成指向數(shù)組首元素的指針。
定義指向多維數(shù)組的指針時,千萬別忘了這個多維數(shù)組實際上是數(shù)組的數(shù)組。
因為多維數(shù)組實際上是數(shù)組的數(shù)組,所以由多維數(shù)組名轉(zhuǎn)換得來的指針實際上是指向第一個內(nèi)層數(shù)組的指針:
int ia[3][4];//大小為3的數(shù)組,每個元素是含有4個整數(shù)的數(shù)組 int(*p)[4]=ia;//p指向吳有4個整數(shù)的數(shù)組 p=&ia[2];//p指向ia的尾元素
我們首先明確(*p)意味著p是一個指針。接著觀察右邊發(fā)現(xiàn),指針p所指的是一個維度為4的數(shù)組;再觀察左邊知道,數(shù)組中的元素是整
數(shù)。因此,p就是指向含有4個整數(shù)的數(shù)組的指針。
在上述聲明中,括號必不可少:
int*ip[4]//整型指針的數(shù)組 int(*ip)[4];//指向舍有4個整數(shù)的數(shù)組
隨著C++11新標準的提出,通過使用auto或者decltype就能盡可能地避免在數(shù)組前面加上一個指針類型了:
//輸出a中每個元素的值,每個內(nèi)層數(shù)組各占一行 //p指向含有4個整數(shù)的數(shù)組 for(auto p=ia;p!=ia+3;++p) //q指向4個整數(shù)數(shù)組的首元素,也就是說,q指向一個整數(shù) for(auto q=*p;q!=*p+4;++q) cout<< *q << ' '; cout<<endl;
外層的for循環(huán)首先聲明一個指針p并令其指向ia的第一個內(nèi)層數(shù)組,然后依次迭代直到ia的全部3行都處理完為止。其中遞增運算++p負責將指針p移動到ia的下一行。
內(nèi)層的for循環(huán)負責輸出內(nèi)層數(shù)組所包含的值。它首先后指針q指向p當前所在行的第一個元素。*p是一個含有4個整數(shù)的數(shù)組,像往常一樣,數(shù)組名被自動地轉(zhuǎn)換成指
向該數(shù)組首元素的指針。內(nèi)層for循環(huán)不斷迭代直到我們處理完了當前內(nèi)層數(shù)組的所有元素為止。為了獲取內(nèi)層for循環(huán)的終止條件,再一次解引用p得到指向內(nèi)層數(shù)組首元素的指針,給它加上4就得到了終止條件。
當然,使用標準庫函數(shù)begin和end也能實現(xiàn)同樣的功能,而且看起來更簡潔一些:
//p指向ia的第一個數(shù)組 for(auto p=begin(ia);p!=end(ia);++p){ //q指向內(nèi)層數(shù)組的首元素 for(auto q=begin(*p);q!=end(*p);++q) cout<<*q<<' ';//輸出q所指的整數(shù)值 cout<<endl;
在這一版本的程序中,循環(huán)終止條件由end函數(shù)負責判斷。雖然我們也能推斷出p的類型是指向含有4個整數(shù)的數(shù)組的指針,a的類型是指向整數(shù)的指針,但是使用auto關(guān)鍵字我們就不必再煩心這些類型到底是什么了。
類型別名簡化多維數(shù)組的指針
讀、寫和理解一個指向多維數(shù)組的指針是一個讓人不勝其煩的工作,使用類型別名能讓這項工作變得簡單一點兒,例如:
using int_array=int[4];//新標準下類型別名的聲明 typedef int int_array[4];//等價的typedef聲明 //輸出ia中每個元素的值,每個內(nèi)層數(shù)組各占一行 for(int_array * p=ia;p!=ia+3;++p){ for(int*q=p;q!=*p+4;++q) cout<<*q<< ' '; cout<<endl; } 程序?qū)㈩愋汀?個整數(shù)組成的數(shù)組“和名為int_array,用類型名int_array定義外層循環(huán)的控制變量讓程序顯得簡潔明了。
到此這篇關(guān)于C++ Primer 多維數(shù)組的使用的文章就介紹到這了,更多相關(guān)C++ 多維數(shù)組內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
COLORREF,COLOR,RGB,CString的轉(zhuǎn)化總結(jié)分析
實際的軟件開發(fā)過程中,常需要用到非.net平臺的代碼。這時候就可能碰到ColorRef(也就是以int類型代表的顏色值或是以DWORD值表示的顏色)。這跟.net平臺下的顏色的相互轉(zhuǎn)換MS并沒有直接實現(xiàn)2013-09-09C++實現(xiàn)隨機數(shù)生成的現(xiàn)代化封裝
在現(xiàn)代?C++?中,隨機數(shù)生成是許多程序設(shè)計中不可或缺的部分,例如游戲開發(fā)、算法設(shè)計、統(tǒng)計模擬等,本文將以一個封裝好的隨機工具類?Random?為例,深入剖析其功能的實現(xiàn)與使用,并引入相關(guān)知識,幫助讀者觸類旁通,掌握?C++?隨機數(shù)的核心技巧2024-11-11一文詳解如何實現(xiàn)QT的多語言切換(靜態(tài)+動態(tài))
這篇文章主要給大家介紹了關(guān)于如何實現(xiàn)QT的多語言切換(靜態(tài)+動態(tài))的相關(guān)資料,Qt是一款跨平臺的C++應(yīng)用程序開發(fā)框架,提供了一套豐富的工具和類庫來簡化應(yīng)用程序開發(fā),文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-06-06