-6

I'm reteaching myself C++ and as I'm reading about pointers a question has came into mind.

When declaring function signatures in C++, the address-of and dereference operators are used, such as the below.

int someFunction(std::vector<int>& nums) {
     //do stuff 
}

In this context the & is being used to declare that the address of the nums variable is being used rather than the value.

If this signature is changed to the below, the value is being used instead.

int someFunction(std::vector<int>* nums) {
     //do stuff 
}

However if the below is now used, I assume the value of the nums variable is still being used despite the lack of operator.

int someFunction(std::vector<int> nums) {
     //do stuff 
}

If this is true, since the lack of an operator and the * operator both result in the same thing, why is there any need for the * operator at all? Is it simply for brevity?

Jake12342134
  • 1,539
  • 1
  • 18
  • 45
  • 1
    those are neither dereference nor address-of operators. Both `*` and `&` can have different meanings – 463035818_is_not_an_ai Jan 06 '20 at 12:16
  • 1
    You need to research C++ parameter passing by-value, by-reference and by-pointer. Your question is describing passing by value. – acraig5075 Jan 06 '20 at 12:18
  • 1
    First one declares a reference argument; second one a pointer and third one by value. Reasons to use reference might be performance or the ability to modify the argument. This is a fundamental aspect of C++. The topic question was if arguments always require the * or & and your own observation already proved that this is not the case. – gast128 Jan 06 '20 at 12:19
  • You need [a book](https://stackoverflow.com/q/388242/560648). – Lightness Races in Orbit Jan 06 '20 at 12:52

2 Answers2

2

Those * and & in your code are neither dereference nor address-of operators. Both, * and & can have different meanings. Here they are part of the type:

int x;      // declares an int
int* p;     // declares a pointer to int
int& r = x; // declares a reference to int

The address-of and dereference operators come into play for example when you assign something to the above variables:

p = &x; // here & is address-of operator
x = *p; // here * is dereference operator
int someFunction(std::vector<int>& nums) {
     //do stuff 
}

In this context the & is being used to declare that the address of the nums variable is being used rather than the value.

No. Here the & means that nums is passed as reference.

If this signature is changed to the below, the value is being used instead.

int someFunction(std::vector<int>* nums) {
     //do stuff 
}

No. Here nums is passed as pointer.

Only this is pass-by-value:

int someFunction(std::vector<int> nums) {
     //do stuff 
}
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
1

You are confusing things. In C++ arguments passed to a function are copied into the function. This is called "passing arguments by value", which is Ok for small types such as primitive types (int, double, etc), but it might be very costly for large objects. Imagine if your std::vector has 10 million elements.

In the first case with int someFunction(std::vector<int>& nums) the & indicates to the compiler that you want to pass the argment nums by reference, instead of the default by value. That means that the vector will not be copied into the function and a reference will be used instead (the cost here is like copying a single pointer). Note that since you are using a reference, if you modify nums inside your function the change will be visible outside the function (the variable passed as argument to the function will be changed). This is sometimes what you want and sometimes it is not. If you want to avoid the copy but don't want to change the vector, use int someFunction(const std::vector<int>& nums) instead.

In the second case you are actually passing just a pointer to the function and not a std::vector<int>, although the pointer points to an std::vector<int>. Similarly to the previous case, only a pointer is copied no matter how many elements the vector has and any change you made the the pointed vector will be visible outside the function. Note, however, that pointers can be null, while references cannot. That means that you would need to check if the pointer is null.

The third case is the default "passing by value" and a vector is copied into the function. Any change you make in the vector will not be visible outside the function, since you only changed the copy. But the cost can be high if the vector as many elements.

darcamo
  • 3,294
  • 1
  • 16
  • 27
  • _"That means that you would need to check if the pointer is null."_ Or make it a precondition of `someFunction` that the pointer is not null. – Lightness Races in Orbit Jan 06 '20 at 12:51
  • @darcamo Okay, this is crystal clear now. So does this mean that the &nums variable is actually a pointer that is created solely for use inside the someFunction? Does this mean that the &nums variable is subject to pointer arithmetic? – Jake12342134 Jan 06 '20 at 13:26
  • @LightnessRacesBY-SA3.0 How do I make it a precondition? – Jake12342134 Jan 06 '20 at 13:26
  • When `&` is used as `address-of` then yes, you get the address of the variable as a pointer. Thus, pointer arithmetic can be used with it. – darcamo Jan 06 '20 at 13:28
  • @Jake12342134 Put a comment next to it saying "pointer must not be null" :) – Lightness Races in Orbit Jan 06 '20 at 13:49
  • @Jake12342134 The variable is `nums`. It has type `std::vector&`, a reference type. There is no pointer or pointer arithmetic. The name `nums` is a name that refers to the vector that was declared somewhere in the calling scope. It's like an alias. Simple as! – Lightness Races in Orbit Jan 06 '20 at 13:50
  • @Jake12342134 It can be confusing because `&` means "similar" things in different places, but in a declaration (as opposed to an expression) it is _not_ "address-of". – Lightness Races in Orbit Jan 06 '20 at 13:51