Вычислить сумму, среднее значение, сумму квадратов, и стандартное отклонение элементов массива


Кроме того, я закомментирована функция, что я пытался сделать для подсчета элементов массива; я понял, что это не возможно из-за того, что я не буду иметь возможность вернуть null в массиве.

Хотя эта часть начинающих упражнения с, я хотел бы знать, если есть все, что я могу сделать, чтобы улучшить свой процесс разработки.

#include <stdio.h>
#include <math.h>

#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 Sum is %lf", my_sum);
  printf("The Mean is %lf", my_mean);
  printf("The Standard Deviation is %lf", my_st_dev);

}


3190
8
задан 20 июля 2011 в 05:07 Источник Поделиться
Комментарии
4 ответа

увидеть, где вы сделали

  //generate elements
for (i = 0; i < num; i++) {
x[i] = rand(time(NULL));
}

Это хороший признак, вам нужна функция. Же контракт на другом месте вы положили комментарий

х не должен быть глобальным. Должны быть местные в основном.

5
ответ дан 20 июля 2011 в 09:07 Источник Поделиться

Пусть компилятор помогают

Первое, что нужно сделать, это составить с приличным компилятором и посмотрите на предупреждения. С ССЗ -о-стены -ж:

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 function

Вы упускаете два заголовка, stdlib.ч и время.ч, где функции слчис и время объявляются. После того как вы добавить их можно увидеть другую ошибку:

small_fixes.c: In function ‘main’:
small_fixes.c:72: error: too many arguments to function ‘rand’

Теперь, чтобы получить код, который компилируется, удалить аргументы Рэнд, он не принимает любые. Я объясню о Рэнд ниже.

Последнее предупреждение есть, потому что главная функция возвращает тип int значение; вы забыли это сделать. Если ваша реализация соответствует С99 (несколько делать, и я составил с не), есть специальное разрешение для основная функция: можно не возвращать заявление, а это как если бы вы писали возвращает EXIT_SUCCESS. Для максимальной переносимости, возвращает EXIT_SUCCESS , чтобы указать на успех или EXIT_FAILURE , чтобы указать отказ. В Unix и Windows, EXIT_SUCCESS 0 и EXIT_FAILURE является 1, хотя любое ненулевое значение (положительное и до 255, хотя вы должны придерживаться малых значений) указывает на ошибку. Если вы не возвращает значение из главной (и не используете стандарте C99 компилятора), эффект на большинстве платформ является то, что ваша программа возвращает все, что было в определенный регистр, когда главный закончит работу, что не есть хорошо.

Общий стиль

Вообще говоря, ваш код-это хорошо организованная и хорошо представлены, поздравления. Вот еще несколько мелких улучшений:


  • Массива х на самом деле не должны быть глобальными, Вы можете сделать его локальным для основной. Если вы сделать его глобальным, дать ему длинное имя — глобальные переменные следует использовать с осторожностью и должны быть легко заметным и быстрым.

  • Не используйте сокращений в названиях глобальных переменных или функций. Вызов вашей функции square_sum или sum_of_squares, standard_deviation.

  • Правильный тип для массива длиной в size_t. На некоторых машинах, вы можете иметь массивы, чьи размеры не вписываются в инт. Обратите внимание, что представляют собой типы size_t - это беззнаковый тип, который имеет то преимущество, что вы не наткнетесь на трудности, которые иногда подписанных арифметика, но вы должны быть осторожны с вниз петель (Для (я=н; я>=0; я -) это бесконечный цикл, если я не подписан).

Выход


  • Вы упускаете символы новой строки () по итогам нескольких функции printf звонки.

  • В функции printf спецификатор преобразования для двойной является (или или ), а не %ЛФ. Множество реализаций позвольте %если в качестве синонима , но это не универсально.

  • В функции printf преобразования, указанные на size_t, так это , но это только если ваша реализация соответствует стандарту С99, который еще не является нормой сегодня. В С89 (преобладающий Стандарт Сегодня), ваш лучший выбор, чтобы бросить в длинное целое без знака, например

    printf("[%lu] %lf\n", (unsigned long)i, x[i]);

  • Почему вы печать я+1 рядом с элементом номер я? Это сбивает с толку. Печатать я и Х[я] (как выше).

Генерация случайных чисел

слчис() генерирует случайное целое число между 0 и RAND_MAX. На многих платформах, RAND_MAX - это 32767. Здесь, вы храните это в массив с плавающей точкой, так что, похоже, вы хотите генерировать случайные числа с плавающей запятой. Это сложная проблема, и решение зависит от того, какой дистрибутив вы хотите. В Unix/POSIX и платформ, есть функции drand48 , которая генерирует случайное число с плавающей точкой в диапазоне [0,1] с равномерным распределением. Этот вопрос не имеет отношения к мясу вашу программу, так что вы можете быть довольны генерации случайного числа с слчис().

Вторая проблема заключается в том, что ранд() и друзей использовать псевдо-генератор случайных чисел. Это означает, что они всегда возвращать одну и ту же последовательность чисел, если они инициализируются точно так же. Инициализация генератора случайных называется посев , и функция семя PRNG является srand(инт). Если вы никогда не вызывать эту функцию, ваша программа всегда будет заполнить массив с одинаковыми значениями. Распространенный способ инициализации ГПСЧ для тестирования srand(время(нуль)); это сделает ваши программы используют разные значения каждый второй (на большинстве машин).

Генерация случайных чисел-это довольно сложная тема, я рекомендую прочитать КГО вопросы и ответы, вопросы 13.15–13.20, особенно каждый раз, когда я запускаю мою программу, я получаю ту же последовательность чисел обратно с помощью функции RAND() и как я могу создать с плавающей точкой случайных чисел?.

На данный момент, добавить srand(время(нуль)); в начале вашей функции main() функция, и исправить вызов слчис().

Проверка ввода

Вы читали целое число с помощью функции scanf. Эта функция удобна для быстрых тестов, но сложно использовать правильно. Трудно правильно реагировать, если пользователь вводит мусора.

Так как число должно быть положительным целым числом, сделать это беззнаковый тип. В C99, сделать его реализация и вызов функции scanf("%я", &Нум). В С89, сделать его длинное целое без знака и вызова функции scanf("%Лу", &Нум).

Выполнять хоть какой-то маркер проверки Нум. Число должно быть положительным (если вы хотите разрешить 0, Вам необходимо добавить особый случай некоторые из ваших расчетов). И она не должна быть больше, чем размер массива.

scanf("%lu", &num);
if (num == 0 || num >= sizeof(x)/sizeof(x[0])) {
printf("Invalid number of elements, goodbye.\n");
return EXIT_FAILURE;
}

оператор sizeof(х)/размер(Х[0]) (который может также быть написан как sizeof(х)/оператор sizeof(*х)) это идиома для обозначения количества элементов в массиве х: это размер массива, деленному на размер одного элемента. Обратите внимание, что это работает только если Х является массивом, а не если Х является указателем. Указатели на массивы не содержат никаких указаний на размер массива, а размер должен быть указан отдельно (следовательно, ваш arr_count аргумент, когда вы передаете указатель на массив для различных функций).

14
ответ дан 25 июля 2011 в 08:07 Источник Поделиться

Захват семени возвращается от времени(null) в переменную и использовать то же значение для семян Рэнд. Это предотвращает вас от ненужных звонков на время(нуль) таким образом, что делает его быстрее, а также имеет дополнительный бонус, что она позволяет выполнить контролируемых испытаний путем присвоения семян на постоянное значение (получаем тот же "случайных" чисел при каждом запуске).

2
ответ дан 21 июля 2011 в 11:07 Источник Поделиться

Я не верю, что вы используете слчис() правильно. ранд() не принимает никаких параметров. Вы можете думать о srand(без знака *семя), которое вы должны вызвать один раз в начале, перед вызовом функции RAND().

Кроме того, вы должны включать для слчис().

2
ответ дан 23 марта 2014 в 06:03 Источник Поделиться