2

I'm learning about pointers in class but I never really understood arrays 100%

I have a assignment where I have to read in an array of student scores from a function. Each element of the array would hold a different score and the element identifies what student it is.

I'm trying to read the scores into a array but when it comes to returning it I'm lost. I've tried google but just get more confused because people talking about dynamic memory and using the new and delete operand which I haven't gotten to yet, and I don't want to do the assignment wrong.

I have to user pointer instead of index to access elements in the array. The code below gives me the error "redefinition of formal parameter '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;
    }
}
7
  • You return a pointer to the array from your function but make sure you are not returning pointer to a local array. Commented Feb 9, 2012 at 15:26
  • the function prototype should be "void readScore(double* scoreArray)", and you should not redeclare scoreArray inside the function. Commented Feb 9, 2012 at 15:28
  • @Als Was there supposed to be a "not" in that comment? Returning a local array is never pretty. Commented Feb 9, 2012 at 15:29
  • @AlanStokes: oops I wanted to add a bold not and actually forgot to add it by the time i finished the comment, lulz, thanks for pointing that out, corrected it. Commented Feb 9, 2012 at 15:30
  • @Zyx2000 when I removed scoreArray from inside the function the pointer says it is unidentified? Commented Feb 9, 2012 at 15:34

3 Answers 3

4

The error you get is because you named a local variable the same as the function's argument.

double readScores(double scoreArray /* parameter named scoreArray */)
{
    double scoreArray[maxStudents]; // this cannot have the same name!

The code you've shown reveals a lot of confusion. I'll try to explain the mistakes in it.

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

This will not output the elements 1 and 2. To do that, it should be cout << scoreArray[1] << scoreArray[2];. Also, note that arrays in C++ are 0-based, so the first element will be scoreArray[0], the second scoreArray[1], the third scoreArray[2], and so on.

The code declares a function named readScores taking a pointer to double and returning a double:

double readScores(double[]);

But it only defines a function taking a double:

double readScores(double scoreArray)

I'm sure that's not what was intended, and once the compiler error is fixed, it will produce a linker error because there's no definition for the double readScores(double[]) function.

Now, the arrays.

When you write a parameter as double x[], it's not an array. It's a pointer to a double. It's exactly the same as double* x. Yes, the syntax is highly misleading. That's why you shouldn't use it. It sows confusion. It's better to be explicit and call a pointer a pointer.

You cannot directly return arrays in C++ and you cannot directly pass array arguments in C++. You can pass references to arrays and return references to arrays, but here it seems you have instructions to use pointers, so I won't go there.

The code doesn't seem to be making use of the value returned from readScores, so it's probably better to just use a void return type. The code writes the values directly into the array anyway.

void readScores(double* scorePtr)

The syntax *(scorePTR+count) is exactly the same as scorePTR[count], so there's no gain in using it. And the code is iterating with an index (count) anyway.

I suppose what the assignment meant with that restriction was something actually useful, even if only marginally: iterate using a pointer, not an index. In order to do that, you need to find three things: how to start the loop, how to move to the next element and how to end the loop.

How to start the loop? You should start with a pointer to the first element. Luckily, such a pointer is exactly what gets passed as an argument to the function.

for(double* ptr = scorePtr; /* ... */; /* ... */) 

How to move to the next element? If you increment the pointer, it moves to the next element.

for(double* ptr = scorePtr; /* ... */; ++ptr)

How to end the loop? The loop ends when the pointer has passed over the entire array. The array has maxStudents elements, so the loop ends when the pointer is maxStudents elements away from the start:

double* end = scorePtr + maxStudents;
for(double* ptr = scorePtr; ptr != end; ++ptr)

And how do you use this pointer in the loop? As normal, with the dereferencing operator.

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
Sign up to request clarification or add additional context in comments.

Comments

4
double readScores(double scoreArray)
{
    double scoreArray[maxStudents];
    ...
}

The compile error happens because you declared a local variable with the name scoreArray, which is the same name as that of the formal parameter double scoreArray. Change the name of one of them.

Comments

4

You're almost there:

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;
    }
}

I also suggest switching to "straight" array syntax when accessing the array, rather than relying on array-as-pointer semantic, i.e. use scoreArray[count] rather than *(scoreArray+count) in your expressions:

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;
    }
}

P.S.: I assume that you have not started learning about STL; more appropriate solutions exist with the use of standard C++ library.

4 Comments

I did this but I am getting a read squiggly under scoreArray in the function parameter. It says "Expected a ')'" but I'm not sure why..
@sircrisp I fixed a syntax error from the previous edit (I've been programming in C#/Java for too long, so I put brackets in the wrong place).
"straight array syntax" is very misleading! double scoreArray[] is a pointer! It's exactly the same as double* scoreArray. It relies on the same "array-as-pointer" semantic.
@R.MartinhoFernandes I see how the original version of my answer could be misleading: I was talking about the scoreArray[count] vs. *(scorePTR+count) syntax, not the double scoreArray[] vs. double *scoreArray syntax. The later two are absolutely identical. I edited the answer to add a clarification. Thanks!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.