2012-06-24 199 views
2

我放棄了試圖將2d數組傳遞給函數,其中尺寸在編譯時未知。經過一番研究,似乎二維矢量可能是一個很好的替代品。我只是想確認這是申報尺寸totalRows X totalColumns的2D矢量,initializaing每個單元包含空格字符的正確方法:2d矢量初始化

vector<vector<char> > world(totalRows, vector<char>(totalColumns, ' ')); 
+3

這是有點濫用。矢量向量不一定是二維數組,因爲每行可以有不同的長度。請注意,1d和2d數組之間的區別主要是句法,因此您不必打擾2d數組語法。這條線看起來沒問題。 –

+0

您的規格有點不完整。例如,你是否想要強制所有行(或所有列,取決於你喜歡矩陣的方式)是相同的長度?矢量矢量在這裏幫不了你。向量矢量不一定會佔用連續的內存塊,這可能會有性能問題。你也會發現支持const正確性很棘手。 – Rook

回答

4

你的代碼工作。正如在評論中注意到的那樣,vector<vector<T>>並不是真正的二維數組。

最重要的這裏的事情是,(totalRows, vector<char>(totalColumns, ' '))(totalColumns, vector<char>(totalRows, ' '))是等價的,只要你始終遵循用於創建矢量的規則:line x column(或column x line

+0

嗯,所以按照我的方式,我可以訪問矢量元素: world [row] [column]? – AlmostSurely

+1

是的,因爲'world [row]'返回對特定行向量的引用,然後你用'[column]'得到元素。 – Synxis

9

線本身應該工作,看起來不錯。但讓我提供更多信息。

嘗試使用標準庫是一個不錯的主意。有了這個說法,你需要明白,你頭上的二維數組圖像必須在內存中線性地存在。你可以很容易地創建一個m * n元素的向量(在你的例子中),並將其按行(i * n + j)排序(主要從零開始計數)。

事實上,這就是「二維」陣列的工作方式。例如,當您執行常規元素陣列 - T[][]時,如果您嘗試將其衰減爲指針,它將是一個簡單的T*。在引擎蓋下,記憶被連續地和線性地佈置,沒有形狀,只有一條長長的街道(正如電腦所看到的那樣)。它只是通過使用第一段中的表達式(或類似表達式)來推斷行和列的概念。電腦不在乎。

vector是標準庫的一個不錯的部分,它以一種簽名C++(而不僅僅是臃腫C)的方式封裝數組。它的設計非常容易調整內部數組數據結構的大小,並且隨着C++ 11的出現,移動語義可以調整更便宜的操作。此外,RAII的概念適用於此,仔細初始化構造函數中的數據成員並在析構函數中減輕它們的想法使您能夠避免動態內存分配問題作爲用戶,並簡單地在堆棧上傳播新對象,並在需要時傳遞引用以「退出」他們的範圍。

有一點需要注意的是,vector會創建一個內存塊,這個數組可能會因爲彈出和推送新元素而有時超過實際數組的大小。另外,你並沒有義務首先定義它的大小,但是可以通過push_back,push_front等方便地擴展它。這意味着其他事情可以即時改變,並且擴展會花費你相當多的成本,即使是移動語義。

離開載體的唯一原因是當你正在做一些沉重的3D渲染或模擬,這些渲染或模擬是面向數據的,並期望數據以一些非常自定義的特定方式打包並手動整理, vector可能不容易。但是這會讓你進入更低級的裸陣列領域(你應該準備好了)。你應該從中獲得關鍵的東西,你可以簡單地將「心理二維數組」向量(實際上,數據沒有真正的幾何形狀,這就是我們如何,簡單的人類,看到它)作爲向量,並將它們以不同的方式編入索引。確保你逐個輸入所有的行數據,你將得到一個非常簡單的佈局,可以用(i * n + j)簡單地探測/索引,其中[i,j]是經典的二維矩陣下標/索引。

然後,它可能是簡單的:

vector<char> world(totalRows*totalColumns, ' '); 

然後你簡單地通過參看需要的地方去傳球,索引它(我* N + J),你把它的數據後,正常。

您的代碼應該可以工作,但不必要的膨脹可能會在嘗試操縱數據時將其引入不必要的精神開銷,將它轉移並寫入不必要的內容,遠遠小於實際使用i * n + j「手動索引」方法保持你的二維數組/字符矩陣的心理圖像。如果你願意,你甚至可以覆蓋功能,以添加語法糖。