2016-09-04 5 views
-6

Я пишу эту программу на C/C++, которая, как предполагается, найдет средний, медианный и режим массива различного размера. Хотя, я все равно получаю ошибку сегментации независимо от ввода. Что не так с моим кодом? Любые предложения всегда оценили! :)Ошибка кода: ошибка сегментации [EVERYTIME]

Вот код:

#include <stdio.h> 
//#include <string.h> 
//#include <math.h> 
#include <stdlib.h> 

Прототипы:

void sort(double*[],int); 
static int min(double,double[],int); 
double mean(double[],int); 
double median(double[],int); 
double mode(double[],int); 
int numberOf(double,double[],int); 

Основные функции:

int main() { 
    int i; 
    scanf(" %d ",&i); //10 
    double arr[i]; //array that contains all the values and will be sortted 
    for (int j=0; j<i; j++) { //64630 11735 14216 99233 14470 4978 73429 38120 51135 67060 
     scanf(" %lf ",&arr[j]); 
    } 
    printf("%.1lf\n%.1lf\n%.0lf",mean(arr,i),median(arr,i),mode(arr,i)); 
    return 0; 
} 

Сортировать Функция:
Конечный результат должен обновить обр массив от вызова в медианной функции. Изменяет используемые значения в исходном массиве до -1, пока это не весь массив.

void sort(double* arr[],int l) { 
    double arr2[l]; 
    for (int i=0; i<l; i++) { 
     int j; 
     if (i) 
      j = min(arr2[i-1], *arr, l); 
     else 
      j = min(0, *arr, l); 
     arr2[i] = *arr[j]; 
     *arr[j] = -1; 
    } 
    for (int i=0; i<l; i++) { 
     *arr[i] = arr2[i]; 
    } 
} 

Min Функция (вспомогательная функция для сортировки функции).
находит минимальное значение среди элементов массива, которые больше или равен minLookingTo
возвращает позицию значения находится в

static int min(double minLookingTo,double arr[],int l) { 
    int minP; 
    double minA = minLookingTo; 
    for (int i=0; i<l; i++) { 
     if (arr[i] == -1) 
      continue; 
     if (minLookingTo<=arr[i] && arr[i]<=minA) { 
      minP = i; 
      minA = arr[i]; 
     } 
    } 
    return minP; 
} 

средней Функция:
Возвращает среднее значение введенного массива с длиной л

double mean(double arr[],int l){ 
    double total = 0; 
    for (int i=0; i<l; i++) { 
     total += arr[i]; 
    } 
    return total/l; 
} 

Медиана Функция:
Использует Sort функции. Предполагая, что работает, возвращается медиана.

double median(double arr[],int l){ 
    sort(&arr,l); 
    double d = arr[(l/2)+1]; 
    double dd = arr[(l/2)]; 
    if (l%2!=0) 
     return d; 
    return (d+dd)/2; 
} 

Режим Функция:
Использует NumberOf функции для определения элемента массива с максимальным количеством повторов. Возвращает самое низкое значение самых высоких (равных) повторов.

double mode(double arr[],int l){ 
    int maxA; 
    int maxP; 
    for (int i=0;i<l;i++) { 
     int j = numberOf(arr[i],arr,l); 
     if (j>maxA) { 
      maxA = j; 
      maxP = i; 
     } 
     else if (j==maxA && arr[maxP]>arr[i]) 
      maxP = i; 
    } 
    double d = arr[maxP]; 
    return d; 
} 

NumberOf Функция:
Вспомогательная функция для функции Mode. Возвращает количество элементов с , глядя.

int numberOf(double looking,double arr[],int l) { 
    int amount = 0; 
    for (int i=0; i<l; i++) 
     if (looking == arr[i]) 
      amount++; 
    return amount; 
} 
+3

Одно предложение, запустить свой код в отладчике – Martin

+1

Это не неправильные вещи вы ищете, но я могу вам сказать, что: 1. Вы 'using 'scanf', [который, как известно, трудно использовать] (http://www.c-faq.com/stdio/scanfprobs.html). 2. Ugh, пожалуйста, не используйте строчные буквы L для имен переменных. 3. Не похоже, что вы приложили все усилия для того, чтобы изолировать, какая часть вашего кода терпит неудачу, и в этом случае этого не должно быть много. – jamesdlin

+0

Вы отметили вопрос как C и C++, поэтому мы не можем определить, какой язык/компилятор вы используете, и вы не определяете, где происходит сбой, поэтому вы, по-видимому, слишком ленивы, чтобы использовать отладчик даже один раз. – kfsone

ответ

1

В вашем коде имеется ряд ошибок. Некоторые из них:

  1. Вам не нужно (в данном случае) использовать пробелы в scanf. Это вызывает ошибку чтения.
  2. Вам не нужно передавать адрес массива функции, чтобы изменить ее значения. Массивы всегда передаются по ссылке. Таким образом изменить функцию от void sort(double*[],int); до void sort(double[],int);, внести необходимые исправления в функции и вызвать его с помощью sort(arr,l); вместо sort(&arr,l);
  3. функции
  4. Вашей мин() объявляет неинициализированную переменную minP, так что это переменный содержит мусор из вашей памяти.Цикл for() не вводит ни одно из условий if(), поэтому ваша функция заканчивается и возвращает неподвижную неинициализированную переменную minP. Это случайное значение затем используется для доступа к индексу в вашем массиве: j = min(0, arr, l); min возвращает случайное число, а затем arr2[i] = arr[j];, обращаясь к области запрещенной памяти, что вызывает ошибку ошибки сегментации. Та же проблема возникает с переменными maxP и maxA в функции mode().

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

+0

И компиляция с достаточным количеством предупреждений позволяет компилятору помочь. Он предупреждает меня о 'minP', но также и' maxP' и 'maxA'. (Я использовал 'gcc -O3 -g -std = c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -c mess11.c' после исправления его на' int main (void) ' .) –

+0

Подробно, «... пробелы в scanf. Это вызывает ошибку чтения». -> Это конечные пробелы в формате, которые вызывают проблему.Ведущие - только ненужные. – chux

1

Я отследил вашу ошибку сегментации к вашей процедуре sort(), вызванной median(). Вместо того, чтобы исправить sort(), я заменял qsort() из библиотеки, чтобы убедить себя, что это проблема:

// Median Function: 
// Uses the Sort Function. Assuming that works, returns the median. 

int comparator(const void *p, const void *q) { 

    double a = *((double *) p); 
    double b = *((double *) q); 

    return (a > b) - (a < b); // compare idiom 
} 

double median(double array[], int length) { 
    // sort(array, length); 

    qsort(array, length, sizeof(double), &comparator); 

    double d = array[length/2]; 

    if (length % 2 != 0) { 
     return d; 
    } 

    double dd = array[(length/2) - 1]; 

    return (d + dd)/2; 
} 

Для примера списка чисел при условии, после коррекции остальной части кода, это возвращает медиану 44627.5

Другие исправления:

Вы пропустили окончательный перевод строки здесь:

printf("%.1lf\n%.1lf\n%.0lf",mean(arr,i),median(arr,i),mode(arr,i)); 

Вы, вероятно, следует инициализировать переменные в mode():

double mode(double array[], int length) { 
    int maxA = INT_MIN; 
    int maxP = -1; 

    for (int i = 0; i < length; i++) { 
     int j = numberOf(array[i], array, length); 

     if (j > maxA) { 
      maxA = j; 
      maxP = i; 
     } else if (j == maxA && array[maxP] > array[i]) { 
      maxP = i; 
     } 
    } 

    return array[maxP]; 
} 
Смежные вопросы