For fun, I would like to implement some of the SQL aggregates in C: SUM (sum), AVG (average), MIN (minimum), MAX (maximum), STDEV (standard deviation), VAR (variance).
To do this in C, I’ll use functions with variable number of arguments instead of a function with an array and a count of the elements in that array. To do this, I need to have a special value for the last parameter in the variable list of arguments to know when to stop getting arguments in the list. For that, I’m going to use the INT_MIN macro in the <climits> C library. For example, to get the average of the numbers 6, 3, and 19, the call would look like AVG(6, 3, 19, INT_MIN).
SUM
Implementing this in C is lame, but I’ll use it as the starting point before getting to the other functions. I would definitely prefer to write 1 + 2 + 3 in C instead of SUM(1, 2, 3, INT_MIN).
Definition
int sum (int first, ...)
{
register int i = first;
int sum = 0;
// declare a variable argument list
va_list arg_list;
// initialize the arglist
va_start (arg_list, first);
// Sum all arguments
while(i != INT_MIN)
{
sum += i;
i = va_arg (arg_list, int);
}
// End the argument list
va_end(arg_list);
return sum;
}
Usage
printf ("Sum of (1, 2, 3, 4, 5) = %d\n", sum (1, 2, 3 , 4, 5, INT_MIN));
Output
15
AVG
Instead of writing something like (1+2+3+4)/4 or (4 + 3 + 6 + 1 + 5 + 11 + 19 + 25 + 111 + 55 + 32 + 57)/ 12, I’d rather write AVG(1, 2, 3, 4, INT_MIN) or AVG(4, 3, 6, 1, 5, 11, 19, 25, 111, 55 , 32, 57, INT_MIN) without having to count the number of numbers I’m calculating the average for.
Definition
double avg (int first, ...)
{
register int i = first;
int sum = 0, count = 0;
va_list arg_list;
va_start (arg_list, first);
// sum and count all arguments
while(i != INT_MIN)
{
sum += i;
count++;
i = va_arg (arg_list, int);
}
va_end(arg_list);
return (double) sum / count;
}
Usage
printf ("Average of (1, 2, 3, 4, 5) = %.2f\n", avg (1, 2, 3 , 4, 5, INT_MIN));
Output
3.00
MIN
Instead of implementing MIN by passing an array and the count of numbers in that array , I’d rather just pass all the numbers to the function without having to worry about creating an array and counting the number of elements inside it.
Definition
int min (int first, ...)
{
register int i = first;
int min = first;
va_list arg_list;
va_start(arg_list, first);
// Search for any other argument that is less than the first
// If you find one, then assign it to min
while(i != INT_MIN)
{
if(i < min)
min = i;
i = va_arg(arg_list, int);
}
va_end(arg_list);
return min;
}
Usage
printf ("Minimum of (10, 23, 3, 41, 15) = %d\n", min (10, 23, 3, 41, 15, INT_MIN));
Output
3
MAX
Gets the maximum number in a set.
Definition
int max (int first, ...)
{
register int i = first;
int max = first;
va_list arg_list;
va_start(arg_list, first);
// Search for any other argument that is greater than the first
// If you find one, then assign it to max
while(i != INT_MIN)
{
if(i > max)
max = i;
i = va_arg(arg_list, int);
}
va_end(arg_list);
return max;
}
Usage
printf ("Maximum of (10, 23, 3, 41, 15) = %d\n", max (10, 23, 3, 41, 15, INT_MIN));
Output
41
STDEV

Calculates the standard deviation for a set of numbers.
Definition
double stdev (int first, ...)
{
register int i = first;
int count = 0;
int sum = 0;
double mean = 0;
double deviation = 0;
va_list arg_list;
// Calculate the mean (average)
va_start(arg_list, first);
while(i != INT_MIN)
{
sum += i;
count++;
i = va_arg (arg_list, int);
}
va_end(arg_list);
mean = (float) sum / count;
// Calculate the standard deviation
i = first;
va_start(arg_list, first);
while(i != INT_MIN)
{
deviation += pow((i - mean), 2);
i = va_arg (arg_list, int);
}
deviation /= count;
deviation = sqrt(deviation);
va_end(arg_list);
return deviation;
}
Usage
printf ("Standard Deviation of (2, 4, 4, 4, 5, 5, 7, 9) = %.2f\n", stdev (2, 4, 4, 4, 5, 5, 7, 9, INT_MIN));
Output
2.00
VAR

Calculates the variance for a set of numbers.
Definition
double var (int first, ...)
{
register int i = first;
int count = 0;
int sum = 0;
double mean = 0;
double variance = 0;
va_list arg_list;
// Calculate the mean (average)
va_start(arg_list, first);
while(i != INT_MIN)
{
sum += i;
count++;
i = va_arg (arg_list, int);
}
va_end(arg_list);
mean = (float) sum / count;
// Calculate the variance
i = first;
va_start(arg_list, first);
while(i != INT_MIN)
{
variance += pow((i - mean), 2);
i = va_arg (arg_list, int);
}
variance /= (count - 1);
va_end(arg_list);
return variance;
}
Usage
printf ("Variance of (1, 2, 3, 4, 5, 6) = %.2f\n", var (1, 2, 3, 4, 5, 6, INT_MIN));
Output
3.50
Full source code is available
here.
Like this:
Like Loading...