Memory Addresses & Pointers
Tags: c, beginners, pointers
Published: 2019-06-24 16:19:23

Welcome to Memory street! In Memory street, there are 2^64 plots. Each plot has an address, starting from 0 to 2^64 - 1 (yeah, that's a long street, especially because all the plots are on the same side of the road). In some plots, there is a house, in others not. Some houses are built on several plots and others are built on only one. For example, the Charles's house (we will call it __`ch`__ from now on) is built on only one plot, and there is only one person who lives in it. The address of this house is 100, Memory street.

If we translate this information to our language, we can say that the variable __`ch`__ contains 1 as its value, and its address is 100. Also, its size is one [__Byte__](https://en.m.wikipedia.org/wiki/Byte). A byte is the smallest unit of memory __that can be accessed__ (like one plot in our theoretical street) and it contains 8 bits. A bit is the smallest unit of memory, which can be only 0 or 1.

Let's look now on the Interno's house (`ih`__ from now on), which contains 4 people and is built on 4 plots: 200, 201, 202 and 203. What means that its address is 200. Right next to this house, there is the Floaters' house (`fh`__ from now on), which its address is 204 and is also built on 4 plots. The number of people that live in this house is 10.5.

![](https://thepracticaldev.s3.amazonaws.com/i/tj52t7f33lq4uvpv4erz.PNG)

What can we say about all the houses we mentioned above? We can say that the addresses of the houses are 100, 200, and 204, respectively. Moreover, we can say that their values are 1, 4, and 10.5, respectively. We already know how to represent the values in our code:
```cpp
char ch = '1';
int ih = 4;
float fh = 10.5;
```
But how do we represent the addresses?

Remember the '&' sign in the __`scanf`__ function? That's the answer. If you put this operator before a variable, you get its __address__ instead of its __value__. For example:
```cpp
char * chAddress = &ch; // 100 in our example
int * ihAddress = &ih; // 200 in our example
float * fh fhAddress = &fh; // 204 in our example
```
Pay attention, the '\*' here is __not the multiplication operator__ but it's how we declare a __pointer__. A __pointer__ is a variable in which we save __addresses__. That means that the __value__ of a __pointer__ is a __memory address__. A __pointer__ also has its own address, what means we can also points to it with another pointer. If we want to declare a pointer we write:
```cpp
<variable_type> * <pointer_name>;
```
For example:
```cpp
int * pointer; // can  point at an integer variable
```

If we want to get the __value__ of the variable the pointer points at, we can use again the asterisk ('\*') operator this way:
```cpp
#include <stdio.h>

int x = 10;
int * pointer = &x; // pointer now points at x
printf("The value of the variable which the pointer points at is: %d", *pointer); // we put '*' before a pointer in order to get the value of the variable/address it points at
```
In other words, if we want to declare a pointer we add a '\*' after the type, and if we want to get the value of the variable/address the pointer points at, we also add '\*' before the pointer name. It may be a little confusing, but you will get used to it soon.

"Why do we need pointers?" you probably ask. One answer is that we want to __pass the addresses of variables__ to functions, and __not their values__. In other words, we want to tell the function where it can find the original box and gets what it contains, to prevent it from the need to create a new box in which it will only copy the value of the original box. For example, as we mentioned above, the __`scanf`__ function:
```cpp
#include <stdio.h>

int x;
printf("Enter a number:\n");
scanf("%d", &x);
```
In the example above, the __`scanf`__ function gets the __address__ of __`x`__ and the reason is clear: the __`scanf`__ function doesn't need the value of __`x`__, (to be more accurate: the value of __`x`__ is "garbage" because we have never initialize it before), but it needs the __address__ of __`x`__ in order to know where to put the input from the user. The __`scanf`__ function gets an __address__ of a box and fills it with the input!

This passing variables method is called __by reference__ (instead of __by value__). 

Let's observe the next example:
```cpp
#include <stdio.h>

void swapByValue(int x, int y) {
    int temp = x;
    x = y;
    y = temp;
}

void swapByReference(int * x, int * y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}

int main() {
    // Initializes two variables
    int x = 5;
    int y = 3;
    printf("x=%d, y=%d\n", x, y);
    // Runs the first function and prints the values of x and y
    swapByValue(x, y);
    printf("x=%d, y=%d\n", x, y);
    // Runs the second function and prints the values of x and y
    swapByReference(&x, &y);
    printf("x=%d, y=%d\n", x, y);
    // Success
    return 0;
}
```
The output of the code in the example above is:
```cpp
x=5, y=3
x=5, y=3
x=3, y=5
```
Why? The first __`printf`__  output is trivial, it's just how we initialize our variables in __`main`__. The second output should also be trivial to the wise reader because actually the __`swapByValue`__ function __does nothing!__ This function creates two __new__ variables, __`x`__ and __`y`__ which are completely different from the __`main`__'s variables __`x`__ and __`y`__ ("other boxes"), but have the same values. What means that the swap happens, but on irrelevant variables that no longer exist at the end of the function (we will learn about __scopes__ in the future). The last output is the output we want. The variables really swapped their values in the right scope (the code block of __`main`__). That's because the __`swapByReference`__ function also creates two __new__ variables, but this time the values of the variables are not just a copy of the values of the __`main_'s`__ variables. The values of the new variables are the __addresses__ of the __`main`__'s variable, and therefore, the swap operation occurs on the __`main`__'s variables! (Just as was the intention).

That's all for this post. This is a lot for one time, I know. Make sure you fully understand what we said before you continue to the next post, which is about __Memory Allocation__ and __Dynamic Arrays__.

A nice challenge, which appears frequently in job interviews: can you write a swap function that doesn't initialize a new variable? (__`temp`__, in our case.)

####__Always remember, it's much C-mpler than you thought!__

Regards,
Gilad