[[Programming#Section 2 Intermediate|Learn Programming Section 2]] previous: [[Structs - Classes]]
---
## Pointers
Each byte in our system's memory has it's own address.
Pointers are a type of variable that store that address. Typically we use this to store the address of another variable.
```cpp
type* pointerName; //basic pointer declaration
int* intPtr;
float* floatPtr; //pointer to a float variable
// You can also have pointers to other pointers.
int** intPtrPtr; //pointer to a pointer an int variable, also known as a double pointer
```
The variables in the above example have not been initialized so we should never use them as is.
> [!Warning] Uninitialized Pointers
>Just like all other variables uninitialized pointers will most likely be zero but can have any possible value.
> Pointing to a random place in memory can be dangerous as we don't know what it will do.
When we declare a variable it is given a place in memory. We can look at the variables address using the address operator '&'
```cpp
int potatoes = 5;
int* foodPtr = &potatoes;
```
You can dereference the pointer to access the variable it points to.
```cpp
printf(*foodPtr);; // outputs the '5' stored in potatoes
```
Being a variable you can change what address is stored and thus what it 'points' to.
```cpp
int cabbages = 7;
foodPtr = &cabbages; //now our foodPtr points to cabbages instead of potatoes.
```
## References
In some ways references are similar to pointers. They both are a variables that give access to another variable.
The key difference is
- Pointers store the memory address
- References are an alias for the other variable.
You can also think of references as a pointer but once it is declared you cannot change what it points to.
References after declaration can be used just like the original variable without any extra steps.
```cpp
float pi = 3.14159;
int& piRef = pi; //refrences must be initialized at declaration!
std::cout << piRef; //outputs 3.14159
//this would at best give an error
int& piRef;
piRef = a;
```
## Passing Variables to Functions
When passing arguments to a function copies are made of each argument.
- This can be very inefficient if you are passing arrays or other large data structures.
- Changes to the copies do not propagate to the originals.
One way around this is to pass a pointer or reference to the variable instead of the variable itself.
```cpp
class Car{/* .... */ };
//without pointers a lot of extra time would be spent constructing and deconstructing our car class along with whatever data it contains.
Car TuneUp(Car aCar) { /* */}
void main()
{
Car myCar;
myCar = TuneUp(MyCar);
}
```
```cpp
//a better way would be to pass a refrence or pointer
void TuneUp(Car& aCar) { /* */} //using refrences
void TuneUp(Car *aCar) { /* */} //using pointers
```
---
next: [[Variables Casting and Conversion]]