I am working on an embedded system that has different output capabilities (digital out, serial, analog, etc). I am trying to figure out a clean way to pass many of the variables that will control those functions.
I don't need to pass ALL of them too often, but I was hoping to have a function that would read the input data (in this case from a TCP network), and then parse the data (IE, the 3rd byte contains the states of 8 of the digital outputs (according to which bit in that byte is high or low)), and put that into a variable where I can then use elsewhere in the program.
I wanted that function to be separate from the main() function, but to do so would require passing pointers to some 20 or so variables that it would be writing to. I know I could make the variables global, but I am trying to make it easier to debug by making it obvious when a function is allowed to edit that variable, by passing it to the function.
My best idea was a struct, and just pass a pointer to it, but wasn't sure if there was a more efficient way, especially since there is only really 1 function that would need to access all of them at once, while most others only require parts of the information that will be stored in this bunch of state variables.
So anyway, is there a clean way to send many variables between functions at once that need to be edited?
Using a struct with a pointer to it is really a good bet. The code may be a little longer to write, but it will look nice. You can pass a struct by value, but pass by reference will avoid copying the data.
Another alternative is to create a struct composed of structs. Then you can be more selective in what data you pass to each function by passing the whole thing, just one or two of them, or an individual element of a struct.
typedef struct a {
struct b {
int b1;
int b2;
} b_s;
struct c {
int c1;
int c2;
} c_s;
} a_s;
This is a classic use of a "parameter block" -- just a pointer to a well-known struct.
The upsides include: Efficient, since any access to a given paramter is an adderess plus an offset; Ease of debugging (you can see all the parameters in one 'print'); Locality (caches nicely); Easy to turn into a stackable set of calls, where you don't easily know what parameters any given function down the stack might need.
The downsides include: You cannot tell by looking at a function call which parameters are important to the callee -- you have to know, or go digging in the source of that function; It's easier to cause side effects, especially of you allow the called functions to modify the block (bad, bad, bad!); Increases coupling (every function can see every parameter, which can lead to temptations...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With