Update variable passed as parameter to a function

I am trying to write a function where the parameter is a variable that gets updated in the function itself. I believe I need to use pointers, but I've read up on them and it is confusing.

Here is an example:

const byte pinA = 3;
const byte pinB = 4;
boolean stateA = digitalRead(pinA);
boolean stateB = digitalRead(pinB);

void pinCheck(byte pin, boolean state) {
    current_state = digitalRead(pin);
    if(current_state != state){
        // HERE I WANT TO UPDATE THE 'PIN' VARIABLE
    }
}

How can I do this?

How can I do this?

Use reference variables.

void pinCheck(byte &pin, boolean &state) {

Oh. That was easy.

So would I refer to variables within the function as 'state' or '&state'?

When I call the function, would it be:

checkpin(&pinA, &stateA);

Why don't you see what the compiler or a programming reference book says?

A variable has two important properties: 1) where it is stored in memory, which is its lvalue, and 2) the value that is actually stored there, its rvalue. In the following code fragment:

int x= 10;
int y;

y = x;

The compiler assigns memory addresses (i.e., lvalues) to variables x and y where they will "live" in memory while in scope. For variable x, it also assigns the value 10 (.e., x's rvalue) and places that (binary) representation at x's lvalue. The last statement assigns x into y. Note: most assignments like this are rvalue-to-rvalue data movements.

As Paul pointed out, sticking the address-of operator (&) in front of the variable in the function call tells the compiler: "Don't send pinA's rvalue to the function; send its lvalue instead." Now, because your function now knows where pinA lives in memory, it can change its value via the process called indirection.

Inside your function, you won't use a normal rvalue-to-rvalue assignment. For example, if you want to change pinA from 10 to 20, you would have something like:

   // some code, perhaps in loop()
   pinA = 10;
   state = false;
   pinCheck(&pinA, &state);    // Call your function, but send lvalues, not rvalues
   // more code in loop();
}   //end of loop()


void pinCheck(byte &pin, boolean &st) {
   *pin = 20;
   *st = true;
}

In your function, because of the asterisk in front of pin and st, the compiler knows to use the process of indirection during the assignment rather than an rvalue-to-rvalue assignment. As a result, the code in your function first goes to the memory address (lvalue) that was sent to the function as stored in pin because of the address-of operator (&) in the call in loop(), and places (binary) 20 (the new rvalue) at that memory location (the lvalue for pinA in loop()). Using the same indirection process, it goes to the memory address held in st (the lvalue of state back in loop()) and changes its rvalue to true. Because the original memory addresses for the variables are from loop(), the rvalues for the two variables are permanently changed in loop() via indirection.

Read the above about 50 times and it will make sense.

1 Like
void pinCheck(byte &pin, boolean &st) {
   *pin = 20;
   *st = true;
}

What's with the pointer operations on references?
That's just making stuff harder to understand.
References are really, really simple, it's just that the IDE makes prototypes a little harder.

The line for the function should be:

void pinCheck(byte *pin, boolean *st) {

I cut-and-paste from your post...opps...

@econjack Thanks so much for that!

I've always avoided using pointers bc they seemed so complicated in the tutorials. Now that I have an actual use for it, it seems much clearer.

I think I'll only have to reread your post 35 times. Thanks a bunch!

@delta_g would that way update the variable outside of the function as well?

econjack:
The line for the function should be:

void pinCheck(byte *pin, boolean *st) {

I cut-and-paste from your post...opps...

Why on earth would you advocate using pointers when the language supports references? References are far easier to understand, and FAR less error-prone, especially for newbies. Pointers only exist in c++ because of its c legacy, and it makes no sense to use pointers where references can do the same job (which is almost always....).

Regards,
Ray L.

Why on earth would you advocate using pointers when the language supports references?

Mainly because so much literature talks about pointers. True, they are a C legacy, but the concepts of indirection still apply regardless of the syntax used. If nothing else, the OP might be able to use some of that legacy code in his own work once he understands how pointers work.

PaulS' solution in reply #1 is by far the simplest.