Program for 1-D Statistics - c

So I'm having some issues with a program I'm writing to calculate statistics of an arbitrary amount of numbers. As you probably know, C does not have a native way of growing an array based on user input, so I made one. I'm not too familiar with pointers as I have not learned them yet. However, the main issue I'm having is that my program will not allow me to input anymore than 16 numbers. Any ideas on why?
#include <stdio.h>
#include <math.h>
float getMin(float arr[], int size)
{
int i;
float minimum = arr[0];
for (i=1; i < size; i++) {
if (arr[i] < minimum) {
minimum = arr[i];
}
}
return(minimum);
}
float getMax(float arr[], int size)
{
int i;
float maximum;
for(i=0; i<size; i++) {
if (arr[i] > maximum) {
maximum = arr[i];
}
}
return(maximum);
}
float getAverage(float arr[],int size)
{
int i;
float avg, sum;
for(i=0; i<size; i++) {
sum += arr[i];
}
avg = sum/size;
return avg;
}
float getVar(float arr[], int size, float average)
{
int i;
float var, diff[size], sq_diff[size], sum;
for(i=0; i<size; i++) {
diff[i] = arr[i] - average;
}
for(i=0; i<size; i++)
{
sq_diff[i] = pow(diff[i], 2);
}
var=getAverage(sq_diff, size);
return(var);
}
float getStdDev(float var)
{
float std_dev = sqrt(var);
return(std_dev);
}
int main(void)
{
int n=0, i=0;
float array[n], x;
printf("This program computes 1-D statistics.");
printf("\nEnter a negative number to stop input.\n");
do {
printf("Number %d: ", i+1);
scanf("%f", &x);
n++;
array[i] = x;
i++;
}while(x >= 0);
float avg = getAverage(array, n-1);
float var = getVar(array, n-1, avg);
printf("\nMinimum: %f", getMin(array, n-1));
printf("\nMaximum: %f", getMax(array, n));
printf("\nAverage: %f", getAverage(array, n-1));
printf("\nVariance: %f", getVar(array, n-1, avg));
printf("\nStandard Deviation: %f", getStdDev(var));
return(0);
}

I am afraid you have some general miss-understanding of how C and programming languages work in general. Programming is not exactly the same as math. If you declare a variable n and an array myarr[n], your array won't grow as n grows. The array will take the value n had at the point you declared it and will use that. Also declaring arrays like that is probably not a good idea, I don't think many C compilers will compile what one would expect. In your case you are declaring an array of size 0, the fact that it seems to work up to 16 numbers is completely system dependent. You can not expect this kind of behavior to be consistent over different systems/compilers.
Instead what you should do if you really need this is use dynamic memory. I have written a simple example really fast you could use. This is by no means a complete but for your needs it should be good enough. Use the initArr(&arr) whenever you create a new growing array. If for example you have an array of type MyArr with name arr you can get the data of the array like this arr.data[i] while you can get the length of the array (the meaningful data) like this arr.len. Finally you can get the current max size of your array like this arr.size. Please not that you should only add new elements using addElement(&arr, x) as this function will take care of the array growth. When you are done using your array you can use destrArr(&arr) to free the memory. This is good practice even though when your program exits the memory is freed anyway.
Finally please review your functions. I haven't been through your logic but remember that you should never exceed boundaries. For example you should not try to access array[-1] or array[size_of_array] where size_of_array is the total size of your array. Remember that an array declared as float arr[100] can only safely be used in the region arr[0] to arr[99]. Also doing sum += x is equivalent to doing sum = sum + x. Consider what the initial value of sum is if you do not initialize it. In fact it depends but could contain garbage values.
Try looking at your compiler warnings and fix them. It is worth understanding them and are rarely worth neglecting. Try the -Wall flag if you are using gcc, it might give you some more warnings worth looking at.
I hope this was helpful and not too confusing. In any case have a look at the following code and add your functions and libraries back. This should work out of the box.
Good Luck! :)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INIT_SIZE 2
typedef struct MyArr {
float *data;
int size;
int len;
} MyArr;
int initArr(MyArr *arr) {
arr->data = (float *)malloc(INIT_SIZE*sizeof(float));
if (arr->data == NULL) {
printf("OUT OF MEMORY\n");
return -1;
}
arr->size = INIT_SIZE;
arr->len = 0;
return 1;
}
int addElement(MyArr *arr, float x) {
if (arr->len == arr->size) {
int i;
float *tmp = (float *)malloc(2*arr->size);
if (tmp == NULL) {
printf("OUT OF MEMORY\n");
return -1;
}
for (i = 0; i < arr->size; ++i) {
tmp[i] = arr->data[i];
}
free(arr->data);
arr->data = tmp;
arr->size = 2*arr->size;
}
arr->data[arr->len] = x;
arr->len++;
return 1;
}
void destrArr(MyArr *arr) {
free(arr->data);
arr->size = 0;
arr->len = 0;
}
int main(void)
{
int n=0, i=0;
float x;
MyArr array;
initArr(&array);
printf("This program computes 1-D statistics.");
printf("\nEnter a negative number to stop input.\n");
do {
printf("Number %d: ", i+1);
scanf("%f", &x);
n++;
addElement(&array, x);
i++;
}while(x >= 0);
float avg = getAverage(array.data, n-1);
float var = getVar(array.data, n-1, avg);
printf("\nMinimum: %f", getMin(array.data, n-1));
printf("\nMaximum: %f", getMax(array.data, n));
printf("\nAverage: %f", getAverage(array.data, n-1));
printf("\nVariance: %f", getVar(array.data, n-1, avg));
printf("\nStandard Deviation: %f", getStdDev(var));
destrArr(&array);
return(0);
}

Related

I want to make a program in C which takes an array as an input and tells which number are perfect squares

#include<stdio.h>
#include<math.h>
int perfectSquare(int arr[], int n);
int main()
{
int n , arr[n];
printf("number of elements to store in array");
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
printf("enter %d number", i+1);
scanf("%d", &arr[i]);
}
perfectSquare(arr, n);
return 0;
}
int perfectSquare(int arr[], int n)
{
int i;
int a;
for (i = 0; i <= n; i++) //i=4 arr[4]==9 //arr[1]=2 i=1
{
a=sqrt((double)arr[i]); //a=3 //a=1.454=1
if ( a*a==arr[i] ) //a==3*3==9==arr[4] //a*a=1!=arr[2]
printf("%d", arr[i]);
}
}
I am new to coding and I am currently learning c. I came up with this code but it doesn't work can someone tell me what is the problem with this code?
There are a couple of issues with this exercise, but generally you're on the right track. Here, a version of your example with some possible corrections:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void perfect_square(int arr[], int n);
int main(void)
{
int i, n, *arr;
printf("number of elements to store in array: ");
scanf("%d", &n);
if (n <= 0)
return -1;
arr = malloc(n*sizeof(int));
if (arr == NULL)
return -2;
for (i = 0; i < n; i++) {
printf("enter number %d: ", i+1);
scanf("%d", &arr[i]);
}
perfect_square(arr, n);
free(arr);
arr = NULL;
return 0;
}
void perfect_square(int arr[], int n)
{
int i, a;
for (i = 0; i < n; i++) {
a = (int)sqrt((double)arr[i]);
if (a*a == arr[i])
printf("%d ", arr[i]);
}
}
Some hints:
Arrays, that have an unknown size at compile time are usually allocated with malloc(), and must be deallocated again with free() (see also: alloca(), calloc(), realloc()). (In "more recent versions of C" there is also the possibility to use variable length arrays, but those can limit the portability of the code).
Always make sure to check the start value and end condition of for-loops, to prevent out of bound errors.
And try to consistently format the code, use good names and nice indentation to improve read-, maintain-, reusablilty.

how can i create a function to read the numbers that the user inserts into an array in c?

I am new to programing.
I'm doing an exercise witch the user inserts numbers in an array and the program prints the average of those numbers.
But part of the exercise is making the numbers that the user inserts using a function, and thats where i'm struggling.
my code:
#include <stdio.h>
main() {
int n = 10, i, array1[10];
float sum = 0.0, average;
printf("insert 10 numbers\n");
for (i = 0; i < n; ++i) {
printf("insert digit no%d: ", i + 1);
scanf("%d", &array1[i]);
sum += array1[i];
}
average = sum / n;
printf("average = %.2f", average);
return 0;
}
all the help is much apreciated :)
Here's a small program to show you how functions work:
#include "stdio.h"
void foo(int array[], int size)
{
for (int i = 0; i < size; i++)
scanf("%d", &array[i]);
}
size_t bar(int array[], int size)
{
int sum = 0;
for (int i = 0; i < size; i++)
sum += array[i];
return (sum);
}
int main(void)
{
int array[3] = {0};
int sum;
foo(array, 3);
sum = bar(array, 3);
printf("array sum = %d\n", sum);
return (0);
}
foo and bar are two functions, they both have a return type on the left side, a name (foo/bar), some parameters in the parentheses, and their body declaration between braces.
When you call a function from your main, you'll have to call it with its required parameters. In my exemple, both functions need an integer array, and an integer value as parameters. That's why we called it this way from the main: foo(array, 3); and bar(array, 3).
When we call a function, the given parameters are copied into memory so you can work with those params into the function body as if they were variables.
Some functions have a return type different than void. Those functions are able to (and must) return a value of the return type with the return statement. Those values can be used, assigned etc, as you can see with the instruction sum = bar(array, 3);
Even the main is a function !
If you want to move user input and average calculation into separate methods. It should be done something like this.
#include <stdio.h>
/*
* Takes an array and get input for N items specified
*/
void getUserInputForArray(int array[], int N) {
printf("insert %d numbers\n", N);
for (int i = 0; i < N; ++i) {
printf("insert digit no %d: ", i + 1);
scanf("%d", &array[i]);
}
}
/*
* Calculate average for a given array of size N
*/
float getAverage(int array[], int N) {
// Initialize sum to 0
float sum = 0.0f;
// Iterate through array adding values to sum
for (int i = 0; i < N; i++)
sum += array[i];
// Calculate average
return sum / N;
}
int main() {
int n = 10, array1[10];
// Pass array to method, since arrays in C are passed by pointers.
// So Even if you modify it in method it would get reflected in
// main's array1 too
getUserInputForArray(array1, n);
// Calculate Average by delegating average calculation to getAverage(...) method
float average = getAverage(array1, n);
printf("average = %.2f", average);
return 0;
}

How to for loop an array then put elements into a list format?

I'm writing a program which scanf integers and printf in double.
Here is my code:
int main(void) {
int arraySize;
scanf("%d",&arraySize);
double vector[arraySize];
for(int i=0;i<arraySize;i++) scanf("%lf", &vector[i]);
for(int a=0;a<arraySize;a++) printf("VECTORS:[%lf]",vector[a]);
}
Since I need to for loop every element in the array then printf all of them one by one.
this is the output I had:
VECTORS:[1.000000] VECTORS:[2.000000] VECTORS:[3.000000]
How can I change the format of the printf function and get ouput like this:
VECTOR: [ 1.000, 2.000, 3.000 ]
Your one major mistake is your array size. I know your compiler won't issue any warning but this is not any feature which language provide so size must be a
constant numerical value or const expression.
So in short you can't create array After asking size from user. This is completely wrong.
int arraySize;
scanf("%d",&arraySize);
double vector[arraySize];
You must make size const. If you want less values than the declared size you can decrease the no of times for loop will run but you can't decide array size as inputted by user.
const int size = 10; // this is how your size should be. Even your compiler allowed VLA you should not try this. size of arrays must be constant.
int main()
{
unsigned int i,s;
int arr[size];
printf ("Enter the size of array.");
scanf("%d",&s);
for(i = 0 ; i<s;i++){
scanf("%d",&arr[i]);
}
for(i = 0 ; i<s;i++){
arr[i] = arr[i]*arr[i];
}
for(i = 0 ; i<s;i++){
printf("%d",arr[i]);
}
}
Print VECTOR once then loop over all the vectors and output them in the desired format.
const int size = 10;
int main(void) {
double vector[size];
for(int i=0;i<size;i++)
scanf("%lf", &vector[i]);
printf("VECTOR: [ ");
for(int a=0;a<size;a++){
printf("%lf", vector[a]);
if(i < size - 1)
printf(", ");
}
printf(" ]");
}
You need to allocate memory dynamically to use it.
Use the printf in the code below to define precision.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int arraySize = 0;
scanf("%d",&arraySize);
double *vector = (double *) calloc(arraySize, sizeof(double));
for(int i=0; i<arraySize; i++) {
scanf("%lf", &vector[i]);
}
printf("VECTORS:[");
int a;
for(a=0;a<arraySize;a++) {
printf(" %.3lf",vector[a]);
if (a<(arraySize-1)) {
printf(",");
} else {
printf(" ");
}
}
printf("]");
}
Change your for loop to take 3 elements at once.
for(a=0;a<arraySize;a+=3) {
printf("VECTORS:[%lf", vector[a]);
if (a+1 < arraySize) printf(", %lf", vector[a+1]);
if (a+2 < arraySize) printf(", %lf", vector[a+2]);
printf("]\n");
}

summing numbers using pointer arithmetic

I was given an assignment to write a code which takes in numbers as input from the user and provides the sum of it, specifically by the use of pointer arithmetic i.e. no array subscripting a[i] is allowed.
Below is the code that I wrote, which got compiled and even ran. But almost always it gives the sum of the input numbers as 0. I tried to fix it, but to no avail. Thus, I am asking for help, any help is greatly appreciated.
#include<stdio.h>
#define N 5
int sum_array( const int *p, int n)
{
int sum, a[N];
sum = 0;
for(p=&a[0]; p<&a[N]; p++)
sum += *p;
return sum;
}
int main()
{
int a[N], *i,x;
printf("Enter %d Numbers: ", N);
for(i=a; i<a+N; i++)
scanf("%d", i);
// all the input values get scanned as i or the array a
x= sum_array(i,N);
printf("the sum is %d\n", x);
return 0;
}
Beware, you are declaring array int a[N] in both main and sum_array. They are in different scopes, so they are different arrays (and the one from sum_array is never initialized so reading it invokes Undefined Behaviour).
The correct way is to pass the array along with its used length:
Here is a fixed version:
#include<stdio.h>
#define N 5
int sum_array( const int *a, int n) // a points to a array of at least n elements
{
int sum = 0; // initialize at definition time
for(const int *p=a; p<&a[n]; p++) // have the pointer p take all values from a
sum += *p;
return sum;
}
int main()
{
int a[N], *i,x;
printf("Enter %d Numbers: ", N);
for(i=a; i<a+N; i++)
scanf("%d", i);
// all the input values get scanned as i or the array a
x= sum_array(a,N); // pass the array address, not a pointer past last element
printf("the sum is %d\n", x);
return 0;
}
Finally it is mainly a matter of taste, but I was too often burnt for trying to add an instruction in a for loop without braces, so I strongly recommend using always braces for loops:
for(i=a; i<a+N; i++) {
scanf("%d", i);
}
int sum_array( const int *p, int n)
{
int sum = 0, i = 0;
for(i = 0; i < n ; i++)
sum += *(p+i);
return sum;
}
int main(void)
{
int a[N], i = 0, x = 0;
printf("Enter %d Numbers: ", N);
for(i=0; i<N; i++)
scanf("%d", a+i);
// all the input values get scanned as i or the array a
x= sum_array(a,N);
printf("the sum is %d\n", x);
return 0;
}
In x= sum_array(i,N); i is the iterator of your loop so after the loop has finished it points to the first position after the array.
You should pass the original array instead x= sum_array(a,N);
In the sum function you just throw away the passed pointer and replace it with your local a[].
int sum_array( const int *p, int n)
{
int sum = 0;
int *end = &p[n]; // first element after the array.
for(; p<end; p++) // just use p because you don't need the reference to the start of the array
{
sum += *p;
}
return sum;
}
but as you said that array notation is not allowed you can change it as follows
#include "stdio.h"
#define N 5
int sum_array( const int *p, int n)
{
int sum = 0;
const int *end = p+n; // first element after the array.
for(; p<end; p++)
{
sum += *p;
}
return sum;
}
int main()
{
int *a, *i, x;
a = malloc(N * sizeof(*a));
if (a == NULL)
exit(-1);
printf("Enter %d Numbers: ", N);
for(i=a; i<a+N; i++)
{
scanf("%d", i);
}
// all the input values get scanned as i or the array a
x= sum_array(a,N); // pass the array address, not a pointer past last element
printf("the sum is %d\n", x);
return 0;
}
in general, when programming, the code should be kept as simple as possible while still being complete.
The program criteria shows no need to keep a number after it is applied to the sum of the numbers, So in the proposed code, the input number is only kept long enough to be applied to the sum, then it is discarded.
The following proposed code:
cleanly compiles
performs the desired functionality
is kept very simple
properly checks for; and handles any errors
And now the proposed code:
#include <stdio.h> // scanf(), printf(), fprintf(), stderr
#include <stdlib.h> // exit(), EXIT_FAILURE
#define N 5
int main( void )
{
int num = 0;
int sum = 0;
printf("Enter %d Numbers: ", N);
for(size_t i=0; i<N; i++)
{
if( scanf("%d", &num) != 1 )
{
fprintf( stderr, "failed to read number\n" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
sum += num;
}
printf( "the sum is %d\n", sum );
return 0;
}

How to read space-separated integers representing the array's elements and sum them up in C

How to read space-separated integers representing the array's elements and sum them up in C?
I used the below code but it reads all the elements in a new line:
#include <math.h>
#include <stdio.h>
int main() {
int i = 0, N, sum = 0, ar[i];
scanf("%d" , &N);
for (i = 0; i < N; i++) {
scanf("%d", &ar[i]);
}
for (i = 0; i < N; i++) {
sum = sum + ar[i];
}
printf("%d\n", sum);
return 0;
}
Your array ar is defined with a size of 0: the code invokes undefined behavior if the user enters a non zero number for the number of items.
Furthermore, you should check the return value of scanf(): if the user enters something not recognized as a number, your program will invoke undefined behavior instead of failing gracefully.
Here is a corrected version:
#include <stdio.h>
int main(void) {
int i, N, sum;
if (scanf("%d", &N) != 1 || N <= 0) {
fprintf(stderr, "invalid number\n");
return 1;
}
int ar[N];
for (i = 0; i < N; i++) {
if (scanf("%d", &ar[i]) != 1) {
fprintf(stderr, "invalid or missing number for entry %d\n", i);
return 1;
}
}
sum = 0;
for (i = 0; i < N; i++) {
sum += ar[i];
}
printf("%d\n", sum);
return 0;
}
Note that the program will still fail for a sufficiently large value of N as there is no standard way to check if you are allocating too much data with automatic storage. It will invoke undefined behavior (aka stack overflow).
You should allocate the array with malloc() to avoid this:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i, N, sum;
int *ar;
if (scanf("%d", &N) != 1 || N <= 0) {
fprintf(stderr, "invalid number\n");
return 1;
}
ar = malloc(sizeof(*ar) * N);
if (ar == NULL) {
fprintf(stderr, "cannot allocate array for %d items\n", N);
return 1;
}
for (i = 0; i < N; i++) {
if (scanf("%d", &ar[i]) != 1) {
fprintf(stderr, "invalid or missing number for entry %d\n", i);
return 1;
}
}
sum = 0;
for (i = 0; i < N; i++) {
sum += ar[i];
}
printf("%d\n", sum);
free(ar);
return 0;
}
Finally, there is still a possibility for undefined behavior if the sum of the numbers exceeds the range of type int. Very few programmers care to detect such errors, but it can be done this way:
#include <limits.h>
...
sum = 0;
for (i = 0; i < N; i++) {
if ((sum >= 0 && arr[i] > INT_MAX - sum)
|| (sum < 0 && arr[i] < INT_MIN - sum)) {
fprintf(stderr, "integer overflow for entry %d\n", i);
return 1;
}
sum += ar[i];
}
#include <math.h>
#include <stdio.h>
int main()
{
int i=0,N,sum=0;
scanf("%d" ,&N);
int ar[N];
for(i=0; i<N; i++)
scanf("%d",&ar[i]);
for(i=0; i<N; i++)
sum=sum+ar[i];
printf("%d\n", sum);
return 0;
}
This should be the code.
You have initially declared the array of size 0 (because i=0).
Even though you declared the array of size 0, when I ran it on my machine, it actually executed successfully with the correct output.
This is generally due to undefined behavior which means that we can only guess the output when the code is correct. If the code has undefined behavior, then it can do whatever it wants (and in the worst case the code will execute successfully giving the impression that it's actually correct).
Declaring a Variable Size Array (VLA) is optional in C11 standard. Thus, it depends on the implementation of the compiler whether it will support VLA or not. As pointed out by #DavidBowling in comments, if the compiler does support, then declaring a VLA of size 0 can invoke undefined behavior (which you should avoid in all cases). If it doesn't support, then this will simply give a compilation error and you'll have to declare the array size as some integer constant (example, int arr[100];).
#include <math.h>
#include <stdio.h>
int main()
{
int i=0,N,sum=0;
scanf("%d" ,&N);
int ar[N];
for(i=0; i<N; i++)
{
scanf("%d",&ar[i]);
}
for(i=0; i<N; i++)
{
sum=sum+ar[i];
}
printf("%d\n", sum);
return 0;
}
You should declare the array after accepting the value of N.
#include <math.h>
#include <stdio.h>
int main()
{
int i=0,N,sum=0;
scanf("%d" ,&N);
int ar[N];
for(i=0; i<N; i++)
{
scanf("%d",&ar[i]);
sum=sum+ar[i];
}
printf("%d\n", sum);
return 0;
}
As this is a very simple question I'll expand it a bit to include some good programming practices.
1. Analyze the problem
We have to complete two tasks here:
Read and store the numbers to array.
Sum the array elements.
Of course you can both read and calculate the same time, but we ❤ the SoC design principle. This will help you later with bigger programs.
2. Create the program structure
In this state we have to consider what function to use, as we already solved the data structure problem (we use array).
Of course, we always can put the whole procedure in main function but this would break the SoC principle.
The main principle here is:
I create a function for a separate procedure.
So we'll have to build two functions. Let's consider the following example:
ReadArrayData will be used to read the data from the standard input (your keyboard in other words) to array. But what will declare as parameters? We surely have to pass the array and the array size. The return type of this function will be void (we don't have to return something).
Keep in mind that if you pass array to function you can manipulate it as you please and keep these changes in your main program. This is because the arrays are passed always by reference to a function.
In the end this will be your function prototype:
void ReadArrayData(int arraySize, int array[]);
CalculateArraySum will be used to calculate the sum of the array elements. The function prototype will be the same as for ReadArrayData with the difference that the returning type will be int (we return the sum).
int CalculateArraySum(int arraySize, int array[]);
3. Write your program
#include <stdio.h>
void ReadArrayData(int arraySize, int array[]);
int CalculateArraySum(int arraySize, int array[]);
int main(void) {
int N;
printf("Give the array size: ");
scanf("%d", &N);
int array[N];
ReadArrayData(N, array);
int sumOfArrayElements = CalculateArraySum(N, array);
printf("The sum of array elements is %d.\n", sumOfArrayElements);
return 0;
}
void ReadArrayData(int arraySize, int array[]) {
printf("Give %d elements: ", arraySize);
for (int i = 0; i < arraySize; ++i) {
scanf("%d", &array[i]);
}
}
int CalculateArraySum(int arraySize, int array[]) {
int sum = 0;
for (int i = 0; i < arraySize; ++i) {
sum += array[i];
}
return sum;
}
I know this was a large scaled answer, but I saw you are new to computer programing. I just wanted to present you the main functionality to solve all kinds of problems. This was just a small introduction. In the end, you have to remember what steps we take to solve a problem. With time and as you solve many problems you will learn many many other things.

Resources