Reputation: 1652
I'm trying to get the length of an array passed as a parameter on some function. The code is look like this :
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;
}
My question is how to get the array length which is passed as argument of a function by reference(although I know that every array is passed by reference)? I know that there is a lot of questions about finding the array length in C/C++ but no one of them give me the answer which I'm looking for. Thanks in advance.
Upvotes: 1
Views: 522
Reputation: 2832
If you must use an array, you could 'templatize' your function:
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;
}
Upvotes: 2
Reputation: 153840
You can pass an array by reference in which case the areay size has to be specified. However, the size of a statically sized array can be deduced for a template argument:
template <int Size>
double getAverage(int (&numbers)[Size]) { ... }
The only problem with this approach is that it creates a new instantiation for each array size. Of course, the fix to this is to actually pass begin and end iterators to the function doing the actual work. The iterators can easily be determined using begin()
and end()
functions using the trick above. The code would look something like this:
double average
= std::accumulate(begin(numbers), end(numbers), 0.0)
/ std::distance(begin(numbers), end(numbers));
Upvotes: 1
Reputation: 10562
You can use templates:
template<std::size_t Length>
double getAverage(int (&numbers)[Length])
{
...
}
but this may lead to code bloat as the compiler will create this for every new array size you pass in. You might be better off combining a template with a parameter
template<typename T, std::size_t Length>
std::size_t GetCount(T (&numbers)[Length])
{
return Length;
}
[main]
getAverage(numbers, GetCount(numbers));
Upvotes: 0
Reputation: 399833
At run-time, there is no information associated with an array that tells you its length. The array pretty much "decays" into just the address of the first element.
At compile-time, the length is part of the type, so if you declare your function to take e.g. int numbers[8]
you can get the length using the sizeof
expression you mention.
Of course, this means you can only validly call the function with arrays of length 8, which kind of makes it a bit useless.
Thus, the only way around this is to explicitly add information at run-time about the array's length, by adding a second size_t length
argument to the function.
In C++, you could also use templates to have the compiler create specialized versions of the function for each array length, but that is kind of wasteful.
As pointed out by others, you can also "level up" your abstraction and use e.g. std::vector<int>
to get a size()
method. That is of course pretty much the same thing, the vector
container adds run-time information about the number of elements.
This might not be "the answer which you're looking for", I'm sorry about that.
Upvotes: 3
Reputation: 13309
You can use std::vector
, or std::list
as all have give. But if you are adamant that you want to use an int[]
without a second argument, then you can insert a code number as the last element of the array. that way you can know the end.... Or u can save the length of the array in its first element and use the rest normally.
Upvotes: 1
Reputation: 958
Or use std::vector (instead of int[]) which provides a size() function
Upvotes: 1
Reputation: 258608
Arrays decay to pointers when passing them as parameters. You can't retrieve size information inside the function.
Why aren't you using std::vector
? It's the c++ way.
Upvotes: 4
Reputation: 1607
You have to pass in the length as a parameter, or use std::vector
which "contains" the length. You can access it with the size()
method.
Upvotes: 1
Reputation: 206526
You will have to explicitly pass the length of the array as an parameter to the function.
What you pass to the function is just an pointer to the array, not the array itself, so there is no way to determine the length of the array inside the function unless you explicitly pass the length as an function parameter.
You can probably use std::vector
, which provides member functions to get no of elements in the vector, using std::vector::size()
, that is the best you can do there is no way to do so using c-style arrays.
Upvotes: 6