Ошибка, которую вы получаете, потому что вы назвали локальную переменную такой же, как аргумент функции.
double readScores(double scoreArray /* parameter named scoreArray */)
{
double scoreArray[maxStudents]; // this cannot have the same name!
Код, который вы показали, показывает много путаницы. Я попытаюсь объяснить ошибки в нем.
cout<<scoreArray[1],scoreArray[2];
Это не выход элементы 1 и 2. Для того, чтобы сделать это, он должен быть cout << scoreArray[1] << scoreArray[2];
. Также обратите внимание, что массивы на C++ основаны на 0, поэтому первый элемент будет scoreArray[0]
, второй scoreArray[1]
, третий scoreArray[2]
и т. Д.
Код объявляет функцию с именем readScores
принимает указатель на double
и возвращение double
:
double readScores(double[]);
Но он определяет только функцию, принимая double
:
double readScores(double scoreArray)
я уверен, что это не то, что было предназначено, и как только ошибка компилятора будет исправлена, это приведет к ошибке компоновщика, потому что нет определения для функции double readScores(double[])
.
Теперь, массивы.
Когда вы пишете параметр double x[]
, это не массив. Это указатель на double
. Это точно такое же как double* x
. Да, синтаксис сильно вводит в заблуждение. Вот почему вы не должны его использовать. Это свистнет путаницу. Лучше быть явным и называть указатель указателем.
Вы не можете напрямую возвращать массивы в C++, и вы не можете напрямую передавать аргументы массива в C++. Вы можете передавать ссылки на массивы и возвращать ссылки на массивы, но здесь, похоже, у вас есть инструкции по использованию указателей, поэтому я туда не поеду.
Код, похоже, не использует значение, возвращаемое с readScores
, поэтому, вероятно, лучше использовать только возвращаемый тип void
. В любом случае код записывает значения непосредственно в массив.
void readScores(double* scorePtr)
Синтаксис *(scorePTR+count)
точно такой же, как scorePTR[count]
, так что нет никакой выгоды в ее использовании. И код итерации с индексом (count
) в любом случае.
Я полагаю, что назначение, связанное с этим ограничением, было чем-то полезным, хотя и незначительно: итерацией с помощью указателя, а не индекса. Для этого вам нужно найти три вещи: как начать цикл, как перейти к следующему элементу и как закончить цикл.
Как начать цикл? Вы должны начать с указателя на первый элемент. К счастью, такой указатель именно то, что передается в качестве аргумента функции.
for(double* ptr = scorePtr; /* ... */; /* ... */)
Как перейти к следующему элементу? Если вы увеличиваете указатель, он переходит к следующему элементу.
for(double* ptr = scorePtr; /* ... */; ++ptr)
Как закончить цикл? Цикл заканчивается, когда указатель прошел через весь массив. Массив имеет maxStudents
элементов, поэтому цикл заканчивается, когда указатель находится maxStudents
элементов от начала:
double* end = scorePtr + maxStudents;
for(double* ptr = scorePtr; ptr != end; ++ptr)
И как использовать этот указатель в цикле? Как обычно, с оператором разыменования.
for(double* ptr = scorePtr; ptr != end; ++ptr)
{
cout<<"Please enter score for student "<< /* (1) */ <<" or -999 to end.\n";
cin>>*ptr;
if(*ptr == -999)
break;
}
// (1) left as an exercise for the reader
Вы возвращаете указатель на массив из своей функции, но убедитесь, что вы ** не ** возвращаете указатель на * локальный * массив. –
Прототип функции должен быть «void readScore (double * scoreArray)», и вы не должны переопределять scoreArray внутри функции. –
@Als Должен ли быть «не» в этом комментарии? Возвращение локального массива никогда не бывает красивым. –