如何獲取c Array元素個數

2021-07-26 16:07:57 字數 1963 閱讀 9419

這個問題可簡單描述為:

給定乙個c++ 陣列(如:int x[10]),如何獲取它的元素個數?

一種顯而易見的方法是使用巨集(定義1):

#define countof( array ) (sizeof( array )/sizeof( array[0

]))

我不能說這種方法不正確,因為在給定乙個陣列,他確實能獲取其元素個數。然而,當提供的物件不是陣列時,同樣的表示式會給你一些不真實的結果。例如,如果你提供

int* p;
這時當執行在int指標和int擁有相同大小(如win32平台)機器上,countof( p )總是返回1。

這種巨集表示也可以錯誤接受任何有operator方法的類物件。例如,假設你寫的**如下:

class intarray  x;
此時,sizeof(x)將返回x物件的大小,而不是x.p指向buffer的大小。因此,通過countof(x),你將不能獲取正確值。

所以我們可以斷言定義1不是一種好的方法,因為編譯器不能阻止你錯用它。它不能強制只傳遞陣列。

有沒有更好的選擇呢?

是的,如果我們希望編譯器保證coutof的引數總是陣列,我們必須找到乙個只允許陣列的上下文,且同時必須拒絕所有非陣列的表示式。

一些初學者可能嘗試這樣(定義2):

template

size_t countof(t array[n])

他們認為,這個模板函式將接受大小為n的陣列,並返回n。

不幸的是,這將編譯不過,因為c++對待陣列形參等同於指標引數,也就是上述的定義等同於:

template

size_t countof(t* array)

現在顯然函式主體沒方法知道n是多少。

然而,如果傳入的引數是陣列引用,此時編譯器保證實參的大小匹配形參。這意味我們小改定義2,使其工作(定義3):

template

size_t countof(t (&array)[n])

這個countof能工作很好,且你不能傳遞指標引數。但是,它是個函式,而不是巨集。這意味著你不能用它作為編譯常數。尤其,你不能寫**如下:

int

x[10];

inty[2

*countof(x)];

我們還有其他方法嗎?

有人(我不知道具體是誰)提出更好的主意:

從函式主體移出n至返回型別,此時我們能獲取n,而不需要實際呼叫函式。

確切地說,我們必須讓函式返回乙個陣列引用,因為c ++不允許直接返回陣列。

具體實現:

template char (&_arraysizehelper(t(&array)[n]))[n];

#define

countof(array) (sizeof(_arraysizehelper(array)))

不可否認,語法看起來很糟糕。事實上,有必要做一些解釋。

首先,頂層的表述

char (&_arraysizehelper(...))[n];
表示「_arraysizehelper是返回大小為n的char陣列引用的函式」。

而後,函式引數是

t (&array)[n]
表示引用元素個數為n的t陣列。

最後,coutof被定義為函式_arraysizehelper返回值大小。注意我們沒必要定義_arraysizehelper(),一宣告足矣。

利用新的定義,

int x[10];

int y[2*countof(x)]; //twice as big as x

正如我們希望的,變為有效定義。

如何獲取元素

1 通過elementid獲取元素 引用自 autocad revit二次開發基礎教程 並通過自我編輯 已知levelid,通過id獲取元素,確認後進行其他操作 private void useelementidandgetelement document doc 2 通過element filte...

12 9 2獲取鍊錶元素個數

鍊錶中往往會儲存大量的資料內容,同時鍊錶的本質有相當於乙個陣列,那麼為了可以準確的獲取資料的個數,就需要在鍊錶中進行資料的統計操作。1 ilink 在介面中定義乙個size 方法用於返回資料儲存的個數 獲取鍊錶中集合元素的儲存個數 return 元素個數 public int size 2 link...

C DataGridView如何獲取某個資料

datagridview的幾個基本操作 1.獲取某個 指定的 單元格的值 datagridview1.row i cells j value 2.獲取選中的總行數 datagridview1.selectedrows.count 3.獲取當前選中行的索引 datagridview1.currentr...