What does this C code mean? Arrays and pointer variables - c

So I am instructed to write a function that uses the following prototype:
double stats(int *array, int size, double *std_dev);
The function should return the average value of the array. The argument std_dev is passed by reference so that the standard deviation of the data in the array can be returned. I assume this to mean that I need to calculate standard deviation as well.
I set about this in the following manner:
double stats(int *array, int size, double *std_dev){
int sum = 0; //declare int to hold sum
int i; //index used in for-loops
for (i = size; i>0; i--){ // for every element(i)
sum += array[i]; //add array element to
}
int mean = sum/size;
for (i = size; i>0; i--){ // for every element(i)
sum += array[i] -mean;
}
return 0;
}
The code compiles; but I'm not quite sure if these lines actually do what I think they do, and I don't have parameters to test with:
sum += array[i]; //add array element to
sum += array[i] -mean;
I know that "array" is a pointer variable, but I'm not exactly sure what it is my code is actually doing, can someone please tell me what these lines actually do? Thanks.
EDIT: I am aware that this code does not completely satisfy my objective, it is a WIP that compiles.
EDIT EDIT: That includes the logical correctness of my program.

when you do this
sum += array[i];
you are iterating through every element of the array - i.e., element at each index and storing the result in the variable sum.
a[i] is the ith element of the array a. It can be thought of as *(a+i).
Similarly in the second loop, you are adding up a[i] - sum to the variable sum. I think you are trying to compute the standard deviation in the second loop in which case you need to sum (a[i] - mean)^2 (i.e, square of difference from the mean) into the variable std_dev and then divide by size.

you have problems in your for:
you will never get to array[0] which is the first element in array
use for(i=0;i<size;i++)as for your question
sum +=array[i]; will put in variable sum the result of sum + array[i]
sum += array[i] -mean; will put in sumthe result of array - mean
BTW I have no idea what are you doing in second for loop (mathematically)
but if you don't want to use previous sum which contain the sum of all the array then you
should to set sum to 0 before you run the second for.
BTW, you returning 0
don't you want to return your average which is return mean; in your case ?
in function prototype it says function should return double
what you've done is int mean = sum/size; is an integer value that will cut the numbers after the "."
you probably want to use double mean = sum/size;
and then to return it as I have mentioned before.

Related

calculation of average number get way to high. I don't get why?

I am trying to get the average number of an array but the output is way to high for it to be correct. What am I doing wrong?
int count(int arr[]){
int sum;
//Average
for(int i=0;i<100; i++)
sum = sum + arr[i];
printf("Average:%f \n", sum/100);
}
int main()
{
int array[100]; //RANDOM NUMBERS 0-900
count(array);
return 0;
}
You need to initialize sum to zero before using it. C or C++ does not do this automatically for you in case of variables with automatic storage duration. It takes "time", and in C or C++ you don't pay for what you don't need. Otherwise you get a junk value (whatever its stored at that memory address, and technically it is undefined behaviour to use un-initialized variables except in assignments).
You also need to initialize the array, like
int arr[100]{}; // C++11 or later
or
int arr[100] = {0}; // C++98 or good old C
then fill it up with values. Do not consider the junk values as "random numbers", since again you are encountering undefined behaviour and the program is not altogether safe.
Undefined behaviour(UB):
sum = sum + arr[i];
You have used sum above and it was not initialized. It is UB to read values of uninitialized variables in C and C++.
Actually given your code it is even once again UB because neither array values arr[i] are initialized.
sum contains garbage value. Do initialize variable sumenter code here.
To verify you can print before updating sum.
Try the following:
int count(int arr[]){
int sum = 0; // <==================== initialize to zero
//Average
for(int i=0;i<100; i++)
sum = sum + arr[i];
printf("Average:%f \n", sum/100);
}
int main()
{
int array[100]; //RANDOM NUMBERS 0-900
count(array);
return 0;
}
Without this initialization, the local variable sum can have any arbitrary initial value. And you will end up with arbitrarily large sum. Which will throw off the average.
The reason for this is that local variables are NOT initialized to zero automatically (unlike global variables).

C programming help - adding values together/for loop

I'm trying to add values together that I get using a for loop but I'm stumped as to how to do it. This is the code I have so far:
float counter;
float harmonic;
float sum;
for (counter = 2; counter <= n; counter ++)
{
harmonic = 1/counter; // current value
sum = harmonic; // stores current value
}
return 0;
}
So basically for each value I get for the "harmonic" variable I need to add it to the next until the loop ends. Should I be looking at arrays? Thanks for any help.
Change your code to read
float sum = 0;
then inside the loop write
sum += harmonic;
You don’t need an array unless you want to remember all of the values you’ve summed.
Also, don’t use a float as your loop counter. You probably want an int instead.

Multiply each element of an array by a number in C

I'm trying to optimize some of my code in C, which is a lot bigger than the snippet below. Coming from Python, I wonder whether you can simply multiply an entire array by a number like I do below.
Evidently, it does not work the way I do it below. Is there any other way that achieves the same thing, or do I have to step through the entire array as in the for loop?
void main()
{
int i;
float data[] = {1.,2.,3.,4.,5.};
//this fails
data *= 5.0;
//this works
for(i = 0; i < 5; i++) data[i] *= 5.0;
}
There is no short-cut you have to step through each element of the array.
Note however that in your example, you may achieve a speedup by using int rather than float for both your data and multiplier.
If you want to, you can do what you want through BLAS, Basic Linear Algebra Subprograms, which is optimised. This is not in the C standard, it is a package which you have to install yourself.
Sample code to achieve what you want:
#include <stdio.h>
#include <stdlib.h>
#include <cblas.h>
int main () {
int limit =10;
float *a = calloc( limit, sizeof(float));
for ( int i = 0; i < limit ; i++){
a[i] = i;
}
cblas_sscal( limit , 0.5f, a, 1);
for ( int i = 0; i < limit ; i++){
printf("%3f, " , a[i]);
}
printf("\n");
}
The names of the functions is not obvious, but reading the guidelines you might start to guess what BLAS functions does. sscal() can be split into s for single precision and scal for scale, which means that this function works on floats. The same function for double precision is called dscal().
If you need to scale a vector with a constant and adding it to another, BLAS got a function for that too:
saxpy()
s a x p y
float a*x + y
y[i] += a*x
As you might guess there is a daxpy() too which works on doubles.
I'm afraid that, in C, you will have to use for(i = 0; i < 5; i++) data[i] *= 5.0;.
Python allows for so many more "shortcuts"; however, in C, you have to access each element and then manipulate those values.
Using the for-loop would be the shortest way to accomplish what you're trying to do to the array.
EDIT: If you have a large amount of data, there are more efficient (in terms of running time) ways to multiply 5 to each value. Check out loop tiling, for example.
data *= 5.0;
Here data is address of array which is constant.
if you want to multiply the first value in that array then use * operator as below.
*data *= 5.0;

Trying to find numbers repeated in two arrays

I am trying to find all of the numbers that are repeated across two arrays..
For example:
array1[2]: 1,2
array2[2]: 1,5
The number that repeats itself is 1 so we create a new array that will contain 1.
array3[2]: 1
My code is:
int func1(int *str, int *str2)
{
int i,j,temp,c[10];
for(i=0;i<*(str+i);i++){
for(j=0;j<*(str2+j);j++){
if(*(str+i) == *(str+j))
{
temp = *(str+i);
*(str+i) = temp;
temp = *(c+i);
return c[i];
}
}
}
return 0;
}
What is the problem?(logically)
Thanks.
There are multiple problems:
The conditions in the two for loops are odd and probably wrong. They are equivalent to:
for (i = 0; i < str1[i]; i++)
for (j = 0; j < str2[j]; j++)
You should probably specify the sizes of the input arrays in the function interface.
In C, you must make sure you always know the sizes of the arrays.
You should probably specify the output array in the function interface.
Since you will need to know how many values were found in common, you'll need to return that number from the function.
Your choice of the names str1 and str2 is unusual. Not technically wrong, but probably not a good idea. Such names should be reserved for character strings, not arrays of integers.
Your local array c is barely used, and is not used safely.
Your code returns when it finds the first pair of numbers that match, not all possible matches.
The first two lines of the body of the if statement elaborately copies the value in str[i] back to itself via temp.
The third line of the body of the if statement copies an uninitialized value from array c into the variable temp.
The last line of the body of the if then returns that uninitialized value.
This adds up to changes such as:
int func1(int *arr1, int num1, int *arr2, int num2, int *arr3)
{
int k = 0;
for (int i = 0; i < num1; i++)
{
for (int j = 0; j < num2; j++)
{
if (arr1[i] == arr2[j])
arr3[k++] = arr1[i];
}
}
return k;
}
Note that this code assumes that the size of arr3 (the array, not the pointer itself) is as big as the product of num1 and num2. If both arrays contain a list of the same value, then there will be one row in the output array, arr3, for each pair so it could use num1 * num2 rows. This points out that the code does not deal with suppressing duplicates; if you need that (you likely do), then the body of the if statement needs to search through the current values in arr3 to check that the new value is not present. It would be wise to add another parameter, int siz3, to indicate the size of the third array; if you run out of space for values, you could then return -1 as an error indication.
The coded algorithm is quadratic (or, more accurately, proportional to the product num1 * num2). If you know the arrays are sorted on entry, you can reduce it to a linear algorithm (proportional to num1 + num2). With duplicate elimination, it is a little more expensive - it isn't quite as simple as 'cubic'. If you know the input arrays contain unique values (no duplicates), then duplicate elimination is obviously not necessary.
for(i=0;i<*(str+i);i++){
for(j=0;j<*(str2+j);j++){
Are wrong. You are applying '<' condition on an integer to itself and hence loop condition breaks. So, the loop never runs.
And why are you using these redundant statements?
temp = *(str+i);
*(str+i) = temp;
Also, this is wrong
temp = *(c+i);
return c[i];
Try more to correct those statements.If you can't do again, I will provide you a solution

Trouble making a running total in C

I'm new at programming, new on this site too, so hello...
I'm attempting to obtain a running total for integers one thru 10, but I'm getting gibberish answers and I just can't understand why.
To attempt to find out what was going wrong, I added the
printf(" running total is %d\n", sum);
line to the while loop, but just got more of the same nonsense...
please see http://codepad.org/UxEw6pFU for the results....
I'm sure this has a blindingly obvious solution...I'm just too dumb to see it though!
anyone know what I'm doing wrong?
#include <stdio.h>
int main(void) {
int count,sum,square;
int upto=10;
count = 0;
square = 0;
while (++count < upto) {
square = count * count;
printf("square of %d is %d",count,square);
sum =square + sum;
printf(" running total is %d\n", sum);
}
printf("overall total of squares of integers 1 thru 10 is %d\n", sum);
return 0;
}
You need to initialize sum to 0.
EDIT As others have stated after the fact, the reason you're seeing garbage is because sum isn't initialized and contains whatever is in memory. It can be anything, and your use of it with sum = square + sum is going to add square to the uninitialized value.
You are never initializing the value of sum.
The first time your code runs
sum = square + sum;
The value of sum (on the right side) is an arbitrary number because it has not been initialized. Therefore, the resulting value of sum (on the left side) is that arbitrary number plus square.
Simply add a sum = 0 statement like you have for count and square already.
Right off the bat, you do not initialize 'sum' to anything.
edit: A cleaned up version, though depending on compiler, you might need to enforce C99 mode, otherwise older compilers might not support initial declarations in the for loop.
#include <stdio.h>
int main()
{
const int COUNT_MAX = 10;
int sum = 0;
for ( int i = 1; i <= COUNT_MAX; ++i )
{
sum += i*i;
}
printf("The sum of squares from 1 to 10 is: %d\n", sum);
return 0;
}
Initialize sum with 0, otherwise it contains arbitrary data:
sum = 0;
See: http://codepad.org/e8pziVHm
sum is not initialized
You should do :
sum=0;
and remove
square=0;

Resources