For a homework assignment I need to write a function that computes the average value of an array of floating-point data:

double average(double* a, int a_size)

In the function, use a pointer variable, and not an integer index, to traverse the array elements.

The code below is what I have so far but I don't know what I can do to make it better. Any help or comments will be appreciated!

Dennis

#include <iostream>

using namespace std;

double average (double* a, int a_size)
{
	double total;
	double average;
	double* p = a;

	for (int i = 1; i < a_size; i++)
	{
		total = total + a[i];
		average = total / a_size;
	}
    return average;
}
      
int main()
{
     return 0;
}

Line 9 - You create the pointer variable, but never use it.

Line 13 - You're using an array index, which the assignment does not allow.

You need to change line 13 to this:

total = total + *p;

and you need to adjust the p pointer. If p points to a[5], then this line:

p++;

will make it point to a[6].

But there are other problems too. I suggest you write it using array indexes first, then when that works, convert it to use pointers.

I'm just wondering, is there a way to compute the arithmetic mean without using a summation like the normal algorithm does?

I'm just wondering, is there a way to compute the arithmetic mean without using a summation like the normal algorithm does?

The "accumulate" function will add it up for you.

http://www.cppreference.com/wiki/algorithm/accumulate

But with the "no array indexes, must use pointers" stipulation, I think the OP is expected to loop through the elements and add them, then divide by the number of elements. I can't think of any other way.

After a google search I found out that Knuth (the programming book author) has in his second edition something like this (this is my implementation):

#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <ctime>

int main()
{
	typedef unsigned int uint;
	const uint cSize = 99999;
	uint data[cSize] = {0};
	srand(uint(time(nullptr)));
	std::for_each( data, data+cSize, [](uint &n) {
		//
		n = rand();
	});

	double M = 0.0;//,
		//S = 0.0;
	for(uint i = 0; i < cSize; ++i){
		//
		M += (data[i] - M)/(i+1);// <<<----ATTENTION HERE.
		if( (std::numeric_limits<double>::max() - M) < 1000 )
			std::cerr << "WARNING!!!" << std::endl;
	}
	//std::for_each(data, data+cSize, [](uint n){
	//	std::cout << n << ' ';
	//});
	std::cout << M << std::endl;
	std::cin.get();
}

I used a lambda or two so if you want to use it with an older compiler you will need to make adjustments.

Line 19 - 24 --> If you are worried about overflow errors, you are correct. You can't add everything up, then stick it in a variable, then divide, because it's overflowed, so your method would work in that case, whereas adding them all up, then dividing them would not.

If you are not worried about overflow, however (i.e. 100 numbers, all less than a million), you're making far more calculations (100 additions, 100 divisions, 100 subtractions) than the other method (100 additions, 1 division), so it's slower.

I'm not sure which method is better as far as round-of error.

Can you post a link? I'd be interested in reading that page to see if Knuth talks about overflow and when he suggests to use which methods.

My source is stack overflow, a person citing Knuth as his source. Unfortunately I've lost the page, and there wasn't a better answer as far as I was concerned. You can google it, however.

Perhaps I should re-phrase my previous post in which it sounded as if it was fact that Knuth had something to say about this--it was another who claimed so. I would have to read it myself to know for certain.

No need to create extra pointers - just dereference and increment.

double average (double* a, int a_size){
    double total = 0.0;     
    for (int i = 0; i < a_size; i++)
        total += *a++;
    return total / a_size;
}

user422, it's perfectly fine if you understand the order of operations with regard to * and ++, but I don't remember them exactly so I typically will include parentheses, even when not required, so as to make more clear the intent.

user422, it's perfectly fine if you understand the order of operations [...]

Good point. Just make sure its *(a++) and not (*a)++
Or try both and observe what happens.

Surprised none mentioned the use of const.

float computeAverage(const float data[], const int DATA_SIZE){
   return std::accumulate(data, data + DATA_SIZE, 0)/ float(DATA_SIZE);
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.