permanently changing value of parameter

2019-03-03 15:21发布

问题:

I have a function check that takes a boolean as an argument, uses the value of the boolean and then changes it. I always pass this function a global variable, like:

check(4, some_global_boolean, 'a');

and I want the change to the variable to remain after "check" is called. Right now, the change is not going beyond this function call. How do I do this?

boolean check(int key, boolean prev_key_high, char c){

 if (key == LOW) {
    if ( prev_key_high){
      prev_key_high = false;
      Serial.println(c);
      return true;
}
  }

  else {
    prev_key_high = true;
    return false;
  }
}

回答1:

You should pass the pointer, but you'll have to change all usages to dereferenced pointer like this:

boolean check(int key, boolean *prev_key_high, char c){

    ...
    if (*prev_key_high)
    ...
    *prev_key_high = true;
    ...


回答2:

Additionally, if your variable is in global scope, you could just remove it from your argument list and access it directly, that way it would never appear in local scope. For example:

int globalInt;

void incGlobal() {
    globalInt++;
}

int main() {
    globalInt = 0;
    printf("%d\n", globalInt);
    incGlobal();
    printf("%d\n", globalInt);
    incGlobal();
    printf("%d\n", globalInt);
    incGlobal();
}

prints

0
1
2


回答3:

Thanks Simon. Here is the new code:

  check(key_a, &prev_key_a_high, 'a');

boolean check(int key, boolean *prev_key_high, char c){

 if (key == LOW) {
    if ( *prev_key_high){
      *prev_key_high = false;
      Serial.println(c);
      return true;
    }
  }

  else {
    *prev_key_high = true;
    return false;
  }



}


回答4:

The change in the global boolean value is not persisting because it is being passed by value. When an argument is passed by value to a function, the function creates a local copy of the variable and makes changes to the local copy. This local variable goes out of memory once the program is out of the scope of the function. Using pointers should solve the issue. Try the following..

boolean check(int key, boolean* prev_key_high, char c){
  if (key == LOW) {
    if ( *prev_key_high){
      *prev_key_high = false;
      Serial.println(c);
    return true;
    }
   }

    else {
      *prev_key_high = true;
      return false;
    }
  }

and when you call the function :

check(4, &some_global_boolean, 'a');


回答5:

First you need to learn how scope works in C, and how are variables passed to functions. Local Scope > Global Scope, for example, if you have a global variable named "variable", and a function with a variable also named "variable", you'll be working on the local copy of it.

Now, with that in mind, think of this, when you pass an argument to a function, you actually make a copy of the variable, with local scope. So in your function:

check(4, some_global_boolean, 'a');

When you defined the function you gave each argument a name right? so when you call a function, and you instantiate each argument into a variable(of the defined type) according to the function signature. Kinda this: argument1 = value1, argument2 = value 2,..., argumenn = valuen

Now, lets take this to your function: boolean check(int key, boolean prev_key_high, char c) => key = 4, prev_key_high = some_global_boolean, c = 'a'

Each of this variables has a local scope, and it has the same values as the arguments/variables/values you used in the call, but the variable is in a completely different position in memory.

Now, there are different ways to deal with this, personally I discourage people into using global variables:

1.Instantiate a variable in your main function (static or dynamic as you wish), and work with pointers to that specific variable:

    int main(int argc, char const *argv[])
    {
       boolean some_global_boolean = true; //or false or w/e or initialize it as you wish
       check(4, &some_global_boolean, 'a');
       return 0;
    }

    boolean check(int key, boolean * prev_key_high, char c){

    if (key == LOW) {
        if ( *prev_key_high){
          *prev_key_high = false;
          Serial.println(c);
          return true;
        }
    }

    else {
        *prev_key_high = true;
        return false;
      }
    }

2.If you insist in using a global variable, use it directly, or in combination with previous comment. I encourage you into learning about pointers and working with them.

boolean check(int key, char c){

    if (key == LOW) {
        if ( some_global_boolean){
            some_global_boolean = false;
            Serial.println(c);
            return true;
        }
    }

    else{
          some_global_boolean = true;
          return false;
        }
    }
}


回答6:

You need not pass global to you function as argument!. Rather access it directly. Passing global as an argument creates a local copy of the global variable, which stays within the function scope.



标签: c arduino