A pointer points to a memory address.
These gives you two different levers to manipulate pointers:
- The pointer itself
- The object the pointer is pointing to.
Three things to take away:
ptrrefers to the pointer variable itself.ptrrefers to the object at the address stored in the pointer.- Assigning to
ptrchanges where the pointer points; assigning toptrchanges the object being pointed at.
Operation 1: Change the address of the pointer
Assigning a new address to a pointer changes what object it points to.
#include <iostream>
int main(){
int indoorTemperature { 22 };
int outdoorTemperature { 31 };
int* activeReading { &indoorTemperature };
std::cout << "Current reading: " << *activeReading << '\\n';
activeReading = &outdoorTemperature;
std::cout << "Current reading: " << *activeReading << '\\n';
}
// Output:
Current reading: 22
Current reading: 31
This line changes the pointer:
activeReading = &outdoorTemperature;
It does not modify indoorTemperature.
It simply makes activeReading store a different address. After that assignment, dereferencing the pointer gives access to outdoorTemperature.
Operation 2: change the value being pointed at
Assigning through a dereferenced pointer modifies the object at the stored address.
#include <iostream>
int main(){
int motorSpeedRpm { 1800 };
int* selectedMotorSpeed { &motorSpeedRpm };
std::cout << "Before update: " << motorSpeedRpm << " rpm\\n";
*selectedMotorSpeed = 2200;
std::cout << "After update: " << motorSpeedRpm << " rpm\\n";
}
// Output:
Before update: 1800 rpm
After update: 2200 rpm
This line does not change the pointer:
*selectedMotorSpeed = 2200;
The pointer still points to motorSpeedRpm.
What changes is the object being pointed at. Since selectedMotorSpeed points to motorSpeedRpm, assigning through *selectedMotorSpeed changes motorSpeedRpm.
The same pointer can do both
A pointer can be reseated and then used to modify the new target.
#include <iostream>
int main(){
int channelAOffset { 3 };
int channelBOffset { -2 };
int* activeOffset { &channelAOffset };
*activeOffset = 5;
activeOffset = &channelBOffset;
*activeOffset = 0;
std::cout << "Channel A offset: " << channelAOffset << '\\n';
std::cout << "Channel B offset: " << channelBOffset << '\\n';
return 0;
}
// Output:
// Channel A offset: 5
// Channel B offset: 0
This line modifies the first object:
*activeOffset = 5;
At that point, activeOffset points to channelAOffset.
This line changes where the pointer points:
activeOffset = &channelBOffset;
After that, this line modifies the second object:
*activeOffset = 0;
A const caveat
This Nibble assumes an ordinary pointer:
int* ptr;
Const changes what can be modified.
For example:
const int* ptr;
means the object cannot be modified through the pointer.
int* const ptr { &value };
means the pointer cannot be reseated.
Those forms are important, but the base model stays the same: ptr is the pointer, and *ptr is the object being pointed at.
Takeaway
Pointers can be manipulated in two different ways.
- By changing the address the pointer is pointing to
- Dereference the pointer and changing the value at the address