I added a few printf stantments to see if the information is being computer and passed correctly, and while is is being computed correctly in the calcMean function, I keep getting zeros in the main function. I am not sure where my mistake is.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void calcMean(int [], int, float);
void calcVariance(int [], int, float);
int main(void)
{
/*create array and initialize it with values*/
int mainArr [ ] = {71,1899,272,1694,1697,296,722,12,2726,1899,
.......
1652,488,1123,17,290,1324,2495,1221,2361,1244,
813,2716,1808,2328,2840,1059,2382,2391,2453,1672,
1469,778,2639,357,2691,1113,2131,23,2535,1514,
2317,45,1465,1799,2642,557,1846,1824,1144,1468,-1};
/*create initilized values for variables*/
float mean = 0.0;
int counter = 0;
calcMean(mainArr, counter, mean);
calcVariance(mainArr, counter, mean);
printf ("Mean: %10.2f\n", mean); /*gives the average number to one decimal place*/
printf ("counter: %10.0d\n", counter);
getchar();
}/*End of the program*/
void calcMean(int mainArr[], int counter, float mean)/*This function finds the Mean(average) of the function, and the size of the array*/
{
int sentinel = -1;
float sum = 0.0;
int index = 0;
for (index; mainArr[index] != sentinel; index++) /*gets the total numbers in the function and the sum*/
{
counter++;
sum = sum + mainArr[index];
} /*end of the sumation and counting of integers*/
printf ("%0.0d\n", counter);
mean = ((float) sum / counter); /*Divides the sum by the total number of numbers to find the mean*/
printf ("mean: %10.2f\n", mean);
}
void calcVariance(int mainArr[], int counter, float mean)
{
int varindex = 0;
int numerator =0;
int square = 0;
int variance = 0;
int sumation = 0;
for(varindex; varindex<counter; varindex++)
{
numerator = (mainArr[varindex] - mean);
square = (numerator * numerator);
sumation = sumation + square;
variance = sumation / (counter-1);
}
printf ("variance %10.2f\n", variance);
}
You're assuming your function changes the value of outer variables. It won't.
calcMean(mainArr, counter, mean);
^ ^ pass by value
void calcMean(int mainArr[], int counter, float mean)
^ ^ receive by value
Modifying counter inside the function changes only the local variable.
Function parameters are copied into functions. So the variables inside a function will not change the parameters in the outer function.
You will need to do something like the following to any function which you wish to pass back more than one value from a function. (If you only need to pass back one value that can be returned with the function return statement).
// declare the parameters you wish to pass back to calling function as pointers
void calcMean(int [], *int, *float);
// pass the address of the variables:
calcMean(mainArr, &counter, &mean);
// obtain the values of the pointers in your calcMean using derefence operator *
printf ("%0.0d\n", *counter);
*mean = ((float) sum / *counter);
OP later requested an answer with little use of pointers.
As others (#suspectus, #Karoly Horvath, #Carl Norum) correctly pointed out the problem that passing into a function mean does not change it.
main() has an object named mean. That object's value was used to initialize the object called mean in the argument list of calcMean(). calcMean() proceeded to set its mean to some value. At the end of the function, the original mean in main() is not affected.
Instead, use the return value of function calcMean() to set mean in main().
// void calcMean(int mainArr[], int counter, float mean)
float calcMean(int mainArr[], int counter) {
float mean;
...
mean = ((float) sum / counter);
return mean;
}
int main(void) {
...
float mean = 0.0;
...
// calcMean(mainArr, counter, mean);
mean = calcMean(mainArr, counter);
...
}
Do the same for calcVariance
C is a pass-by-value language. Modifying mean and counter in the other functions doesn't affect their values in main().
Related
I am new to the C language (I started to learn it a week ago). the program was having some random output so i wanted to see what was it storing in the variable. then the printf fixed it somehow.
#include <stdio.h>
int laske(float lista[]);
const int MAX = 3;
int main()
{
float lista[5], yhteispisteet;
int counter = 0;
do
{
printf("Anna %d. pisteet: \n", counter +1);
scanf("%f", &lista[counter++] );
printf("%d",lista[counter]); <-- if you remove this line it dosent work
}
while (counter < MAX);
yhteispisteet = laske(lista);
printf("\nYhteispisteet ovat: %.2f\n", yhteispisteet);
getchar();
return 0;
}
int laske(float lista[])
{
int rivi, tulos;
for (rivi=0; rivi< MAX; rivi++)
tulos = tulos + lista[rivi];
return tulos;
}
Three things to note from your code:
You are adding a float and an int when you do: tulos = tulos + lista[rivi];, without casting the input float to int like this: tulos = tulos + (int)lista[rivi]; Or better yet, just declare tulos as float, and return a float from your laske function, because the return value is again being assigned to a float yhteispisteet
You assign to lista[counter++] with the scanf, and then increment the counter (post-increment) and print the lista[counter](which is printing the incremented indexed value that did not take any assignments yet). It is better to increment counter++ after the printf function.
You did not initialize your variable tulos, and this gives you undefined behavior when your code is running, which is probably what you are seeing when you add and then remove the printf and then rerun
I am currently trying to take a sum from two different subroutine and pass it back to the main function, but every time I do this, it just comes up with a zero value and I am unsure why. I have tried putting my print statements in the main function and just doing calculations in the subroutines and that still didn't work, so I know that my variables aren't returning right and my sum is an actual number. How do I pass my variable sum back to my main function correctly?
Here is my code:
#include<stdio.h>
int X[2000];
int Y[2000];
int main()
{
FILE*fpdata1= NULL;
FILE*fpdata2 = NULL;
fpdata1=fopen("DataSet1.txt","r");
fpdata2=fopen("DataSet2.txt","r");
if(fpdata1==NULL || fpdata2 == NULL)
{
printf("file couldn't be found");
}
int i=0;
while(i<2000)
{
fscanf(fpdata1,"%d!",&X[i]);
fscanf(fpdata2,"%d!",&Y[i]);
// printf("This is X: %d\n",X[i]);
// printf("This is Y: %d\n",Y[i]);
i++;
}
fclose(fpdata1);
fclose(fpdata2);
avgX(X);
avgY(Y);
float sum;
float sumY;
float totalsum;
float totalavg;
totalsum= sum + sumY;
totalavg= totalsum/4000;
printf("Sum X: %f\n\n",sum);
printf("Total sum: %f\n\n",totalsum);
printf("The total average is: %0.3f\n\n",totalavg);
return 0;
}
int avgX(int X[])
{
int i=0;
float averageX;
float sum;
sum = 0;
while (i<2000)
{
sum += X[i];
i++;
}
averageX = sum/2000;
printf("Sum of X: %f\n\n",sum);
printf("The sum of Data Set 1 is: %0.3f\n\n",averageX);
return(sum);
}
int avgY(int Y[])
{
int i=0;
float averageY;
float sumY;
sumY = 0;
while (i<2000)
{
sumY += Y[i];
i++;
}
averageY = sumY/2000;
printf("Sum of Y: %f\n\n",sumY);
printf("The sum of Data Set 2 is: %0.3f\n\n",averageY);
return (sumY);
}
Firstly, it would appear you are expecting the lines
avgX(X);
avgY(Y);
to somehow update the sum and sumY variables in the main function. This is a fundamental misunderstanding of how memory is accessed.
Local variable declarations with the same identifier are not shared between functions. They can be accessed only from within the function in which they are declared (and only for the duration of the function call).
In this example, the apples variables in each of the functions have absolutely no correlation to one another. Expecting this program to print 15 is wrong. This program has undefined behavior because foo and bar read values from uninitialized variables.
void foo(void) {
int apples;
/* This is undefined behaviour,
* as apples was never initialized. Do not do this. */
apples += 5;
}
void bar(void) {
int apples;
/* This is undefined behaviour,
* as apples was never initialized. Do not do this. */
printf("%d\n", apples);
}
int main(void) {
int apples = 10;
foo();
bar();
return 0;
}
Instead of this, you'll want to utilize the arguments and return values of your functions. In this example, in main we pass the value of apples as an argument to foo, which adds 5 to this value and returns the result. We assign this return value, overwriting our previous value.
int foo(int val) {
return value + 5;
}
void bar(int val) {
printf("%d\n", val);
}
int main(void) {
int apples = 10;
apples = foo(apples);
bar(apples);
return 0;
}
Again note that the val parameters do not refer some "shared variable", they are local to both foo and bar individually.
As for the specifics of your program:
The functions avgX and avgY do the exact same thing, just with different identifiers.
It would be better to write a more generic summation function with an additional length parameter so that you are not hard-coding data sizes everywhere.
int sum_ints(int *values, size_t length) {
int result = 0;
for (size_t i = 0; i < length; i++)
result += values[i];
return result;
}
You can then easily write averaging logic utilizing this function.
You do check that your file pointers are not invalid, which is good, but you don't halt the program or otherwise remedy the issue.
It is potentially naive to assume a file will always contain exactly 2000 entries. You can use the return value of fscanf, which is the number of conversions that took place, to test if you've failed to read data. Its also used to signify errors.
Though the fact that global variables are zeroed-out saves you from potentially operating on unpopulated data (in the event the files contain less than 2000 entries), it would be best to avoid global variables when there is an alternative option.
It might be better to separate the reading of files to its own function, so that failures can be handled per-file, and reading limits can be untethered.
int main(void) or int main(int argc, char **argv) are the correct, valid signatures for main.
With all that said, here is a substantially refactored version of your code. Note that an implicit conversion takes place when we assign the integer return value of sum_ints to our floating point variables.
#include <stdio.h>
#include <stdlib.h>
#define DATA_SIZE 2000
int sum_ints(int *values, size_t length) {
int result = 0;
for (size_t i = 0; i < length; i++)
result += values[i];
return result;
}
size_t read_int_file(int *dest, size_t sz, const char *fname) {
FILE *file;
size_t i;
if ((file = fopen(fname, "r")) == NULL) {
fprintf(stderr, "Critical: Failed to open file: %s\n", fname);
exit(EXIT_FAILURE);
}
for (i = 0; i < sz; i++)
if (fscanf(file, "%d!", dest + i) != 1)
break;
fclose(file);
return i;
}
int main(void) {
int data_x[DATA_SIZE] = { 0 },
data_y[DATA_SIZE] = { 0 };
size_t data_x_len = read_int_file(data_x, DATA_SIZE, "DataSet1.txt");
size_t data_y_len = read_int_file(data_y, DATA_SIZE, "DataSet2.txt");
float sum_x = sum_ints(data_x, data_x_len),
sum_y = sum_ints(data_y, data_y_len);
float total_sum = sum_x + sum_y;
float total_average = total_sum / (data_x_len + data_y_len);
printf("Sums: [X = %.2f] [Y = %.2f] [Total = %.2f]\n"
"The total average is: %0.3f\n",
sum_x, sum_y, total_sum,
total_average);
}
So I'm rather stumped on why my code isn't working. I have 2 functions, one that adds numbers and the other gets the average. Thinking that I might as well as call the add function within the average function to save a few more lines of code, I tried it out.
Also, they both have an array as their parameter. The array has a size of 5 and is set to float.
float addOp(float num[])
{
int i;
float ans;
for(i=0;i<5;i++)
{
ans += num[i];
}
return ans;
}
float aveOp(float num[])
{
float average;
average = addOp(num) / 5;
return average;
}
The add function works perfectly but when I try to use the average function, the code runs but the answer it gives out is way off. I'm thinking that C doesn't allow passing arrays in succeeding functions but I'm not very sure. Any thoughts on what am I doing wrong?
The problem is addOp()
float addOp(float num[])
{
int i;
float ans; /* This is uninitialized */
for(i=0;i<5;i++)
{
ans += num[i]; /* This adds an undefined start point to the 5 numbers*/
}
return ans;
}
The fix is to change to
float ans = 0;
I have the following code in C :
#include <stdio.h>
// Global variables :
int i;
int x[10];
int Nmax;
int sum;
// Functions used :
void Summation();
int Average(float avg); // This function will return avg
int main()
{
float avg;
printf("Mention how many numbers to be added\n");
scanf("%d",&Nmax);
printf("Enter %d numbers\n",Nmax);
for (i=0; i<Nmax; i++){
scanf("%d",&x[i]);
}
Summation();
Average(avg);
printf("%d %d %f\n",Nmax,sum,avg);
printf("Average = %.2f\n",avg);
return 0;
}
// Summation :
void Summation()
{
sum=0;
for (i=0; i<Nmax; i++) {
sum=sum+x[i];
}
printf("Sum of them = %d\n",sum);
}
// Average
int Average(float avg)
{
avg=(float)sum/(float)Nmax;
return avg;
}
Somehow the function Average is not returning the expected average value.
Instead it's showing a garbage value.
A typical input/output :
Mention how many numbers to be added
4
Enter 4 numbers
1 2 3 4
Sum of them = 10
4 10 1637156136366093893632.000000
Average = 1637156136366093893632.00
What's going wrong here? Hope I don't require a pointer here or do I?
For the average function you are passing the argument as pass by value. Once you call the function your are not assigning the return value back to the avg variable inside the main function. So what you are printing is the garbage value inside the avg variable declared in main function. Change your code to
avg = Average(avg);
Also this is a very bad way of writing c programs. Please dont you use global variables if you dont need them.
You are mixing int and float and that can cause problems.
You are never initializing avg in main(), use parameters instead of global variables to avoid the confusion. You pass avg's value to Average() it has absolutely no use in this case.
In c parameters to functions are always passed by value so the value of avg is not being modified in Average(), you may think it is because you seem confused about how you can modify global variables everywhere. The truth is global variables are mean, of course they have their uses for example, a global state in a library could be stored in a global variable1 but generally they are not needed.
Try like this
#include <stdio.h>
// Functions used :
float Summation(float *data, int size);
float Average(float *data, int size); // This function will return avg
int
main(void)
{
int size;
printf("Mention how many numbers to be added\n");
if (scanf("%d", &size) == 1)
{
float data[size];
float sum;
float average;
int i;
printf("Enter %d numbers\n", size);
for (i = 0 ; ((i < size) && (scanf("%f", &data[i]) == 1)) ; i++)
;
size = i;
sum = Summation(data, size);
average = Average(data, size);
printf("%d %f %f\n", size, sum, average);
printf("Average = %.2f\n", average);
}
return 0;
}
// Summation :
float
Summation(float *data, int size)
{
float sum;
sum = 0;
for (int i = 0 ; i < size ; i++)
sum = sum + data[i];
return sum;
}
// Average
float
Average(float *data, int size)
{
return Summation(data, size) / (float) size;
}
Note that you "don't really need an Average() function.", although it could be useful to make the API clean.
1Although I don't like that either, it makes the library very limited in multithreaded environments. Still sometimes it makes senes, but you can always have a structure with all the needed data and pass it in every call to the library API. So global variables are very rarely good.
I am new to C and have a question about making a simple function in which I hand in a given array and also an integer that tells the number of numbers in that array. I wrote this code but I am unsure if it is correct. What I was trying to do was to make it so that I could find the product of all the numbers in the array.
#include <stdio.h>
#include <math.h>
double my_product (int n, double x[]);
int main (void)
{
my_product(n, x);
return 0;
}
double my_product (int n, double x[])
{
int i;
product=0;
for(i=0; i<n; i++)
{
product=x[i]*x[i+1]
}
return product;
}
I will comment your code, pointing out your mistakes:
double my_product (int n, double x[])
{
int i;
product=0;
/* The variable "product" needs to have a type.
In your case, since your values have type "double",
and a "double" return is expected,
of course you need to declare:
double product;
On the other hand,
it has not sense to initialize a product to 0,
since multiplication by 0 "kills" every value,
giving you a value 0, not matter what you do.
So, initialize in this way:
double product = 1.0;
*/
for(i=0; i<n; i++)
{
/* A semicolon is missing in the next line: */
product=x[i]*x[i+1]
/* In every step of the loop,
the variable "product" will hold the value
given by the multiplication of two consecutive values
in the array.
Thus, you lose every previous factor.
Also, when i == n you are in trouble,
because x[i] == x[n] is beyond the limits of the array,
which may cause access violation to memory.
You need a cumulative product.
Starting by the initialized value 1.0,
you have to multiply the previous value of "product"
with the present value of the array: x[i]
product = product * x[i];
Thus, in the step i, it can be proved that
the variable "product" contains the cumulative product
of the factors x[0], x[1], ... up to x[i].
A more compact notation in C can be provided by the *= operator:
product *= x[i];
*/
}
return product;
}
In the function main():
int main (void) {
my_product(n, x);
/* The function "my_product()" has been called with
undeclared parameters "n" and "x".
First, you have to declare and define the value of "n",
as much as the array "x", having type double:
double x[] = {3.0, 1.41, -2.3, 9.4, };
int n = sizeof(x)/sizeof(double);
The first line would declare an array "x" having type "double",
and initialized to hold 4 values, as it's seen there.
The second line would declare an "int" variable "n"
holding the number of elements in the array,
which can be computed as the size of x (measured in bytes)
divided by the size of the type "double"
(of course, in this example we have n == 4).
Finally, you need to do something with the result returned by
the function "my_product()".
If not, the returned value will be completely lost.
For example, to hold it in a variable, or to show it on screen.
double ans;
ans = my_product(n, x);
*/
return 0;
}
The code will look like this:
#include <stdio.h>
#include <math.h>
double my_product (int n, double x[]);
int main (void)
{
double x[] = {3.0, 1.41, -2.3, 9.4, };
int n = sizeof(x)/sizeof(double);
double ans;
ans = my_product(n, x);
printf("Product is: %f\n", ans);
return 0;
}
double my_product (int n, double x[])
{
product=1.0;
int i;
for(int i=0; i<n; i++)
{
product *= x[i];
}
return product;
}
In your function my_product you overwrite the value of product in the loop
for(i=0; i<n; i++)
{
product=x[i]*x[i+1]
}
So suppose your array x = {2, 3, 4}, then first product gets the value of 2*3, but then you overwrite it with the value of 3*4. What you probably want is to use a variable in which you accumulate the results of the multiplications (e.g. total = total * number).
Also, watch out with your indexing. In your current code i+1 can be larger than the number of elements in x, so you run out of the array.