#c #debu&&in&
#c #отладка
Вопрос:
Я использую & в fedora linux 13. Я просто отрабатываю некоторые упражнения из моего учебника по c и не могу скомпилировать эту программу. Вот код:
double *MovieData::calcMed() {
double medianValue;
double *medValPtr = amp;medianValue;
*medValPtr = (sortArray[numStudents-1] / 2);
return medValPtr;
}
Вот объявление класса:
class MovieData
{
private:
int *students; // students points to int, will be dynamically allocated an array of inte&ers.
int **sortArray; // A pointer that is pointin& to an array of pointers.
double avera&e; // Avera&e movies seen by students.
double *median; // Median value of movies seen by students.
int *mode; // Mode value, or most frequent number of movies seen by students.
int numStudents; // Number of students in sample.
int totalMovies; // Total number of movies seen by all students in the sample.
double calcAv&(); // Method which calculates the avera&e number of movies seen.
double *calcMed(); // Method that calculates the mean value of data.
int *calcMode(); // Method that calculates the mode of the data.
int calcTotalMovies(); // Method that calculates the total amount of movies seen.
void selectSort(); // Sort the Data usin& selection sort al&orithm.
public:
MovieData(int num, int movies[]); // constructor
~MovieData(); // destructor
double &etAv&() { return avera&e; } // returns the avera&e
double *&etMed() { return median; } // returns the mean
int *&etMode() { return mode; } // returns the mode
int &etNumStudents() { return numStudents; } // returns the number of students in sample
};
Вот мой конструктор и деструктор и selectSort():
MovieData::MovieData(int num, int movies[]) {
numStudents = num;
// Now I will allocate memory for student and sortArray:
if(num &&t; 0) {
students = new int[num];
sortArray = new int*[num];
// The arrays will now be initialized:
for(int index = 0;index < numStudents;index ) {
students[index] = movies[index];
sortArray[index] = amp;students[index];
}
selectSort(); // sort the elements of sortArray[] that point to the elements of students.
totalMovies = calcTotalMovies();
avera&e = calcAv&();
median = calcMed();
mode = calcMode();
}
}
// Destructor:
// Delete the memory allocated in the constructor.
MovieData::~MovieData() {
if(numStudents &&t; 0) {
delete [] students;
students = 0;
delete [] sortArray;
sortArray = 0;
}
}
// selectSort()
// performs selection sort al&orithm on sortArray[],
// an array of pointers. Sorted on the values its
// elements point to.
void MovieData::selectSort() {
int scan, minIndex;
int *minElement;
for(scan = 0;scan < (numStudents - 1);scan ) {
minIndex = scan;
minElement = sortArray[scan];
for(int index = 0;index < numStudents;index ) {
if(*(sortArray[index]) < *minElement) {
minElement = sortArray[index];
minIndex = index;
}
}
sortArray[minIndex] = sortArray[scan];
sortArray[scan] = minElement;
}
}
Компилятор выдает эту ошибку:
moviedata.cpp : В memberfunction ‘double * MovieData::calcMed()’:
moviedata.cpp:82: ошибка: недопустимые операнды типов ‘int*’ и ‘double’ в двоичный ‘operator/’
Я не уверен, что делать с этой ошибкой, я пробовал статическое приведение типов, но безуспешно, что означает это сообщение об ошибке?
Комментарии:
1. Судя по всему, sortArray на самом деле будет динамически распределяемым массивом указателей на целые числа.
Ответ №1:
вы пытаетесь разделить указатель на double, о чем компилятор говорит, что он не знает, как это сделать.
sortArray, вероятно, определяется
int ** sortArray;
также стоит отметить, что вы возвращаете указатель на переменную стека, значение которой будет неопределенным, как только вы вернетесь из функции.
Комментарии:
1. что такое переменная стека? простите мое невежество.
2. Стек — это область памяти, используемая языками программирования для отслеживания вызовов функций, аргументов функций, возвращаемых значений и временных переменных, используемых в функциях masters-of-the-void.com/book5.htm
3. Отсюда также происходит термин «переполнение стека». т. е. когда в стеке заканчивается место и «переполняется» куча или другие области памяти
4.Лучшие ссылки en.wikipedia.or&/wiki/Stack-based_memory_allocation en.wikipedia.or&/wiki/Automatic_variable
Ответ №2:
sortArray[numStudents - 1]
является указателем на int, который не может находиться в левой части раздела (если вы помните, что указатели являются адресами, это имеет смысл). Если вы опубликуете больше своего кода, мы сможем помочь вам исправить это.
Возможно, вы хотите что-то вроде:
int *MovieData::calcMed() {
return sortArray[(numStudents - 1) / 2];
}
Это возвращает средний элемент в вашем массиве, который должен быть указателем на среднего ученика. Я не понимаю, почему вы сортируете списки указателей (не фактические значения) или почему вы возвращаете указатель здесь. Возвращаемое значение 1 будет указателем на следующее значение в students
, которое не является следующим большим значением численно. Таким образом, вы могли бы также вернуть фактический student (int из students
). Если вы сделаете это, вы также сможете усреднить два средних элемента при четном подсчете (это правило является частью типичного алгоритма медианы).
Обратите внимание, что я изменил возвращаемый тип на int *
, тип элементов sortArray. Кроме того, ваш комментарий неверен. Это медиана, а не среднее значение.
Кроме того, ваша сортировка выбора неверна. Внутренний цикл должен начинаться с scan 1
.
Комментарии:
1. какая часть кода была бы полезной, объявление класса?
2. Да, и где
sortArray
определено и инициализировано.3. Вы не можете разделить любой указатель ни на одно значение. Это просто не имеет смысла и не разрешено. Причина, по которой вы должны возвращать an
int *
, заключается в том, что каждый элемент в sortArray являетсяint *
. Если бы вы решили вернуть фактическую медиану, это было бы значение int. Да,scan 1
следует заменитьindex
. Смотрите этот псевдокод . Причина в том, что вы хотите поменять местами только с наименьшим более поздним элементом. Если вы поменяетесь местами с более ранним элементом, который меньше, вы отменяете свою предыдущую работу по сортировке.4. (numStudents — 1) / 2 неверно — например, вернет 1, когда numStudents == 4. Технически, чтобы правильно рассчитать медиану, вы должны использовать numStudents/2 для нечетного числа учащихся и среднее значение разыменованных значений в numStudents /2 и в (numStudents-1) / 2 для четного числа учащихся.
5. @sje397, я добавил заметку об этом. Ему пришлось бы возвращать значение int вместо указателя на
students
.
Ответ №3:
Ваш код показывает непонимание указателей. Вам нужно больше читать и практиковаться на более простых примерах.
Более конкретно:
double medianValue;
создает двойную переменную. Зачем? Очевидно, вы собираетесь вернуть double *
а возвращать указатель на локальную переменную всегда неправильно, потому что локальные переменные «перерабатываются», когда их функция завершается.
double *medValPtr = amp;medianValue;
создает указатель с именем medValPtr и устанавливает его в местоположение medianValue. Что ж.
Из-за текущего содержимого medValPtr, *medValPtr = (sortArray[numStudents-1] / 2);
имеет тот же эффект, что и ввод medianValue = (sortArray[numStudents-1] / 2);
(предположим, что он вообще должен был компилироваться).
Чего не происходит, потому что sortArray[numStudents-1]
это, по-видимому, последний элемент в массиве sortArray
, но это указатель на что-то другое. Вы не можете разделить указатель (численно вы можете, но C запрещает это всегда неправильно).
Наконец, вы, return medValPtr;
что неверно, потому что medValPtr
указывает на локальную переменную.
Комментарии:
1. Да, я все еще пытаюсь изучить указатели и динамическое распределение памяти. На самом деле я выполняю упражнения из моего учебника в главе «Указатели». Вы пытаетесь сказать, что у меня должен быть просто оператор return вместо всего остального мусора?
Ответ №4:
Вы, вероятно, хотите что-то вроде:
int *MovieData::calcMed() {
return sortArray[numStudents/2];
}