# Need some explanation with Pointers

I started programming on my own snake game for the arduboy and came across something very interesting I can’t explain to myself (I just discovered it and never thought it would work).

In the Headerfile of a class there is an Arduboy pointer (looks like this: Arduboy *arduboy; )
and a method requiring a pointer (looks like this: void method(Arduboy *ard) )

Now the method looks like this:

void method(Arduboy *ard) {
arduboy = ard;
}

Why and how does this work? Can someone explain this to me please.

Can you point to the actual code you’re asking about? The code you’re showing is just modifying a global variable that points to an Arduboy class. The place where it’s used is likely to be more interesting.

I see what you did there!

By default, when you call a function in C++ the values are copies rather than the original values.

Take this code:

``````void AddThree(uint8_t x) {
x = x + 3;
}

uint8_t x = 3;
Serial.print("Before:"); Serial.println(x);
Serial.print("After:"); Serial.println(x);
``````

Will produce the result:

``````Before: 3
After: 3
``````

Why? Because the function is working on a copy of the variable rather than the one passed. Once the arithmetic is complete and the function returns, the copy is discarded.

Change the code to :

``````void AddThree(uint8_t *x) {
*x = *x + 3;
}

uint8_t x = 3;
Serial.print("Before:"); Serial.println(x);
Serial.print("After:"); Serial.println(x);
``````

Will produce the result:

``````Before: 3
After: 6
``````

What’s happening?

The `AddThree` function now uses a pointer to the original value and is operating on the original value. The pointer is simply a reference to the memory address of the original value. When we call the function, we use the `&` operator to say pass the memory address of this variable rather than the actual value.

This is a terrible way of doing this though. It would be possible to pass a pointer to anything to the function and the function would try to add 3 to it. Imagine if you called it like this:

``````AddThree(arduboy);
``````

You would need to add additional code to check that your pointer actually points to a `uint8_t` before blindly adding the value.

A better approach is to pass by reference. Its easier, cleaner and more readable.

``````void AddThree(uint8_t &x) {
x = x + 3;
}

uint8_t x = 3;
Serial.print("Before:"); Serial.println(x);
Serial.print("After:"); Serial.println(x);
``````

Will produce the result:

``````Before: 3
After: 6
``````

In this example, the function receives a reference to the variable by default. Any changes you make to it will be made on the passed variable, not a copy.

2 Likes

Just to add a bit of clarification…

Technically you’d have to do `AddThree(reinterpret_cast<uint8_t *>(arduboy))` (or worse, `AddThree((uint8_t *)arduboy)`) to get that to work.
(Fortunately we don’t live in a world where all pointers are implicitly convertible to `uint8_t *`.)

If you don’t add a cast the compiler will detect the type mismatch and stop you, which is why a strong type system is a good thing.
(In a dynamically typed language you wouldn’t discover the mistake until you ran the program.)

The bigger issue is null pointers, you could easily write `AddThree(nullptr)` and the compiler wouldn’t complain.
(I’m not sure if integer literals are implicitly convertible to pointers. I’d hope not.)