On Sun, Apr 06, 2014 at 02:55:22PM -0400, Josh Koffman wrote: > [declare a variable across two source files...] > Do I do it in the main loop, or as a global? I know that technically I > could craft all my functions to take every single variable as an > argument, but that seems a bit unwieldy.=20 There are aggregate abstractions for handling groups of variables that are related. Arrays are used if all the variables are of the same type. Structures are available if the types vary or if you need specific names for each of the variables inside the aggregate. So say you have 8 items you need to track and pass between main and a function. Instead of declaring 8 separate variables, you can put all 8 into a single structure and then pass that between the two. There are some issues to resolve if you want both sides to have the ability to manipulate a shared set of variables in a structure. The key to understanding this is the critial inviolate rule of C parameters: "All parameters is C are a copy, without exception."* (for experts read bel= ow) So if you have a variable that you pass to a function, and you change it in the function, the original is untouched. This is true for all scalar variables and structures. * C Arrays seem to violate this rule. It actually holds. The trick is that the name of a C array is defined to be a pointer to the first element and that the array operators work with pointers just as well as array names. So while there is a functional violation of the rule, in actuality a copy of the pointer is passed on function calls. I generally exploit this definition by always declaring a type for a structure that's a single element array. So the name of the struct is in fact a pointer to it. i.e. typedef struct mine_s { int one, two, three; char c1,c2; long counter } *mine_p, mine_t[1]; So I can then declare a struct using mine_t: mine_t mine1; I can reference using the -> arrow operator: mine1->c1 =3D 'Z'; and I can pass just using the name: change_mine(mine1); with change_mine defined as: void change_mine(mine_p my_struct) { my_struct->counter++; // Actually updates the counter in the struct. } It's a cheap and very effective abstractive trick to get around the inviolate rule. >Generally I keep a few > registers that I will set bits in for flags on how the program is > running, or what state it's in. I don't think I've fully grasped what > it means to declare something volatile, static, or just regular > global. global: visible through the entire program. Lives for the entire life of ex= ecution local/automatic: allocated on stack. visible in block it is declared in. l= ives only for execution of the block. static: visible in the block/file it is declared in. Lives for the entire l= ife of execution. automatic: allocated on stack. visible in block it is declared in. lives o= nly for execution of the block. volatile: variable can be changed outside of current context. So each read/= write is meaningful non-volatile (default): variable is untouched outside of current context. Just remember to make everything only as visible and live as long to get the job done. BAJ >=20 > Thank you again! >=20 > Josh > --=20 > A common mistake that people make when trying to design something > completely foolproof is to underestimate the ingenuity of complete > fools. > -Douglas Adams > --=20 > http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive > View/change your membership options at > http://mailman.mit.edu/mailman/listinfo/piclist --=20 Byron A. Jeff Chair: Department of Computer Science and Information Technology College of Information and Mathematical Sciences Clayton State University http://faculty.clayton.edu/bjeff --=20 http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist .