Functions that accept various type?

Q

QQ

I have two 'mean' functions, one to handle an integer array, and one to
handle a double array (see code provided below). Is there a way to write a
single 'mean' function that would take either an array of ints or an array
of doubles?

Thanks.

-------------------
#include <stdio.h>

double int_mean (int * array, int num_elem)
{
int i, sum = 0;
for (i = 0; i < num_elem; i++)
sum += array;
return (double)sum/(double)num_elem;
}

double double_mean (double * array, int num_elem)
{
int i;
double sum = 0.0;
for (i = 0; i < num_elem; i++)
sum += array;
return sum/num_elem;
}

int main ()
{
int i;
int array_size = 5;
int * int_array = (int *)malloc(sizeof(int) * array_size);
double * double_array = (double *)malloc(sizeof(double) * array_size);
for(i = 0; i < array_size; i++)
{
int_array = 0;
double_array = 0.0;
}
int_array[1] = 4;
double_array[3] = 2.1;

printf ("%lf, %lf\n", int_mean (int_array, array_size), double_mean
(double_array, array_size));

return 1;
}
 
J

Jack Klein

I have two 'mean' functions, one to handle an integer array, and one to
handle a double array (see code provided below). Is there a way to write a
single 'mean' function that would take either an array of ints or an array
of doubles?

Thanks.

Yes, but it doesn't save you much.

enum array_type { INT, DOUBLE };

double int_mean (int * array, int num_elem)
{
int i, sum = 0;
for (i = 0; i < num_elem; i++)
sum += array;
return (double)sum/(double)num_elem;
}

double double_mean (double * array, int num_elem)
{
int i;
double sum = 0.0;
for (i = 0; i < num_elem; i++)
sum += array;
return sum/num_elem;
}


Now replace these two functions with this one:

double mean(void * array, int num_elem, array_type type)
{
double result = 0.0;

if (INT == type)
{
/* code from your int_mean function, change */
/* return statement to: */
result = (double)sum/num_elem; /* only need to cast one */
}
else if (DOUBLE == type)
{
/* code from your double_mean function */
}
else
{
/* decide if you are happy with just returning 0.0, */
/* or calling exit() or abort() or some other error */
/* handling */
}
return result;
}
int main ()
{
int i;
int array_size = 5;
int * int_array = (int *)malloc(sizeof(int) * array_size);
double * double_array = (double *)malloc(sizeof(double) * array_size);
for(i = 0; i < array_size; i++)
{
int_array = 0;
double_array = 0.0;
}
int_array[1] = 4;
double_array[3] = 2.1;

printf ("%lf, %lf\n", int_mean (int_array, array_size), double_mean
(double_array, array_size));

return 1;
}
 
A

Antoine Mathys

I have two 'mean' functions, one to handle an integer array, and one to
handle a double array (see code provided below). Is there a way to write a
single 'mean' function that would take either an array of ints or an array
of doubles?

Yes, it is called C++.
 
M

Malcolm

QQ said:
I have two 'mean' functions, one to handle an integer array, and one to
handle a double array (see code provided below). Is there a way to write a
single 'mean' function that would take either an array of ints or an array
of doubles?
The C++ way is to use templates.

In C, you could use a typedef to toggle between versions. If the functions
are static this means you can have two versions in one program, but
unfortunately not in scope at the same time.

There is no other practical way of doing it.

For the general problem, however, you would solve it by writing

/*
take mean of addable objects
el - elemets
elsize - size of each element
N - number of elements
add - function to add an element to a double
*/
double mean(void *el, size_t elsize, int N, double (*add)(void *, double))
{
int i;
double tot = 0;
unsigned char *ptr = el;

for(i=0;i<N;i++)
tot += add( &ptr[i*elsize], tot);

return tot/N;
}

This is obviously ridiculous for "mean", but the general principle can be
used for more complex problems, where it may make some sense.
 
H

Herbert Rosenau

I have two 'mean' functions, one to handle an integer array, and one to
handle a double array (see code provided below). Is there a way to write a
single 'mean' function that would take either an array of ints or an array
of doubles?

Thanks.
double int_mean (int * array, int num_elem)
{
int i, sum = 0;
for (i = 0; i < num_elem; i++)
sum += array;
return (double)sum/(double)num_elem;
}

double double_mean (double * array, int num_elem)
{
int i;
double sum = 0.0;
for (i = 0; i < num_elem; i++)
sum += array;
return sum/num_elem;
}


replace with

/* closed in itself */
#define MEAN(sum, a, n) { \
int i; \
for (i = 0, sum = 0; i < (n)); i++) \
sum += a; \
}

OR
/* requires defition of i outside this macro */
#define MEAN(sum, a, n) \
for (i = 0, sum = 0; i < (n); i++) \
sum += a;
int main ()
{
int i;
int array_size = 5;
int * int_array = (int *)malloc(sizeof(int) * array_size);
superflous cast, hiding the fact that stdlib.h is not included,
producing undefined behavior.

int isum;
double * double_array = (double *)malloc(sizeof(double) * array_size);
superflous cast, hiding missing #include <stdlib.h>, producing
undefined behavior
double dsum;
for(i = 0; i < array_size; i++)
{
int_array = 0;
double_array = 0.0;
}
int_array[1] = 4;
double_array[3] = 2.1;

printf ("%lf, %lf\n", int_mean (int_array, array_size), double_mean
(double_array, array_size));

mismatch type in format list with actual parameter

replace with
MEAN(isum, int_array, array_size);
MEAN(dsum, double_array, array_size);
prinf("%d, %lf\n", isum, dsum);


return 1;
}


--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
L

Lawrence Kirby

I have two 'mean' functions, one to handle an integer array, and one to
handle a double array (see code provided below). Is there a way to write a
single 'mean' function that would take either an array of ints or an array
of doubles?

It can be done as others have indicated. It isn't usually a good solution
however.

consider making that const int *array
int i, sum = 0;
for (i = 0; i < num_elem; i++)
sum += array;
return (double)sum/(double)num_elem;
}


Also consider that INT_MAX need not be larger than 32767. Are you sure
that is always enough to represent the sum for the array? Could num_elem
be zero?

Lawrence
 
A

Antoine Mathys

double int_mean (int * array, int num_elem)
mismatch type in format list with actual parameter

No way, both functions return a double. You could be a bit more careful
before correcting others.
 
O

Old Wolf

Herbert said:
mismatch type in format list with actual parameter

replace with
MEAN(isum, int_array, array_size);
MEAN(dsum, double_array, array_size);
prinf("%d, %lf\n", isum, dsum);
(I guess you mean printf)

Passing %lf to printf is undefined behaviour in C89. I suppose
you are confusing it with scanf() where %lf means to read a
double. (I think that in C99 they defined %lf as being the
same as %f, simply because it is such a common error).
 
O

Old Wolf

Herbert said:
mismatch type in format list with actual parameter

replace with
MEAN(isum, int_array, array_size);
MEAN(dsum, double_array, array_size);
prinf("%d, %lf\n", isum, dsum);
(I guess you mean printf)

Passing %lf to printf is undefined behaviour in C89. I suppose
you are confusing it with scanf() where %lf means to read a
double. (I think that in C99 they defined %lf as being the
same as %f, simply because it is such a common error).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top