The easy way to do this is with exactly your code but pass the number by reference, i.e. use:
void increase(int &myIndex)
The "&" effectively means that the original will be operated on rather than a copy that only exists in the scope of the function.
References are a less powerful but far easier to use derivative of pointers, Google should find more about them if you want to know.
Here is another way to do this which is handy if you have more than one function to access the data because it keeps the access functions encapsulated with the data.
// example sketch that uses a class with access functions to minipulate instance data
class myClass {
private:
public:
int index;
void increase(){
this->index++;
}
void decrease(){
this->index--;
}
};
// create two instances for example
myClass data1;
myClass data2;
void setup(){
Serial.begin(9600);
data1.increase(); // minipulate instance 1
}
void loop()
{
data2.increase(); // instance 2
Serial.println(data2.index);
delay(100);
}
Making it public exposes index so that the Serial.print statement works. If you don't want to expose the value then you would need an access function to get at it.
Two things with that C++ snippet. You are using index without initialization, and making index public defeats the purpose of having the increase() and decrease() functions. You can just data1.index++; instead of data1.increase(); (you don't want variables in your class to be exposed as public, you always want functions to change them and retrive their context, stuff like getIndex() and setIndex() ).
But that's beyond the scope of this post, as for the comments on passing a pointer to either the struct in question or a member of the struct, it matters not. The size of the argument is the same (size_t, which is 2 bytes long anyway). The difference would be in the implementation.
You can avoid having to type struct myStruct blah as an argument by using typedef:
The compiler does set index to zero (as you can confirm if you run the posted code and look at the Serial print output). Of course, one can set index to any value in the constructor if desired or in setup.
making index public defeats the purpose of having the increase() and decrease() functions. You can just data1.index++; instead of data1.increase();
Not true, having increase and decrease methods allows things like range limiting to be built into the methods.
(you don't want variables in your class to be exposed as public, you always want functions to change them and retrive their context, stuff like getIndex() and setIndex() ).
Although there are cases where only exposing properties through access methods is desirable, this is not always the case. For tinkering around in Arduino sketches there is usually no benefit in writing additional access methods if all you want to do is read the value of the property.
You can avoid having to type struct myStruct blah as an argument by using typedef:
The code you posted does not compile (with Arduino 0017)
It is also good practice not to expose your stuff like that, that same limiting behaviour can be implemented having index public, just somewhere else in the code. I am no C++ expert, I do my work in C (did not know C++ initialized variables to 0). Which brings me to my next point. The code I posted will not compile with any version of the Arduino IDE, as it is not meant to do so. It is C99 code and must be compiled and linked manually with avr-gcc or something alike. You can rewrite it by removing the contents of the main() function and putting it in the proper places the Arduino IDE expects, these being setup() and loop().
When declaring a regular local variable, its value is by default undetermined.
In other words, you are lucky it initializes to 0. That behaviour is not bound to happen all the time. When the variable is created, a portion of memory is allocated to it. Whenever you decide to read the variable, that portion of memory will be read. If you did not initialize the variable, whatever was in that portion of memory will be returned instead. In other words: never leave variables uninitialized, especially if your next operation will be adding or subtracting stuff from it.
Many (most) readers of the Arduino forum are not C++ programmers and are mostly interested in getting their sketch to compile in the Arduino IDE. Posting code here that does not compile in the arduino IDE is probably not that helpful.
? you are lucky it initializes to 0. That behaviour is not bound to happen all the time
Its not luck, it's the way the compiler the arduino is documented to work (see Frequently Asked Questions)
In the code posted, the classes are created statically (the arduino compiler does not support the new keyword). This means that data associated with the class, i.e. the index variable, will be placed in the .bss segment. The .bss segment is where the compiler places global and static data and this is documented to be initialized to zero (unless explicitly initialized to something else).
It seems however that local and non-static variables will not be treated as such though. Your class is indeed global, so it will be treated as such. It's still a good practice to initialize your stuff, however.
BTW, I am no C++ programmer myself, I do my work in C, which is why you see me doing stuff like that snippet of code I posted. I find the Arduino IDE too buggy to work with, so I use Eclipse as a front-end to avr-gcc. It is easier for me to do things that way. Since most (read: all) of my code is written directly in C, my snippets are usually like that. My apologies for that.
// this should compile in the ide, of course
// it will do absolutely nothing but add 1 to myStruct.index and overflow
typedef struct {
int index;
} datastruct;
void doStuff(datastruct *s);
datastruct myStruct;
void setup(){
myStruct.index = 1;
}
void loop(){
doStuff(&myStruct);
}
void doStuff(datastruct *s){
s->index++;
}
Then again, at that point myStruct is global, so unless you are working with many variables of type datastruct, the doStuff function could use a more direct implementation.