Как мне вернуть массив из функции? - PullRequest
2 голосов
/ 09 февраля 2012

Я изучаю указатели в классе, но я никогда не понимал массивы 100%

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

Я пытаюсь считать результаты в массив, но когда дело доходит до их возврата, я теряюсь. Я пробовал Google, но просто запутался, потому что люди говорят о динамической памяти и используют операнд new и delete, которого я еще не получил, и я не хочу делать неправильное назначение.

Мне нужен указатель пользователя вместо индекса, чтобы получить доступ к элементам в массиве. Приведенный ниже код дает мне ошибку «переопределение формального параметра« ScoreArray »»

#include <iostream>
using namespace std;

const int maxStudents = 30;
double readScores(double[]);

int main()
{
    double scoreArray[maxStudents];
    readScores(scoreArray);

    cout<<scoreArray[1],scoreArray[2];

    system ("PAUSE");
    return 0;
}

double readScores(double scoreArray)
{
    double scoreArray[maxStudents];
    double *scorePTR;
    *scorePTR = scoreArray;

    for(int count = 0; count < maxStudents; count++)
    {
        cout<<"Please enter score for student "<<count+1<<" or -999 to end.\n";
        cin>>*(scorePTR+count);
        if(*(scorePTR+count) == -999)
        break;
    }
}

Ответы [ 3 ]

4 голосов
/ 09 февраля 2012

Вы почти на месте:

double readScores(double scoreArray[]) {
    double *scorePTR;
    *scorePTR = scoreArray;

    for(int count = 0; count < maxStudents; count++)
    {
        cout<<"Please enter score for student "<<count+1<<" or -999 to end.\n";
        cin>>*(scorePTR+count);
        if(*(scorePTR+count) == -999)
        break;
    }
}

Я также предлагаю переключиться на "прямой" синтаксис массива при обращении к массиву, а не полагаться на семантику "массив как указатель", то есть использовать scoreArray[count]чем *(scoreArray+count) в ваших выражениях:

double readScores(double scoreArray[]) {
    for(int count = 0; count < maxStudents; count++)
    {
        cout<<"Please enter score for student "<<count+1<<" or -999 to end.\n";
        cin >> scoreArray[count];
        if(scoreArray[count] == -999)
        break;
    }
}

PS: я предполагаю, что вы еще не начали изучать STL;существуют более подходящие решения с использованием стандартной библиотеки C ++.

4 голосов
/ 09 февраля 2012

Ошибка, которую вы получаете, состоит в том, что вы назвали локальную переменную так же, как аргумент функции.

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
4 голосов
/ 09 февраля 2012
double readScores(double scoreArray)
{
    double scoreArray[maxStudents];
    ...
}

Ошибка компиляции происходит из-за того, что вы объявили локальную переменную с именем scoreArray, которое совпадает с именем формального параметра double scoreArray.Измените имя одного из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...