2012-02-09 3 views
2

Я учусь о указателях в классе, но я никогда не понимал массивы 100%Как вернуть массив из функции?

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

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

У меня есть указатель пользователя вместо индекса для доступа к элементам в массиве. Приведенный ниже код дает мне ошибку «переопределение формального параметра" 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; 
    } 
} 
+0

Вы возвращаете указатель на массив из своей функции, но убедитесь, что вы ** не ** возвращаете указатель на * локальный * массив. –

+0

Прототип функции должен быть «void readScore (double * scoreArray)», и вы не должны переопределять scoreArray внутри функции. –

+0

@Als Должен ли быть «не» в этом комментарии? Возвращение локального массива никогда не бывает красивым. –

ответ

4

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

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
double readScores(double scoreArray) 
{ 
    double scoreArray[maxStudents]; 
    ... 
} 

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

4

Вы почти там:

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++.

+0

Я сделал это, но в параметре функции я получаю чтение squiggly под scoreArray. Он говорит «Ожидаемый а»), но я не уверен, почему .. – sircrisp

+0

@sircrisp Я исправил синтаксическую ошибку из предыдущего редактирования (я слишком долго программировал на C#/Java, поэтому поставил скобки в неправильном месте). – dasblinkenlight

+0

"Прямой синтаксис массива" очень вводит в заблуждение! 'double scoreArray []' - указатель! Это точно так же, как 'double * scoreArray'. Он полагается на семантику «массив-указатель». –

Смежные вопросы