How to do simple average calculation using a function & calling it? - c

I need to learn how to use the function for the calculation and then a simple call in main. When I tried it didn't work. I have no idea what to do. It works but when I take out the code from main it gets funky.
this is simple simple scenario and code for that.
Write a function that takes an array of ints, and the size of the array - another int.
It also returns a double. Call this one 'average.' Return a double that is the average
of the values in the array. Demonstrate that it works by finding the average of an array
with these values {78, 90, 56, 99, 88, 68, 92}
#include <stdio.h>
#include <stdlib.h>
// Outside of main, a function will be declared that takes an array of ints.
double Function(int Array[7])
{
// int Array[7] = {78, 90, 56, 99, 88, 68, 92};
int sum = 0;
int i;
double average;
// This for loop allows us to use all 7 elements in the array.
for(i=0; i<7; i++)
{
// This takes all the array's elements and sums them up.
sum += Array[i];
}
// This prints the sum
printf("Sum = %d\n", sum);
// The double average is found by taking the sum found and dividing it by 7.
average = sum/7;
// This prints the average in a double.
printf("The resulting average is %lf \n", average);
return average;
} // Ends Function
// There will also be the size of the array(which is another int)
// The function will return a double called average. It is the average of the values in the array.
int main()
{
//int i; // Allows us to use the for loop and print each element in the corresponding array.
// int array numbers are declared and initialized.
int Array[7] = {78, 90, 56, 99, 88, 68, 92};
int sum = 0;
int i;
double average;
// This for loop allows us to use all 7 elements in the array.
for(i=0; i<7; i++)
{
// This takes all the array's elements and sums them up.
sum += Array[i];
}
// This prints the sum
printf("Sum = %d\n", sum);
// The double average is found by taking the sum found and dividing it by 7.
average = sum/7;
// This prints the average in a double.
printf("The resulting average is %lf \n", average);
Function(Array);
system("pause");
return 0;
}
Can any one give me a tips!

If you want to follow the instruction you were given, your function declaration should be
double average(int *array, int array_size)
Also, your solution should be general, not only for array with length of 7.
In general in C language - when you want to pass an array which its length is unknown, you pass the address of the array (here *array) and its size (here array_size). Then your function will iterate over the array from the given address, with jumps of the type (here jumps of sizeof(int) because it's an array of ints).

In C Program execution always starts from main.
So the stack will be like
main()-->Function()
You are almost right just you called the function which returns the average so to keep that average or to accept that average in main you need variable so just remove all the code shown below
for(i=0; i<7; i++)
{
// This takes all the array's elements and sums them up.
sum += Array[i];
}
// This prints the sum
printf("Sum = %d\n", sum);
// The double average is found by taking the sum found and dividing it by 7.
average = sum/7;
// This prints the average in a double.
printf("The resulting average is %lf \n", average);
Now take the results returned by the Function() in average variable shown below.
average=Function(Array);
Now print that value if you want to print or use in main if you need.

the posted code contains several misconceptions
no need to '#include' header files those contents are not needed.
only write code that is part of the solving of the problem. Other code that is added for 'debug' purposes should be eliminated from the final executable. Usually be surrounding the debug code with: #ifndef NDEBUG .... #endif Suggest learning how to work with NDEBUG
The problem only needs to solved once, not both in 'main()' and in 'Function()' BTW: function is a terrible function name suggest: calculateAverage(). Function names should indicate what they will perform, usually by starting the function with some active verb, like calculate
for ease of readability and understanding, consistently indent the code. Indent after every opening brace '{'. unindent before every closing brace '}'. Suggest each indent level be 4 spaces as that is wide enough to be visible even with variable width fonts. Remember, the compiler (in general) doesn't care about the 'style' of the code formatting. However, any human cares a lot, because the human wants to be able to read the code.
it is (almost always) a bad idea to hard code any values other than 0 and 1. Instead give them meaningful names via a enum statement or #define statements, then use those meaningful names throughout the code.
Please pay attention to these 3 details in the code:
how the size of the array is calculated
how the parameters are passed to the 'Function()'
how the average is calculated.
Note: when all the variables in a divide operation are integers, then a integer divide is performed. This can produce some surprising results.
For instance, 5/3 results in 1, not 1.66.
by wanting to keep the fraction, cast one of the elements (not the whole expression) to double or float
and now the code
#include <stdio.h> // printf()
//#include <stdlib.h>
double Function(int *pArray, int numElements );
int main( void )
{
// int array numbers are declared and initialized.
// note: usually best to let the compiler calculate array size
// rather than hardcoding the size
int Array[] = {78, 90, 56, 99, 88, 68, 92};
// number of elements in array
int sizeofArray = sizeof(Array)/sizeof(int);
// call Function to calculate and return as double,
// the average of the array elements
double average = Function( Array, sizeofArray );
// This prints the average as a 'double'.
printf("The resulting average is %lf \n", average);
//system("pause"); // not portable, suggest:
int ch;
while( (ch = getchar()) != EOF && '\n' != ch );
getchar();
//return 0; // <-- in modern C, if main to return 0 then this line not needed
} // end function: main
double Function(int *pArray, int numInts )
{
int sum = 0;
double average;
for(int i=0; i<numInts; i++)
{
sum += pArray[i];
}
// cast one of the values as a double so an integer divide is NOT performed
average = (double)sum / numInts;
return average;
} // end function: Function

Related

Totally unexpected output when trying to compute the average using arrays

I am trying to compute the average after reading in the data from a text file of int type.The program compiles fine. clang -std=gnu11 -Weverything -g3 -pedantic -g3 -O3 -lm average_weight_of_elephant_seals.c -o average_weight_of_elephant_seals
Suppose I want to compute the average weight of 2000 seals,the expected output is 6838.848152 but I get 1710.566467.I have no idea how to make sense of GDB yet.
Could someone please point out where have I have gone wrong?
/* The following program demonstrates the usage of fscan to read in a set of integer data into a file and then computes the sum followed by the average.
* The computation shall be encapsulated in a function and then be called in the main routine
*/
#include <stdio.h>
#define MAXSIZE 5000 /* Macro definition to pre-define the size of the array */
double average_weight(int count, int weights_array[]);
int main(void)
{
int number_of_seals;
int weights_array[MAXSIZE];
printf("Enter the number of seals: \n");
scanf("%i", &number_of_seals);
printf("Their average weight is %lf\n", average_weight(number_of_seals, &weights_array[number_of_seals]));
return 0;
}
double average_weight(int count, int weights_array[])
{
/* Variable declaration and initialization
* Note the use of the FILE data type */
int weight;
int sum = 0;
FILE *elephant_seal_data = fopen("elephant_seal_data.txt", "r");
if (elephant_seal_data == NULL)
{
return -1;
}
/* FEOF function to determine if EOF has been reached or not */
while (!feof(elephant_seal_data))
{
fscanf(elephant_seal_data, "%i", &weight);
weights_array[count++] = weight;
sum += weight;
count++;
}
double average_weight = (double)sum / (double)count;
fclose(elephant_seal_data);
return average_weight;
}
printf("Their average weight is %lf\n", average_weight(number_of_seals, &weights_array[number_of_seals]));
The code passes a pointer to a position into the array for no apparent reason, and does not check if number_of_seals * 2 is less than MAXSIZE so may overflow the array. But the array isn't needed for this calculation anyway.
weights_array[count++] = weight;
sum += weight;
count++;
The code is writing to the array not reading it. The array is not needed for this calculation.
The code increments count twice, so the average will be out by a factor of two, and alternate locations in the array will have undefined values in them.
There are 2 stupid mistakes in your code, a nastier one, and a risk.
First the stupid ones:
You pass count to the function and increment that value twice per each value in the file. If the initialy given value was correct, you end with a count 3 times too big. You should not pass count to the function but compute it there.
You use a wrong syntax to pass an array: you are expected to pass a pointer to its first element.
Now the nasty one: while Why is “while ( !feof (file) )” always wrong? is indeed a FAQ, is is still a common thing in beginners code...
feof only returns true after a read operation returned an error. Let us examine what happens for the last value. It is read and correctly processed once. feof still returns false (no error so far) so your code re-enters the loop. scanf reaches the end of file and returns 0 (what your code ignores) but does not change the values => the last value will be processed twice. Never ever use while (!feof(...
And finally the risk.
You are summing value into an integer. Even if the average will easily fit there, if you had larger value and a very high number of them, you could get an integer overflow. The recommended way it to sum into a larger type (double?) and if possible use a guess to limit the cumulative error: average(qty-guess) + guess is indeed average(quantity), but the computed sum can be much lower, limiting the cumulative error when using floating point values or preventing overflow when using integer ones. From the number of seals and the expected average there should be no problem here so a guess is useless, but remember that for a different use case...
Last but not least, main is expected to be declared as int main() if you do not care for additional parameters but never int main(void)
Code could become:
/* The following program demonstrates the usage of fscan to read in a set of integer data into a file and then computes the sum followed by the average.
* The computation shall be encapsulated in a function and then be called in the main routine
*/
#include <stdio.h>
#define MAXSIZE 5000 /* Macro definition to pre-define the size of the array */
double average_weight(int* count, int weights_array[]);
int main()
{
int number_of_seals;
int weights_array[MAXSIZE];
double weight = average_weight(&number_of_seals, weights_array);
printf("Their number is %d and their average weight is %lf\n", number_of_seals, weight);
return 0;
}
double average_weight(int* count, int weights_array[])
{
/* Variable declaration and initialization
* Note the use of the FILE data type */
int weight;
int sum = 0;
FILE* elephant_seal_data = fopen("elephant_seal_data.txt", "r");
if (elephant_seal_data == NULL)
{
return -1;
}
*count = 0;
/* FEOF function to determine if EOF has been reached or not */
for(int i=0; i<MAXSIZE; i++) // never process more than the array size
{
if (1 != fscanf(elephant_seal_data, "%i", &weight)) {
break; // immediately stop at end of file
}
weights_array[(* count)++] = weight;
sum += weight;
}
double average_weight = (double)sum / (double)*count;
fclose(elephant_seal_data);
return average_weight;
}
I have kept your general program structure unchanged, but IMHO, you are expected to first read the data into an array, and then pass that populated array along with its count to an average function. Just split your current function into 2 steps.
You have sent the number of counts to use in the array which is great, since the function does not know the length of the weights_array. But you are not using it properly.
I'd suggest you to:
Use count to limit the number of loops based on how many data you want.
Do not change/reassign the value of count. Since this number is crucial to calculate the average. Create some other variable to do the task.
So here is how I slightly modified your code to bring those changes. I assumed the format of elephant_seal_data.txt as space separated integer values.
#include <stdio.h>
#define MAXSIZE 5000 /* Macro definition to pre-define the size of the array */
double average_weight(int count, int weights_array[]);
int main(void)
{
int number_of_seals;
int weights_array[MAXSIZE];
printf("Enter the number of seals: \n");
scanf("%i", &number_of_seals);
printf("Their average weight is %lf\n", average_weight(number_of_seals, &weights_array[number_of_seals]));
return 0;
}
double average_weight(int count, int weights_array[])
{
/* Variable declaration and initialization
* Note the use of the FILE data type */
int weight;
int sum = 0;
int i = 0;
FILE *elephant_seal_data = fopen("elephant_seal_data.txt", "r");
if (elephant_seal_data == NULL)
{
return -1;
}
/* FEOF function to determine if EOF has been reached or not */
while (i<count)
{
fscanf(elephant_seal_data, "%d", &weight);
weights_array[i++] = weight;
if (feof(elephant_seal_data)) break;
sum += weight;
}
double average_weight = (double)sum / (double)count;
fclose(elephant_seal_data);
return average_weight;
}
Edit:
I have used the elephant_seals_data.txt to simulate these in Google Colab for you. Try running the first cell there.
Google Colab Link

printf() with a function call arg sometimes incorrect

The C code at bottom usually operates as expected, using gcc on Ubuntu 20.04, but about 15% of the time I get a huge result for highest temp:
Normal:
Highest temp: 15.30
15% of the time:
Highest temp: 970363834813736688025683948382903403895871057............00
If I pull the the function out of the printf() call, things behave as expected 100% of the time:
double max = maxTemp(temperatures,7);
printf("Highest temp: %.2lf\n", max);
I'm assuming the error case is a huge number because there's a double with garbage data somewhere.
Any idea what's going on?
Thank you for your time.
#include <stdio.h>
double maxTemp(double *temps, int numOfTemps);
int main(void) {
double temperatures[7] = {6.9, 12.3, 9.0, 15.3, 9.8, 1.8, 0.3};
printf("Highest temp: %.2lf\n", maxTemp(temperatures, maxTemp(temperatures,7)));
return 0;
}
double maxTemp(double *temps, int numOfTemps) {
double max = temps[0];
for (int i = 0; i < numOfTemps; i++) {
if (max < temps[i]) {
max = temps[i];
}
}
return max;
}
This is your problem:
maxTemp(temperatures, maxTemp(temperatures,7)))
maxTemp expects its second argument to have type int and to be the number of elements in the temperatures array. In the outer call, you're passing the result of maxTemp, which is a double, and is a temperature, not a count of array elements.
The compiler should be yelling at you right there - if not, turn on all warnings and treat all warnings as errors (-Wall -Werror if you're using gcc).
Secondly, the max temperature in your array is 15.3 - assuming that gets converted to an int value of 15, you're iterating past the end of your array into garbage.
Are you sure you don't mean to call that as
maxTemp( temperatures, 7 );
?
as one comment pointed out, you're calling maxTemp(…) twice in main.
If you remove the "outer call" you'll be fine, i.e. changing main to:
int main(void) {
double temperatures[7] = {6.9, 12.3, 9.0, 15.3, 9.8, 1.8, 0.3};
printf("Highest temp: %.2lf\n", maxTemp(temperatures, 7));
return 0;
}
Reason being that maxTemp(temps, n) calculates the maximum of n temperatures. So it will only work properly (defined behavior) if n is the actual number of values. This does usually not apply to the max temp.
This means you were taking values into consideration that are outside of the temperatures-array.
why it worked sometimes (by accident)
Those values outside your array are undefined. Values outside of allocated space are often 0, but not by definition. This is why it worked most of the time.

Inputing a value and instead of keeping that information in a array, it changes another var

I made a program and then it didn't worked. As in the other post someone advised me to trying to debug my programs, I learned it and debugged this one. Probably it has some basic errors of writting but that's because I've changed a lot of thing recently to understand what's happening. In third time when I input a value on screen on that loop, it changes my var "i" to that value instead of keeping that number in my array "grade".
First I tried to make it all in one loop, the first one, but as always it didn't help much, and then i wrote the code by this manner as you'll see
#include <stdio.h>
#include <stdlib.h>
int main()
{
int j=0,sum=0,i=0;
int grade[]={0};
for(;j<100;j++){
printf("Type a grade:\t");
scanf("%d",&grade[j]);
if(grade[j]<10||grade[j]>20){
break;
}
}
for(;i<j;i++){
sum=sum+grade[i];
}
float average=sum/j;
printf("The average is: %.2f\n",average);
system("pause");
return 0;
}
The exercicise says that you need to read "x" grades from a student and it needs to be between 10 and 20, if the number is out of this range it stops the loop.After I just need to calculate the average os these grades.I don't really know if my var average is being calculated correctly, cause I didn't could reach over there because of my problem. If you input 11, 12 and 13 it should give to a sum of 36, but gaves me 26, i don't know how.
Erik, you should define your array in a coherent way. To allow the necessary number of elements, try defining a numeric constant. You could use it for both define the number of iterations of your cycle and the size of your grade array. You can also avoid a new cycle to calculate the sum of the array, you can do this operation while reading the grades, using only one for loop. Try this way:
#include <stdio.h>
#include <stdlib.h>
#define MAX_GRADES 100
int main()
{
int j,sum=0,i;
float average;
int grade[MAX_GRADES];
for(j = 0 ; j < MAX_GRADES; j++)
{
printf("Type a grade:\t");
scanf("%d",&i);
if ( (i<10) || (i>20) )
break;
grade[j] = i;
sum += i;
}
if (j > 0)
average = (float)sum/j;
else
average = 0;
printf("The average is: %d, %d, %.2f\n",sum, j, average);
system("pause");
return 0;
}

Need help solving a problem with an array

Task: Calculate the 25 values of the function y = ax'2 + bx + c on the interval [e, f], save them in the array Y and find the minimum and maximum values in this array.
#include <stdio.h>
#include <math.h>
int main()
{
float Y[25];
int i;
int x=3,a,b,c;
double y = a*pow(x,2)+b*x+c;
printf("a = ", b);
scanf("%d", &a);
printf("b = ", a);
scanf("%d", &b);
printf("c = ", c);
scanf("%d", &c);
for(i=0;i<25;i++)
{
printf("%f",y); //output results, not needed
x++;
}
system("pause");
}
Problems:
Cant understand how can I use "interval [e,f]" here
Cant understand how to save values to array using C libraries
Cant understand how to write/make a cycle, which will find the
minimum and maximum values
Finally, dont know what exactly i need to do to solve task
You must first ask the user for the values of a, b, c or initialize those variables, and ask for the interval values of e, f, or initialize those variables.
Now you must calculate double interval= (f - e)/25.0 so you have the interval.
Then you must have a loop for (int i=0, double x=e; i<25; i++, x += interval) and calculate each value of the function. You can choose to store the result in an array (declare one at the top) or print them directly.
Problems:
Cant understand how can I use "interval [e,f]" here
(f-e) / 25(interval steps)
Cant understand how to save values to array using C libraries
You need to use some form of loop to traverse the array and save the result of your calculation at every interval step. Something like this:
for(int i = 0; i < SIZE; i++)
// SIZE in this case 25, so you traverse from 0-24 since arrays start 0
Cant understand how to write/make a cycle, which will find the minimum and maximum values
For both cases:
traverse the array with some form of loop and check every item e.g. (again) something like this: for(int i = 0; i < SIZE; i++)
For min:
Initialize a double value(key) with the first element of your array
Loop through your array searching for elements smaller than your initial key value.
if your array at position i is smaller than key, save key = array[i];
For max:
Initialize a double value(key) with 0;
Loop through your array searching for elements bigger than your initial key value.
if your array at position i is bigger than key, save key = array[i];
Finally, dont know what exactly i need to do to solve task
Initialize your variables(yourself or through user input)
Create a function that calculates a*x^2 + b*x + c n times for every step of your interval.
Create a function for min & max that loops through your array and returns the smallest/biggest value.
Thats pretty much it. I will refrain from posting code(for now), since this looks like an assignment to me and I am confident that you can write the code with the information #Paul Ogilvie & I have provided yourself. Good Luck
#include<stdio.h>
#include<math.h>
int main()
{
double y[25];
double x,a,b,c,e,f;
int i,j=0;
printf("Enter a:",&a);
scanf("%lf",&a);
printf("Enter b:",&b);
scanf("%lf",&b);
printf("Enter c:",&c);
scanf("%lf",&c);
printf("Starting Range:",&e);
scanf("%lf",&e);
printf("Ending Range:",&f);
scanf("%lf",&f);
for(i=e;i<=f;i++)
{
y[j++]=(a*pow(i,2))+(b*i)+c;
}
printf("\nThe Maximum element in the given interval is %lf",y[j-1]);
printf("\nThe Minimum element in the given interval is %lf",y[0]);
}
Good LUCK!

function declaration and call and definition in c

Why is this code not running after printing of array if I take value of n>=9?
#include <stdio.h>
#include <math.h>
float mean_function(float array[],int n);
int main() {
int i,n;
float array[n],mean,sum=0,s2,summation,deno,C[i],elements;
printf("Enter No of Elements\n");
scanf("%d",&n);
printf("Enter Elements\n");
for(i=0;i<n;i++){
scanf("%f",&array[i]);
printf("%f",array[i]);
}
printf("sample variance(s2) : (sum((x-mean)*(x-mean)))/(n-1) /n");
printf("population variance(sigma2) : (sum((x-u)*(x-u))/n");
mean_function(array,n);
for(i=0;i<n;i++) {
deno=((array[i]-mean)*(array[i]-mean));
C[i]=deno;
summation=summation+C[i];
}
s2=((summation)/(n-1));
printf("s2=%f \n",s2);
}
float mean_function(float array[],int n) {
int i;
float sum=0,mean;
for(i=0;i<n;i++){ sum=sum+array[i]; }
mean=(sum/n);
return mean;
}
Why is this code not running after printing of array if I take value
of n>=9?
Some thoughts about your code (and about building programs in steps):
Arrays in C don't change in size once defined. VLAs are out for a variety of reasons. malloc() is in.
Use double, unless there is a specific reason to use floats.
Define and initialize one variable per line. Uninit vars can only result in an error as mentioned by #Jens.
Function declarations at the top (which you have done)
During development, there is no need to complicate things with a scanf (at least initially). It only adds an unwarranted layer of complexity. If you are testing statistical functions (mean, variance), put numbers in a pre-defined static array and verify functionality first.
C[i] as been declared with uninitialized i.
For this initial phase of building this program, I include a basic program.
I am not a fan of zero space between tokens (but ignore that)
Consider calling your array something other than 'array'.
Calculating the size of the samples array allows you to change the number of elements without changing anything else in code; which adds another layer of complexity to an already difficult phase.
#include <stdio.h>
#include <math.h>
double sample_mean(double* p, int n);
int main()
{
double samples[] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 16.5, 2.3};
double mean = 0.0;
int size_samples = sizeof samples/sizeof(double);
printf("size_samples = %d\n", size_samples);
mean = sample_mean(samples, size_samples);
printf("Mean = %.2lf", mean);
}
// -------------------------------
double sample_mean(double* p, int n)
{
double mean = 0.0;
double total = 0.0;
for(int i = 0; i < n; i++)
total += *p++;
mean = total/n;
return mean;
}
Once this functionality is present (saved), you can start working on other stat functions. This way you can work step by step to get closer to the desired outcome.
Next up you can define sample_variance(double* p, int n) and work on that knowing that additional(new errors) are not coming from your code written so far.
Output:
size_samples = 8
Mean = 5.24
I hope it helps.
The code is likely not running because array[n] is declared with an uninitialized n. At the time you read n with scanf(), the array does not automatically "grow into the right size". You should either declare array big enough, or if you really want it to be user-defined, use malloc to allocate it (read the comp.lang.c FAQ) and all Stackoverflow questions tagged array...)
In addition, the scanf at some point fails. Note that when you enter numbers, you also have the "Enter" as a newline ('\n') in the input stream. You never read the newline so the next scanf fails.
This becomes obvious when you actually check the return value from scanf with code like this:
if (scanf("%f", &array[i]) == 1) {
/* successfully converted 1 item */
}
else {
/* scanf failed */
}
Usually what you want is to skip whitespace in the input. You do this by placing a space in the scanf format. Note that a single space tells scanf to skip any amount of white-space.
if (scanf(" %f", &array[i]) == 1) {

Resources