Using pointers in Arduino (C/C++) to pass variables by reference
by adrianpark on November 1, 2010
I was writing some code for an Arduino sketch and bumped my head against the issue of how to pass a variable by reference. I’m blogging the solution for future reference (mine and others).
Firstly, what does it mean to ‘pass a variable by reference’ and, what are you doing if you’re not ‘passing a variable by reference’? Answering the last question first, if you’re not passing by reference, you’re passing by value. Passing by value is the most basic form of variable passing in C/C++ and it means that when you assign one variable to another, you’re actually creating a copy of that variable. e.g.
int a = 1; int b = a; b += 1; //now a == 1 and b == 2
Passing by reference is when you store a reference to one variable in another such that modifying the second variable modifies the value of the first. e.g.
int a = 1; int *b = &a; *b += 1; //now a == 2 (and b's value is a pointer to the location of a in memory)
This page does a better job of explaining it: http://home.netcom.com/~tjensen/ptr/ch1x.htm
So, why would you want to do this? One of the things I find this useful for is to avoid repeating code. For example, you might have a function that should do something with one variable in certain cases and do the same thing to another variable in other cases. Instead of having two sequences of code performing essentially the same operation on two different variables, we have one bit of code choosing which variable to operate on. In my example, I have a function that responds to clicks from two buttons: a ‘left’ button and a ‘right’ button. Then I had a variable associated with each button to store the button’s state. The function changes the state value of each the variables depending which button was clicked. Here’s some sample code:
boolean buttonLeftClicked = false;
boolean buttonRightClicked = false;
void clickHandler( String buttonID ) {
// create a pointer variable
boolean *targetStateVar;
// assign the address (lvalue) of the relevant state variable to the pointer variable
if( buttonID == "left") {
targetStateVar = &buttonLeftClicked;
} else {
targetStateVar = &buttonRightClicked;
}
// now perform some (hopefully more complex!) operation on the state variable
*targetStateVar = true;
}
This example is simple so it would be reasonable to question why the operation on the variable doesn’t just happen within the if…else statements. After all, that would actually reduce the amount of code here! But, if that operation consisted of 10 lines of code, that’s a lot of code duplication. If there’s a bug or a mistake in one section of duplicated code, you have to remember to change it in the other. I guarantee that you’ll forget, resulting in a very obscure bug which will take you hours to find!
good post adrian, if anyone (like me) wants to know more about pointers and what they are for, i found a nice tutorial here; http://www.functionx.com/cpp/Lesson13.htm
its c++ but the explanations are generic. anyone starting to code for arduino or processing, don’t panic you don’t have to understand this though as Adrian describes above – there a benefits.
Thanks Tom – good link.
One of the things I’m really enjoying about playing with the Arduino is that, as you say, you don’t need to know this stuff. You can do amazing things with little technical knowledge. But, if you want to geek out properly, you can
Adrian, you are HARD TO DA CORE.