2012-01-30 57 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