Parsing array to function including size

Hi everyone.
I am currently trying to parsing an array to a function as a parameter.

I have been considering this article:
http://www.tutorialspoint.com/cplusplus/cpp_passing_arrays_to_functions.htm
Have a look at the function: getAverage(int arr[], int size)

It seems like you must give the size of the array in another parameter.
Is that true? Or are there any more beautiful way to do it.

Thanks for your help
Or are there any more beautiful way to do it.


Use a proper C++ container such as vector.
Moschops... Thanks. But vector is dynamic data structure.
Can't I simply parse an array?
Yes, you can simply pass an array. There is no way to know the size of an array by looking at it, so you will have to pass the size of the array as well. This is what you were complaining about. A vector does know its own size so you would not need to pass the size of it as well.

Also, "parse" means "break down according to the rules of a given grammar and syntax". "Pass" means "give to".
Yes but you can write :
1
2
3
4
5
6
7
8
9
getAverage(int *arr)
{
while(arr)
{
//Do something...
arr++;
}

}


No need to give the size of the array.
Last edited on
1
2
3
4
5
6
7
8
9
getAverage(int *arr)
{
while(arr)
{
//Do something...
arr++;
}

}


This loop will run... well, forever. It'll eventually cause a segFault, because arr will never be zero (unless you pass in a null pointer to begin with).

There is no way to tell the size of an array by looking at it. Sometimes, people choose to mark the end of the data they care about in the array with a zero value (cf C style char arrays), but that's just a convenience and it doesn't tell you anything about the size of the array.
Last edited on
Okay thanks alot.
Thats really frustrating.

It's cool i can use a while, but i still don't know the total size (to print out for instance).

But thanks a lot.
Thats really frustrating.


It's by design. The C/C++ philosophy is that you shouldn't have to pay for what you don't use. If you want a simple, fast array without overhead, you've got one. If you want something more sophisticated that keeps track of its own size, you've got one. If you don't need the more sophisticated one, you don't have to use it.
It's cool i can use a while


No, you can't. The code Jackson posted won't work in any useful way, and will either loop infinitely causing your program to hang, or else will crash.

Something similar might work if you've done something special to your array, like put in a special number that's supposed to mark the end of the array, but even then you'd have to de-reference the pointer and check the value of the object it's pointing too, rather than the pointer itself, e.g.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const int END_ARRAY_MARKER = 12345;

void myFunc()
{
  int arr[5] = {1, 2, 3, 4, END_ARRAY_MARKER};

  getAverage(arr);
}

void getAverage(int *arr)
{
   // Use a second pointer, so that arr still points to the start of the array in case you need it elsewhere
  int *arrPtr = arr; 
  while (*arrPtr != END_ARRAY_MARKER)
  {
    // Do something...
    arrPtr ++;
  }
}


But why bother? You'll have to remember to add that marker at the end of every array, and if you ever legitimately want to use that number in an array, then it will incorrectly think it's reached the end of the array too soon.

You're better off using a vector, which will manage this stuff for you, unless efficiency is really critical, in which case pass the size in along with the array. It's not that onerous to pass an extra int.

Oh, and beware of advice from Jackson Marie. He/she is, at best, an enthusiastic beginner, and often gives advice that is bad.
Thanks @MikeyBoy. I didn't know that.
But, when did you start learning programming? Did you study at a university?
Sorry, I'm just curious... :)
C++'s real power are templates.
You can do it using templates like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
template <typename Type, int Count>
Type GetAvg(Type (&Data)[Count])
{
	Type avg = Type(0);
	for(unsigned int i = 0; i < Count; ++i)
	{
		avg += Data[i];
	}
	return avg/=Count;
}
template <typename ExtraType, typename Type, int Count>
ExtraType GetAvgPrecise(Type (&Data)[Count])
{
	ExtraType avg = ExtraType(0);
	for(unsigned int i = 0; i < Count; ++i)
	{
		avg += Data[i];
	}
	return avg/=Count;
}
int main()
{
	int Test[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
	int Approximate = GetAvg(Test);
	float Precise = GetAvgPrecise<float>(Test);
}


This also works with all types, also classes, that include a += and a /= operator.

The GetAvgPrecise requires an extra type in the square ( <> ) brackets that is the return value. Usually you use float or double to avoid precision loss.
The GetAvg doesn't need any parameter - Changing the real ones will probably cast an error as you will be passing your array by reference.

As you see you are giving no size informations to GetAvg or GetAvgPrecise explicitly. Instead it's the compiler's template power that retrieves them.
Templates are in the C++ 2003 standard so should work with all modern compilers.

Oh, and, unless you overload that function, you cannot use std::vector with it. Only an array of std::vector if you want, but who uses them :|
Last edited on
But vector is dynamic data structure.
Can't I simply parse an array?

C++11 has std::array if that's closer to what you want.
http://cplusplus.com/reference/stl/array/
Topic archived. No new replies allowed.