(原創) 由一維陣列模擬二維陣列(多維陣列) (C/C++)
C/C++的陣列是有名的難用!!沒有『真正』支援多維陣列,陣列傳到參數時還必須寫死(C++若用template可不用寫死),若是動態的多維陣列就更難寫了,C/C++還必須到一定的功力才寫的出來!!既然C/C++骨子是用一維陣列『模擬』多維陣列,那我們就乾脆直接用一維陣列去『處理』多維陣列。
用一維陣列去處理多維陣列有幾個好處:
1.寫法較簡單。
2.陣列傳到函數時,參數不用寫死。
以下我們就實際的看看怎麼寫...
?2(C)?OOMusou?2007?http://oomusou.cnblogs.com
?3
?4Filename????:?ArrayOneDimSimMultiDim.cpp
?5Compiler????:?Visual?C++?8.0?/?gcc?3.4.2?/?ISO?C++
?6Description?:?Demo?how?to?use?1?dim?array?to?simulate?multi?dim?array
?7Release?????:?02/19/2007?1.0
?8*/
?9
10#include?<iostream>
11
12using?namespace?std;
13
14void?func1(int?(*ia)[3],int?sizex,?int?sizey)?{
15??cout?<<?"By?2?dim?array?:?"?<<?endl;
16??for(int?y?=?0;?y?!=?sizey;?++y)?{
17????for(int?x?=?0;?x?!=?sizex;?++x)?{
18??????//?cout?<<?ia[y][x]?<<?endl;
19??????cout?<<?*(*ia?+?y?*?sizex?+?x)?<<?"?"?;
20????}
21????cout?<<?endl;
22??}
23}
24
25void?func2(int?*ia,?int?sizex,?int?sizey)?{
26??cout?<<?"By?1?dim?array?simulate?2?dim?array:"?<<?endl;
27??for(int?y?=?0;?y?!=?sizey;?++y)?{
28????for(int?x?=?0;?x?!=?sizex;?++x)?{
29??????cout?<<?*(ia?+?y?*?sizex?+?x)?<<?"?";
30????}
31????cout?<<?endl;
32??}
33}
34
35void?func3(int?(*ia)[2][3],?int?sizex,?int?sizey,?int?sizez)?{
36??cout?<<?"By?3?dim?array?:?"?<<?endl;
37??for(int?z?=?0;?z?!=?sizez;?++z)?{
38????for(int?y?=?0;?y?!=?sizey;?++y)?{
39??????for(int?x?=?0;?x?!=?sizex;?++x)?{
40????????//?cout?<<?ia[z][y][x]?<<?endl;
41????????cout?<<?*(**ia?+?z?*?sizey?*?sizex?+?y?*?sizex?+?x)?<<?"?";
42??????}
43??????cout?<<?endl;
44????}
45????cout?<<?endl;
46??}
47}
48
49void?func4(int?*ia,?int?sizex,?int?sizey,?int?sizez)?{
50??cout?<<?"By?1?dim?array?simulate?3?dim?array:?"?<<?endl;
51??for(int?z?=?0;?z?!=?sizez;?++z)?{
52????for(int?y?=?0;?y?!=?sizey;?++y)?{
53??????for(int?x?=?0;?x?!=?sizex;?++x)?{
54????????//?cout?<<?ia[z][y][x]?<<?endl;
55????????cout?<<?*(ia?+?z?*?sizey?*?sizex?+?y?*?sizex?+?x)?<<?"?";
56??????}
57??????cout?<<?endl;
58????}
59????cout?<<?endl;
60??}
61}
62
63int?main()?{
64??const?int?sizex?=?3;
65??const?int?sizey?=?2;
66??const?int?sizez?=?2;
67??
68??int?ia1[][3]?=?{{1,?2,?3},
69??????????????????{4,?5,?6}};
70??
71??int?ia2[]?=?{1,?2,?3,?4,?5,?6};
72??
73??int?ia3[][2][3]?=?{{{1,?2,?3},
74??????????????????????{4,?5,?6}},
75?????????????????????{{7,?8,?9},
76??????????????????????{10,11,12}}};
77??
78??int?ia4[]?=?{1,?2,?3,?4,?5,?6,?7,?8,?9,?10,?11,?12};
79??????????????????
80??func1(ia1,?sizex,?sizey);
81??cout?<<?endl;
82??func2(ia2,?sizex,?sizey);
83??cout?<<?endl;
84??func3(ia3,?sizex,?sizey,?sizez);
85??cout?<<?endl;
86??func4(ia4,?sizex,?sizey,?sizez);
87}
執行結果
1?2?3
4?5?6
By?1?dim?array?simulate?2?dim?array:
1?2?3
4?5?6
By?3?dim?array?:
1?2?3
4?5?6
7?8?9
10?11?12
By?1?dim?array?simulate?3?dim?array:
1?2?3
4?5?6
7?8?9
10?11?12
68行ia1為一個二維陣列,71行ia2則為相同資料的一維陣列,14行的func1處理ia1這個二維陣列,25行的func2則處理ia2這個一維陣列。
14行int (*ia)[3],參數必須寫死,此為C/C++陣列語法的問題,但若用25行的一維陣列,int *ia則不用寫死。
若用二維陣列,最大的好處是可以使用18行subscripting寫法,較為直觀,若用pointer寫法,就必須用19行的寫法,由於2維陣列是array of array,所以需兩個pointer,比較29行一維陣列的寫法,其實幾乎完全一樣,差別只在於一個pointer而已,因為C/C++沒有『直接』支援多維陣列,在記憶體中仍使用一維陣列配置記憶體,所以寫法才會類似,因此雖然用了一維陣列,但寫法卻一樣是兩層迴圈,和二維陣列一樣,若配合其他演算法,並不會覺得特別難用。
73行的ia3為三維陣列,78行的ia4為相同資料的一維陣列,func3和func4則對應處理之。
最後要提醒的是,用一維陣列處理三維陣列的公式如下
陣列ia的x(個數sizex),y(個數sizey),z(個數sizez)
address = ia + z * (sizex * sizey) + y * (sizex) + x
更多維度則類推之。
本文只提到靜態的方式由一維陣列模擬二維陣列,若要用動態的方式由一維陣列模擬二維陣列,請參閱(原創) 如何動態建立一維陣列? (初級) (C/C++)。
Conclusion
用一維陣列去模擬多維陣列,寫法一樣,但卻大幅簡化了C/C++的語法,可將重心擺在演算法上,而不用跟C/C++語法搏鬥。
Remark
在撰寫處理陣列的迴圈時,應該先從z,再y,最後才是x,為什麼呢?因為當宣告陣列時,是int ia[sizey][sizex],所以是先y,然後才x。
See Also
(原創) 如何使用function template傳遞array? (C/C++) (template)
(原創) 如何動態建立一維陣列? (C/C++)
(原創) 如何動態建立二維陣列(多維陣列)? (C/C++)
(原創) 如何動態建立二維陣列(多維陣列)? (C/C++)
Reference
多維矩陣轉一維矩陣
總結
以上是生活随笔為你收集整理的(原創) 由一維陣列模擬二維陣列(多維陣列) (C/C++)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我们的归宿
- 下一篇: WPF - 资源收集