1

I'm learning C++ from a course on Udacity.

Can you explain to me why setGrades() was defined as a pass-by-pointer-to-value function? Why is there an error with passing by value? In the code below, I omitted the definition for printGrades() and setID().

#include<iostream>
using namespace std;

const int SIZE = 5;
template <class T>
class StudentRecord
{
    private:
        const int size = SIZE;
        T grades[SIZE];
        int studentId;
    public:
        StudentRecord(T defaultInput);
        void setGrades(T* input);
        void setId(int idIn);
        void printGrades();
};

template<class T>
StudentRecord<T>::StudentRecord(T defaultInput)
{
    for(int i=0; i<SIZE; ++i)
        grades[i] = defaultInput;
}

template<class T>
void StudentRecord<T>::setGrades(T* input)
{
    for(int i=0; i<SIZE;++i)
    {
        grades[i] = input[i];
    }
}

int main()
{
    StudentRecord<int> srInt(-1);
    srInt.setId(111111);
    int arrayInt[SIZE]={4,3,2,1,4};
    srInt.setGrades(arrayInt);
    srInt.printGrades();
    return 0;
}

The output is supposed to be:

ID# 111111: 4
 3
 2
 1
 4
Melebius
  • 6,183
  • 4
  • 39
  • 52
user1569341
  • 333
  • 1
  • 6
  • 17
  • 4
    I'd call it pass by value (and that's usually what it's called). I've never heard of pass by pointer before. – dsp_user Jan 03 '18 at 06:54
  • Here you go https://stackoverflow.com/questions/18698317/c-pointers-as-function-arguments – user1569341 Jan 03 '18 at 07:01
  • 1
    If this code is from the course itself, I suggest you start looking for alternatives. – StoryTeller - Unslander Monica Jan 03 '18 at 07:02
  • Is it really terrible? I had a feeling that this course is not very good. Very hard to follow for beginners. – user1569341 Jan 03 '18 at 07:04
  • This might help to clarify _pass by value_ vs. _pass by reference_: [SO: What's the difference between passing by reference vs. passing by value?](https://stackoverflow.com/a/430958/7478597). In C (where C++ was developed from), there was only pass by value. Pass by reference could be emulated by using pointers (which were passed by value). In C++, references were added. E.g. `f(int *p)` ... pointer passed by value vs. `f(int *&p)` ... pointer passed by reference. The former allows to change the pointed contents in `f()` vs. the latter allows to change the pointer itself also. – Scheff's Cat Jan 03 '18 at 07:04
  • The method setGrades expects a pointer to `T` (in your case a pointer to `int`). You pass him an array of `T`s (`int`s). A pointer is just a memory address so all you have to do is to pass him the adress of the first element of your array (`srInt.setGrades(&arrayInt);` should do the job). – TobiSH Jan 03 '18 at 07:07
  • 5
    It isn't a good course. Here's issues that pop up to me at a glance: (1) It's getting you comfy with `using namespace std;` something you [shouldn't get comfy with](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice). (2) It favors pointers to access raw arrays, and foregoes many other abstractions in the language that would allow the compiler to do static checking on array sizes. (3) It doesn't know the difference between a static and a non-static `const` member. `size` is unused, *and* still takes up space in each object. – StoryTeller - Unslander Monica Jan 03 '18 at 07:07
  • Yes, but it's still *pass by value*. The fact that you have a pointer as an argument doesn't change that. Informally, you can say whatever you like (even pass by pointer to value). *C++* also supports *pass by reference* (T& ) where an original address is passed as an argument. – dsp_user Jan 03 '18 at 07:08
  • @dsp_user - The original address is not passed as an argument - a reference is. – Ed Heal Jan 03 '18 at 07:51
  • @Ed Heal, Ok, thanks (of course, compilers can still implement this any way they see fit) – dsp_user Jan 03 '18 at 08:00

3 Answers3

1

C++ does not allow passing builtin C-style arrays by value. One can pass an array by reference or pass a pointer to the first element of the array. Given such pointer, the entire array can be accessed.

Passing-by-pointer is not a usual term in the literature but people keep coining similar terms time and again, which shows some kind of genuine need. The idea behind the term is as follows: one passes a pointer by value but the goal is to let the function access the pointed-to object as an lvalue (which is normally achieved by passing that object by reference).

Melebius
  • 6,183
  • 4
  • 39
  • 52
n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
0

That's simply because it is an array you want to give to setGrades because you want to set all SIZE values of the array 'grades'.

As you know perhaps, the name of an array can be used like a pointer to the first value of that array. For example you could write *arrayInt as a term which is equivalent to arrayInt[0].

So when you pass an pointer to the first element of the array to setGrades, the function can get the other elements of that array with arrayName[i] where i is in between 0 and SIZE.

Gmork
  • 171
  • 1
  • 8
0

You want to pass an array to setGrades, you can also define it like this:

void StudentRecord<T>::setGrades(T input[])

However the compiler will convert it to a T* pointer automatically.

Functions will always make its own copy of all parameters you gave during compilation (see: call by value). Right here it's an array, but the compiler can't assign an array to another immediately. The only way to do array assignment is to assign its element one by one (or copy the entire memory chunk of the array), and compiler won't do that. The compiler do know that you can access the entire array if you got a pointer of type T pointed to the first element of the array. It's the alternative way of passing the entire array.

And that is the most common way to pass an array to a function.

walter
  • 1,199
  • 7
  • 13