2009年4月15日 星期三

C++多維陣列

剛剛看到的C++多維陣列注意事項
趁現在還記得就把他打成文章

int a[3][4]={};\\正常用法 沒問題
int b[][4]={};\\這也可以通過編譯
int c[3][]={};\\這不行
int d[][]={}\\這也不行


多維陣列在宣告時,只有最左邊的的[]是可以不填的
因為compile會不知道a[index]之後哪個位置的size是多少
舉個例子
int a[][7][8];
像上面的例子,從a[0]到a[1],compiler必須知道他必須跨過多少memory(mapping)
依此例子a[0]到a[1]必須跨過7*8*4 byte個位置,所以後面的數字是不可省的

再來是填value

int arr[2][3]={1,2,3,4};
for(int i=0;i<2;i++)
{
for(int j=0;j<3;j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}

出來的結果會是

1 2 3
4 0 0

多維陣列可用一維陣列填value的方式去設value
其中{...}內的元素可以小於或等於 多維陣列總大小
像上面例子arr的size是6 所以{}的元素不能多於6
不足的會自動補0 超過則會編譯不過

其中一個有趣的填法

int arr[2][3]={{1,2},3,4};
for(int i=0;i<2;i++)
{
for(int j=0;j<3;j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}


1 2 0
3 4 0

或是

int arr[2][3]={{1},2,3,4};
for(int i=0;i<2;i++)
{
for(int j=0;j<3;j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}


1 0 0
2 3 4

看到沒有,原來用預設填值的方式,{}裡面一個大括號會換一行row
如果裡面沒填滿的自動補0表示

int arr[2][3]={{1},{2,3,4}};
for(int i=0;i<2;i++)
{
for(int j=0;j<3;j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}

這樣就等於有兩個row 結果是

1 0 0
2 3 4


但是如果是

int arr[2][3]={{1},{2},3,4};
for(int i=0;i<2;i++)
{
for(int j=0;j<3;j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}

此時代表要填三個row的內容,分別是 {1},{2},{3,4}
但是此範例只有兩個row 因此會編譯不過

恐怖的多維陣列


其實上面的用法蠻冷門的,平常沒是盡量少碰
多維陣列到二維就非常恐怖了,平常我寫程式頂多也就是用到二維
用到二維以上就該想想自己程式是不是設計有問題
除非是像data mining的商業立方體(cube)
不然多維陣列其實效能相對於一維陣列是非常差
因為二維以上就必須做mapping才能取到元素(二維以上陣列的mapping 可以去研究程式語言原理)
通常能用一維陣列解決就不用多維
不然就是用一維陣列模擬二維陣列

以下一個範例

int* a[10];
int b[100];
a[0]=&b[0];
a[1]=&b[10];
......

像上面程式碼一樣,自己就做好二維陣列的mapping
此時a[0][0]就等於b[0]
a這個二維陣列是模擬出來的,效能會比真正的二維陣列還高

沒有留言: