2012-01-30 55 views
1

我試圖獲取作爲參數傳遞的某個函數的數組長度。 的代碼是這個樣子:數組和C++中的長度

double getAverage(int numbers[]) 
{ 
    int length = sizeof(numbers)/sizeof(numbers[0]); 
    // here the result of the length is 1. 
    int sum = 0; 
    for (int i = 0 ; i < length ; i++) 
    { 
     sum += numbers[i]; 
    } 
    return (double)sum/length; 
} 

int main() 
{ 
    int numbers[8] = {1,2,3,4,5,6,7,8}; 
    //if I call here sizeof(numbers)/sizeof(numbers[0] the result will be 8 as it 
    //should be. 
    cout << getAverage(numbers) << endl; 
    return 0; 
} 

我的問題是如何獲得通過引用作爲函數的參數傳遞的數組的長度(雖然我知道,每個數組通過引用傳遞)? 我知道有很多關於在C/C++中查找數組長度的問題,但是他們中沒有人給我我正在尋找的答案。 在此先感謝。

+2

它可能支付檢查出'的std ::矢量'或'的std ::陣列'。 – aligray 2012-01-30 09:48:22

+0

可能的重複[如何在C++中使用數組?](http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c) – fredoverflow 2012-01-30 10:01:48

+0

現在你可能開始理解這個問題了'sizeof(x [0])'方法的'sizeof(x [0])'方法... C++中有類型安全的替代方法(超越使用向量)來獲得在編譯時會檢測到錯誤的數組的大小。 – 2012-01-30 13:10:56

回答

3

如果你必須使用一個數組,你可以「模板化」的功能:

template <size_t length> double getAverage(int (&numbers)[length]) { 
    int sum = 0; 
    for (int i = 0 ; i < length ; i++) 
    { 
     sum += numbers[i]; 
    } 
    return (double)sum/length; 
} 
+0

當你已經有'N'常量時'length'變量的目的是什麼? – fredoverflow 2012-01-30 10:25:39

+2

您可以簡單地將'N'重命名爲'length' :) – fredoverflow 2012-01-30 10:39:36

+0

請注意,如果函數較大,則可能需要將它作爲一個函數來實現,它將長度作爲參數(或者需要teo iteratorstyle指針),然後模板(包裝器或幫助器)來獲取大小(或指針),因爲這將減少生成的代碼大小。 – 2012-01-30 13:01:36

6

您將不得不將數組的長度作爲參數顯式傳遞給函數。

傳遞給函數的只是指向數組的指針,而不是數組本身,所以除非明確地將長度作爲函數參數傳遞,否則無法確定函數內數組的長度。

你或許可以使用std::vector,它提供了成員函數來得到任何元素的載體,使用std::vector::size(),這是你能做的最好是沒有辦法這樣做,使用C風格的數組。

+0

是的我知道,但這是不是我正在尋找的方式。 就像在Java中。只需聲明一個數組並獲取它的長度: int [] arr = new int [5]; arr.length; – 2012-01-30 09:47:59

+0

@JordanBorisov:如果你正在尋找像「int length = numbers.len()」這樣的答案,那麼我對你有壞消息。獲得這種東西的唯一方法是自己編寫一個Array類,或者使用類似的現有解決方案。或另一種語言。 – PeterK 2012-01-30 09:50:58

+1

@JordanBorisov:我的回答總結了它。使用c風格的數組是不可能的。你最好使用'std :: vector'。 – 2012-01-30 09:52:36

1

您必須傳入長度作爲參數,或使用「包含」長度的std::vector。您可以使用size()方法訪問它。

4

將參數傳遞給指針時,數組衰減爲指針。你不能檢索函數內的大小信息。

你爲什麼不使用std::vector?這是C++的方式。

+0

我想我必須使用的界面 – 2012-01-30 09:54:08

1

或者使用std ::矢量(而不是INT []),它提供一個尺寸()函數

3

在運行時,也沒有以與陣列,告訴您其長度相關聯的信息。該數組幾乎「衰減」成第一個元素的地址。

在編譯時,長度是該類型的一部分,所以如果你聲明你的函數要採用例如int numbers[8]您可以使用您提到的sizeof表達式獲得長度。

當然,這意味着你只能用長度爲8的數組有效地調用該函數,這種方式有點無用。

因此,解決此問題的唯一方法是在運行時顯式添加有關陣列長度的信息,方法是在函數中添加第二個參數size_t length

在C++中,您也可以使用模板讓編譯器爲每個數組長度創建函數的專用版本,但這太浪費了。如其他人所指出的,您也可以「升級」您的抽象並使用例如std::vector<int>得到一個size()方法。這當然幾乎是一回事,vector容器添加了有關元素數量的運行時信息。

這可能不是「你正在尋找的答案」,我很抱歉。

1

您可以使用std::vectorstd::list,因爲它們都有。但是,如果您堅持要使用int[]而沒有第二個參數,則可以插入一個代碼號作爲數組的最後一個元素。這樣你可以知道結束....或者你可以保存數組的長度在其第一個元素,並正常使用其餘的。

+0

這聽起來像我喜歡某種處理數據協議。我喜歡它 – 2012-01-30 09:56:51

0

您可以使用模板:

template<std::size_t Length> 
double getAverage(int (&numbers)[Length]) 
{ 
... 
} 

,但是這可能會導致代碼膨脹,因爲編譯器將創建這適用於您通過的每個新陣列大小。將模板與參數結合使用可能會更好

template<typename T, std::size_t Length> 
std::size_t GetCount(T (&numbers)[Length]) 
{ 
    return Length; 
} 

[main]

getAverage(numbers, GetCount(numbers)); 
1

您可以通過引用傳遞數組,在這種情況下必須指定areay的大小。然而,大小固定的數組的大小可以推斷出一個模板參數:

template <int Size> 
double getAverage(int (&numbers)[Size]) { ... } 

用這種方法唯一的問題是,它會爲每個數組大小的新實例。當然,解決這個問題的方法是將開始和結束迭代器實際傳遞給執行實際工作的函數。使用上述技巧,可以使用begin()end()函數輕鬆確定迭代器。該守則將是這個樣子:

double average 
    = std::accumulate(begin(numbers), end(numbers), 0.0) 
    /std::distance(begin(numbers), end(numbers)); 
+0

+1請注意,雖然累加/距離代碼可能看起來像遍歷數組兩次,但兩個指針的距離是一個常量表達式。 – 2012-01-30 13:07:58

+0

嗯,這是一個常量_time_表達式:_constant expression_是C++中的編譯時事物,儘管可能是這樣,但它可能不是。使用這種配方的主要原因是實際上適用於任何非空容器,儘管例如對於一個列表,它將在列表中迭代兩次。後者是goid的原因,爲什麼有算法的版本取值範圍會很好。 – 2012-01-30 14:25:08

+0

對,這就是用手機寫的問題:)我的意思是時間的表達。 – 2012-01-30 19:43:31