patterncModerate
Calculate sum, mean, sum of squares, and standard deviation of array elements
Viewed 0 times
deviationelementsarraymeansquaresstandardcalculatesumand
Problem
Also, I've commented out a function I was trying to do to count the elements of an array; I realized that is not possible due to the fact that I won't be be able to return a NULL on an array.
Although this part of a beginner to C exercise, I'd like to know if there is anything I can do to improve my coding.
```
#include
#include
#define MAX_ITEM 1000
double x[MAX_ITEM];
int arr_count(double x[]);
double sum(double x[], int arr_count);
double mean(double sum, int arr_count);
double sum_sqr(double x[], int arr_count);
double st_dev(double sum_sqr, double mean, int arr_count);
/*
int arr_count(double x[]) {
int i = 0;
int count = 0;
for (i = 0; i < MAX_ITEM; i++) {
if (x[i] != NULL){
count++;
}
}
return count;
}
*/
double sum(double x[], int arr_count){
int i = 0;
double my_sum = 0;
for (i = 0; i < arr_count; i++){
my_sum += x[i];
}
return my_sum;
}
double mean(double sum, int arr_count) {
return sum / arr_count;
}
double sum_sqr(double x[], int arr_count){
int i = 0;
double my_sum = 0;
for (i = 0; i < arr_count; i++){
my_sum += x[i] * x[i];
}
return my_sum;
}
double st_dev(double sum_sqr, double mean, int arr_count) {
return sqrt(sum_sqr/ arr_count - mean * mean);
}
int main(void){
int i;
int num;
int my_arr_count = 0;
double my_sum = 0;
double my_mean = 0;
double my_st_dev = 0;
printf("Enter the number of elements you want in the array between 0 and 1,000\n");
scanf("%d", &num);
//generate elements
for (i = 0; i < num; i++) {
x[i] = rand(time(NULL));
}
// print the generated elements
printf("The elements are:\n");
for (i = 0; i < num; i++){
printf("[%d] %lf\n", i+ 1, x[i]);
}
// my_arr_count = arr_count(x);
my_arr_count = num;
my_sum = sum(x, my_arr_count);
my_mean = mean(my_sum, my_arr_count);
my_st_dev = st_dev(sum_sqr(x,my_arr_count), my_mean, my_arr_count);
printf("There are %d elements in the random array", my_arr_count);
printf("the Su
Although this part of a beginner to C exercise, I'd like to know if there is anything I can do to improve my coding.
```
#include
#include
#define MAX_ITEM 1000
double x[MAX_ITEM];
int arr_count(double x[]);
double sum(double x[], int arr_count);
double mean(double sum, int arr_count);
double sum_sqr(double x[], int arr_count);
double st_dev(double sum_sqr, double mean, int arr_count);
/*
int arr_count(double x[]) {
int i = 0;
int count = 0;
for (i = 0; i < MAX_ITEM; i++) {
if (x[i] != NULL){
count++;
}
}
return count;
}
*/
double sum(double x[], int arr_count){
int i = 0;
double my_sum = 0;
for (i = 0; i < arr_count; i++){
my_sum += x[i];
}
return my_sum;
}
double mean(double sum, int arr_count) {
return sum / arr_count;
}
double sum_sqr(double x[], int arr_count){
int i = 0;
double my_sum = 0;
for (i = 0; i < arr_count; i++){
my_sum += x[i] * x[i];
}
return my_sum;
}
double st_dev(double sum_sqr, double mean, int arr_count) {
return sqrt(sum_sqr/ arr_count - mean * mean);
}
int main(void){
int i;
int num;
int my_arr_count = 0;
double my_sum = 0;
double my_mean = 0;
double my_st_dev = 0;
printf("Enter the number of elements you want in the array between 0 and 1,000\n");
scanf("%d", &num);
//generate elements
for (i = 0; i < num; i++) {
x[i] = rand(time(NULL));
}
// print the generated elements
printf("The elements are:\n");
for (i = 0; i < num; i++){
printf("[%d] %lf\n", i+ 1, x[i]);
}
// my_arr_count = arr_count(x);
my_arr_count = num;
my_sum = sum(x, my_arr_count);
my_mean = mean(my_sum, my_arr_count);
my_st_dev = st_dev(sum_sqr(x,my_arr_count), my_mean, my_arr_count);
printf("There are %d elements in the random array", my_arr_count);
printf("the Su
Solution
Let the compiler help you
The first thing to do is to compile with a decent compiler and look at the warnings. With
You're missing two headers,
For now, to get code that compiles, remove the arguments to
The last warning is there because
General style
Generally speaking, your code is well-organized and well-presented, congratulations. Here are a few minor improvements:
Output
-
The
-
Why are you printing
Random number generation
A second issue is that
Random number generation is a fairly complex topic; I recommend reading the clc FAQ, questions 13.15–13.20, especially Each time I run my program, I get the same sequence of numbers back from rand() and How can I generate floating-point random numbers?.
For the time being, add
Input validation
You read an integer with
Since
The first thing to do is to compile with a decent compiler and look at the warnings. With
gcc -O -Wall -W:dassouki.c: In function ‘main’:
dassouki.c:70: warning: implicit declaration of function ‘rand’
dassouki.c:70: warning: implicit declaration of function ‘time’
dassouki.c:90: warning: control reaches end of non-void functionYou're missing two headers,
stdlib.h and time.h, where the functions rand and time are declared. Once you add them you see another error:small_fixes.c: In function ‘main’:
small_fixes.c:72: error: too many arguments to function ‘rand’For now, to get code that compiles, remove the arguments to
rand, it doesn't take any. I'll explain about rand below.The last warning is there because
main function returns an int value; you neglected to do that. If your implementation conforms to C99 (few do, and the one I compiled with doesn't), there is a special dispensation for the main function: you can omit the return statement, and it's as if you'd written return EXIT_SUCCESS. For utmost portability, return EXIT_SUCCESS to indicate success, or EXIT_FAILURE to indicate failure. On unix and Windows, EXIT_SUCCESS is 0 and EXIT_FAILURE is 1, though any nonzero value (positive and up to 255, though you should stick to small values) indicates failure. If you don't return a value from main (and aren't using a C99 compiler), the effect on most platforms is that your program returns whatever was in a particular register when main finishes executing, which is not good.General style
Generally speaking, your code is well-organized and well-presented, congratulations. Here are a few minor improvements:
- The array
xdoesn't actually need to be global, you can make it local tomain. If you make it global, give it a longer name — global variables should be used sparingly and should be easily noticeable and searchable.
- Don't use abbreviations in the names of global variables or functions. Call your functions
square_sumorsum_of_squares,standard_deviation.
- The proper type for an array length is
size_t. On some machines, you can have arrays whose size doesn't fit into anint. Note thatsize_tis an unsigned type, which has the advantage that you won't run into the occasional difficulties of signed arithmetic, but you need to be careful with downwards loops (for (i=n; i>=0; i--)is an infinite loop ifiis unsigned).
Output
- You're missing newlines (
\n) at the end of severalprintfcalls.
- The
printfconversion specifier for adoubleis%f(or%eor%g), not%lf. Many implementations allow%lfas a synonym for%f, but this is not universal.
-
The
printf conversion specified for a size_t is %z, but that only exists if your implementation conforms to C99, which is still not the norm today. In C89 (the prevalent standard today), your best bet is to cast to unsigned long, e.g.printf("[%lu] %lf\n", (unsigned long)i, x[i]);-
Why are you printing
i+1 next to element number i? It's confusing. Print i and x[i] (as above).Random number generation
rand() generates a random integer between 0 and RAND_MAX. On many platforms, RAND_MAX is 32767. Here, you're storing this into a floating point array, so it looks like you want to generate a random floating-point number. This is a difficult problem, and the solution depends on what distribution you want. On unix/POSIX platforms, there is a function drand48 which generates a random floating-point number in the range [0,1] with a uniform distribution. This issue is unrelated to the meat of your program, so you may be content with generating a random integer with rand().A second issue is that
rand() and friends use a pseudo-random number generator. This means that they will always return the same sequence of numbers if they are initialized in the same way. Initializing a random generator is called seeding it, and the function to seed the PRNG is srand(int). If you never call that function, your program will always fill the array with the same values. A common way of initializing the PRNG for testing is srand(time(NULL)); this will make your program use different values every second (on most machines).Random number generation is a fairly complex topic; I recommend reading the clc FAQ, questions 13.15–13.20, especially Each time I run my program, I get the same sequence of numbers back from rand() and How can I generate floating-point random numbers?.
For the time being, add
srand(time(NULL)); near the beginning of your main() function, and fix the call to rand().Input validation
You read an integer with
scanf. This function is convenient for quick tests but tricky to use correctly. It's difficult to react properly if the user enters garbage.Since
num should be a positive integer, make it an unsigned type. In C99, make it size_t and call scanf("%z", &num). In C89, make itCode Snippets
dassouki.c: In function ‘main’:
dassouki.c:70: warning: implicit declaration of function ‘rand’
dassouki.c:70: warning: implicit declaration of function ‘time’
dassouki.c:90: warning: control reaches end of non-void functionsmall_fixes.c: In function ‘main’:
small_fixes.c:72: error: too many arguments to function ‘rand’printf("[%lu] %lf\n", (unsigned long)i, x[i]);scanf("%lu", &num);
if (num == 0 || num >= sizeof(x)/sizeof(x[0])) {
printf("Invalid number of elements, goodbye.\n");
return EXIT_FAILURE;
}Context
StackExchange Code Review Q#3566, answer score: 14
Revisions (0)
No revisions yet.