Why define directive is not working here? - c

This is the code I'm trying to run and this is just taking one input and giving me the standard deviation result. Also the 'SIZE' is highlighted as red in GNU nano. I wanna know why, so please help.
This is the code-
#include<stdio.h>
#include<math.h>
#define SIZE 5
float std_dev(float a[], int n);
float mean(float a[], int n);
int main(){
float value[SIZE];
int i;
printf("Enter float values\n",SIZE);
for(i=0; i<SIZE; i++){
scanf("%f",&value[i]);
printf("Std.deviation is %f\n", std_dev(value, SIZE));
}
}
float std_dev(float a[], int n){
int i;
float x, sum=0.0;
x=mean(a,n);
for(i=0; i<n; i++){
sum+=(x-a[i])*(x-a[i]);
return(sqrt(sum/(float)n));
}
}
float mean(float a[], int n){
int i;
float sum=0.0;
for(i=0; i<n; i++){
sum = sum + a[i];
return(sum/(float)n);
}
}
Commands I gave for the output are-
gcc StandardDeviation.c -o compilfile -lm
./compilfile
One more thing, I'm using Kali Linux.
I'm trying to get the result as the standard deviation after giving the five float values.

Edit: I did the basic mistake here that I was using return statement inside the loop. It should be something like this:
float std_dev(float a[], int n)
{
int i;
float x, sum = 0.0;
x = mean(a, n);
for(i = 0; i < n; i++) {
sum += (x - a[i]) * (x - a[i]);
}
return sqrt(sum / (float)n);
}
in every function I created here. Thank you for this solution #axiac.
Few more points:
I am using Visual Studio Code now.
I am learning how to format the code and ask question properly in this platform.
I implemented all the suggestions you guys gave me. Thank you!

Related

why am i getting segmentation fault when i run this code?

#include <stdio.h>
void avg_sum(double a[], int n, double *avg, double *sum)
{
int i;
sum = 0;
printf("%f", *sum);
for(i=0; i<n; i++)
*sum += a[i];
*avg = *sum/n;
}
int main()
{
double arr[2] = {0.0,1.0};
double *sum;
double *avg;
int n = 2;
avg_sum(arr, n, avg, sum);
printf("...Done...\n");
return 0;
}
Tried using both GCC(https://www.tutorialspoint.com/compile_c_online.php) and clang(from repl.it) online compilers
double *sum;
This creates a pointer to a double but it has an arbitrary value and therefore points at no dedicated memory.
In addition, in the called function, you set the sum pointer to zero (the null pointer) then try to use that pointer to dereference memory - that's a big non-no.
I'd also be wary of for(i=0; i<n-2; i++) for summing the values in the array. It's not going to include the final two which, since n is two, means it won't accumulate any of them.
The correct way to do this would be with:
void avg_sum(double a[], int n, double *avg, double *sum) {
int i;
*sum = 0; // set content, not pointer.
for(i=0; i<n; i++) // do all elements.
*sum += *(a+i);
*avg = *sum/n;
}
int main(void) {
double arr[2] = {0.0,1.0};
double sum; // ensure actual storage
double avg; // and here
int n = 2;
avg_sum(arr, n, &avg, &sum); // then pass pointers to actual storage
printf("Sum=%f, Avg=%f\n", sum, avg);
return 0;
}
This gives you, as expected:
Sum=1.000000, Avg=0.500000
Easy. In line 6 you assign 0 to sum but sum is not the actual sum but a pointer to it. When you try to print it you access invalid memory.
Edit:
BTW if you try compling with -fanalyzer you will get a warning and an explanation.
https://godbolt.org/z/W6ehh8

Error in C program in Dynamic memory allocation

I am using gcc compiler in ubuntu18.10 os. And I don't know why this program is giving Error and Can't even understand the error. The Program is as follows and I presented ERRORS also.
#include<stdio.h>
#include<stdlib.h>
float Average(int*, int);
int main()
{
int *arr;
int n;
scanf("%d",&n);
float sum;
arr = (int *)malloc(n * sizeof(int));
for(int i=0;i<n;i++)
scanf("%d",&arr[i]);
sum = Average(int *arr, int n);
printf("%f\n",sum);
return 0;
}
float Average(int *arr, int size)
{
int sum;
int n = size;
printf("arr: %p\n",&arr);
printf("size: %p\n",&size);
printf("sum: %p\n",&sum);
for(int i=0;i<n;i++)
{
sum += arr[i];
}
return (sum * 1.0f) / size;
}
Errors are:
Test.c: In function ‘main’:
Test.c:16:16: error: expected expression before ‘int’
sum = Average(int *arr, int n);
^~~
Test.c:16:8: error: too few arguments to function ‘Average’
sum = Average(int *arr, int n);
^~~~~~~
Test.c:4:7: note: declared here
float Average(int*, int);
^~~~~~~
Please Help me to find out why and any reference materials to understand the concept clearly.
Thank you
sum = Average(int *arr, int n);
Type specifiers are something you give in the declaration and definition of the function, not in calls to it. You want:
sum = Average(arr, n);
Some other things you may want to check.
First, the int sum; in Average() does not initialise the value to zero, it sets it to some arbitrary value. That's not going to end well when you just add the integers to it. It should instead be:
int sum = 0;
Second, unless you're using massive arrays of floating point numbers, it's almost always better to use double for its greater range and precision.
Taking those into account, I probably would have written the function:
double Average(int *arr, int size) {
double sum = 0;
for (int i = 0; i < size; ++i)
sum += arr[i];
return sum / size;
}
When you call a function you don't specify the types of the arguments. That's a syntax error. If you look at where you call printf, you'll see that you don't specify the parameter types there. The same goes for your own functions.
So change this:
sum = Average(int *arr, int n);
To this:
sum = Average(arr, n);

How to make openmp running correctly in subroutine (c language)

I am trying to compare the difference between openmp reduction sum and the normal serial summation of an array. But I only got garbage number from my subroutine "fast_sum", while the result in serial_sum is correct. I am not sure why... I can compile my code successfully using gcc-7 -fopenmp. Please help me and thank you in advance!
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <omp.h>
#include <sys/time.h>
#define NUM_THREADS 8
//////// serial /////////
double serial_sum(double *A, int N){
double sum=0.0;
int i;
for(i=1;i<=N;++i)
sum += A[i];
return(sum);
}
double fast_sum(double *A, int N){
double sum=0.0;
int i;
#pragma omp parallell for reduction(+:sum) num_threads(NUM_THREADS)
for (i =1; i<=N; ++i)
sum += A[i];
return(sum);
}
int main(void)
{
int N = 256;
double sum1, sum2, sum3;
double *A;
int i, h;
A = (double*)malloc(N * sizeof(double));
for( i = 1; i<=N;++i){
A[i] = i;
}
/* initialization A[N] */
sum1 = serial_sum(A,N);
printf("normal_sum is %f\n", sum1);
sum2 = fast_sum(A,N);
printf("fast_sum is %f\n", sum2);
free(A);
}
You have an indexing error here. C is 0-indexed You never initialize A[0], and you try to access A[N], even though the array is only allocated out to N-1. So who knows what values are in A[0] and A[N] - they are probably quite large, giving you the garbage value.

Finding minimal number in array

I would like to write a program which finds the minimal number of 5 inputted numbers. I'm stuck at the point when I want to use function getMinNum, but there is an error saying: expected expression before ']' token
I understand it has a connection with pointers, however I would like to do it without them if it is possible of course.
#include <stdio.h>
#include <stdlib.h>
float getMinNum(float a[], int x);
int main()
{
int n = 5;
int i;
float z[n];
for(i=0; i<n; i++){
scanf("%f", &z[i]);
}
printf("%6.2f", getMinNum(z[], n));
return 0;
}
float getMinNum(float a[], int x)
{
int i, min = a[0];
for(i=0; i<x; i++){
if(min > a[i+1]){
min = a[i+1];
}
}
return min;
}
You shouldn't append '[]' to the variable name.
Instead of:
printf("%6.2f", getMinNum(z[], n));
do:
printf("%6.2f", getMinNum(z, n));
Your a[i+1] will be using values outside the array, so use a[i] instead.
So the code should look like
float getMinNum(float a[], int x){
int i;
float min = a[0]; // Min needs to be a float
for(i=1; i<x; i++){ // Do not need to check a[0]
if(min > a[i]){
min = a[i];
}
}
return min;
}
And call it as
printf("%6.2f", getMinNum(z, n));

Sum of array in C

I'm working on a small program for school and can't get my array of doubles to sum properly. The specific error I'm getting is
warning C4244: 'return': conversion from 'double' to 'int', possible loss of data
on the line where sum is returned. And the sum displayed is gibberish.
The code is intended to:
fill an array of doubles with user input,
print the doubles on the screen in a column,
add up all the doubles in the array, and
print the sum onto the screen.
Code
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#define MAX_SIZE 15
void FillArray(double a[], int *i);
void PrintArray(double a[], int i);
SumArray(double a[], int *i);
int main()
{
double input[15];
int input_size;
double sum;
FillArray(input, &input_size);
PrintArray(input, input_size);
sum = SumArray(input, &input_size);
printf("The sum is %f\n", sum);
return 0;
}
void FillArray(double a[], int *i)
{
int k;
printf("Filling an array of doubles\n");
printf("How many doubles do you want to enter (<15)\n");
scanf(" %d", i);
for (k = 0; k <*i; k++)
{
printf("Enter double:\n");
scanf("%lf", &a[k]);
}
}
void PrintArray(double a[], int i)
{
int k;
printf("Printing an array of integers:\n");
for (k = 0; k<i; k++)
{
printf("%f\n", a[k]);
}
printf("\n");
}
SumArray(double a[], int *i)
{
int k;
double sum = 0;
for (k = 0; k<*i; k++);
{
sum +=a[k];
}
return (sum) ;
}
You need to specify double SumArray(...) instead of merely SumArray(...) where you declare and define the function. If you do not specify a return type, int is assumed. Specifically:
void FillArray(double a[], int *i);
void PrintArray(double a[], int i);
double SumArray(double a[], int *i);
/*^^^^^^-- add return type*/
int main()
and
double SumArray(double a[], const int numElements)
/*^^^^^^- same deal*/ /* also ^^^^^ ^^^^^^^^^^^ */
{
int k;
double sum = 0.0; /* Edit 3: 0.0 rather than 0 for clarity */
for (k = 0; k < numElements; ++k) /* no ; here! --- Edit 3: ++k for speed and good practice */
{ /* ^^^^^^^^^^^ */
sum +=a[k];
}
return (sum) ;
}
Edit Also, you can use const int numElements instead of int *i in SumArray. You don't need to modify the value inside SumArray, so you don't need the * and you can specify const. And it's a good practice to give your variables descriptive names, e.g., numElements instead of i. That will help you understand your own code when you have to maintain it later! (Ask me how I know. ;) )
To use this, you also need to change the call in main to remove the &:
sum = SumArray(input, input_size);
/* ^ no & here */
Edit 2 As #BLUEPIXY pointed out, the trailing ; on the for loop was misplaced. As a result, the {} block ran once, after the loop had completed. That would be a significant cause of the "gibberish" you saw: the effect was to set k=numElements and then set sum=a[numElements], which was a non-existent element. So the sum was being set to whatever random memory contents happened to be after a.

Resources