How to manipulate a variable value using an array?

I really really really want to be able to use an array to call my relays. How can i do this? See below post for what i want to be able to do.

Better yet, how can a store variable names within an array so that when i say:
myVar = 1;
array[1] = {myVar};

array[1] = 2;
printf(myVar);

I want the displayed output to be 2

You can store the address of the variable in the array, then use that address as a pointer to the value you want to print. Your array would be declared as an array of pointers.

myVar = 1;
array[1] = &myVar;

(*)(array[1]) = 2;
printf("%d
",myVar);

Good luck,
~Phil

Or use a macro.


#define MYVAR        array[1]

print(MYVAR);

I need you to confirm if what I am thinking is correct:

myVar = 1; Establish the “shell” as being = 1
array[1] = &myVar; Let the 1st value of array] = the address of the “shell”

(*)(array[1]) = 2; the * means modify/check the contents of the address of myVar
printf(*myVar); since the shell wasn’t updated, the * is needed to display the contents of the address of myVar since printf(myVar) would return 1

 (*)(array[1]) = 2;

That would put a ‘2’ in the memory cell pointed to by the address in array[1]. Or in this case…since the address in array[1] is that of myVar, the value of myVar would be 2, so assuming myVar is an int, your code for printing it out would be:

printf("%d
",myVar);

Which would print out ‘2’.

int *ptr;
int a, b;

a = 10;
ptr = &a;
b = *ptr;

Why bother with the int *ptr declaration when it has to be used again in the b= part? Is this just proper etiquette and not really needed?

Is this alright for my declaration:
int joystickbuttons[8] = {&p1_sw_trig, &p1_sw_top, &pl_sw_aux1, &p1_sw_aux2, &p2_sw_trig, &p2_sw_top, &p2_sw_aux1, &p2_sw_aux2};

And this for my looped search:
if ((*)joystickbuttons[arrayindexer[1]] == 1)

arrayindexer is just a simple array I am using for a counter.

If all this looks good then it means I finally figured this whole pointer thingie out largely thanks to this forum and Wiki.


int *ptr; //ptr is a pointer to the address an 'int' somewhere in memory
int a, b; //compiler chooses where these go in memory, each have an address

a = 10; //set value of a to 10
//pass a by reference to ptr
ptr = &a; //ptr now holds the address of where a is in memory
b = *ptr; //b now holds the value (use *) that ptr points to

In this case, b would be equal to a at the end.
The first line declares a pointer, which is different from a regular variable.
You can do other cool things with this, too.


void idouble(int * input){
   *input *= 2 ;
}

void main(){
    int x ;
    x = 5 ;
    idouble(&x) ;
    print(x);
}

This will print 10.

So i have to say that my array of buttons is going to be holding addresses by declaring it like this:


int (*)joystickbuttons[8] = {&p1_sw_trig, &p1_sw_top, &pl_sw_aux1, &p1_sw_aux2, &p2_sw_trig, &p2_sw_top, &p2_sw_aux1, &p2_sw_aux2};

And thus the * in the declaration indicates that the variable is “special” in that it will indeed be holiding addresses and not just numbers and crap.

And the 2nd half of the above code:


if ((*)joystickbuttons[arrayindexer[1]] == 1)

Will my above 2 pieces of code work?

I don’t get some of your example:


void idouble(int * input){  Input the address and convert it to the data "input"
   *input += input ; I don't get the use of *input
}

void main(){
    int x ;
    x = 5 ;
    idouble(&x) ;  Call the above function giving it an address as a parameter
    print(x); I don't get how the idouble() returns x
}

input is a pointer. it holds an address. in this particular case, it holds the address of x. putting a * in front of a pointer means that you want to look at the value held at the address of the pointer. if input = &x, *input = x. so modifying *input will actually be modifying the value held in x. (input is a pointer, so it has no real value attached to it.) By doing this, you can modify variables in your main function without returning ANYTHING from a called function. idouble returns nothing, but because you are telling it where x is in memory and not just the value of x, you can actually change x from another function. Make sense?

Oh you sly bastard :wink: You are basically bypassing the whole naming system of variables with input and directly puting data to addresses. I like this :slight_smile: The int *input is just the declaration of input and not the actual conversion of &x to data…that was the confusing part. I can see why google refers to pointers as “advanced c”.

Can you check the code i posted above the above post to tell me if that will work fine?

This code isn’t working:

int *joystickbuttons[8] = {&p1_sw_trig, &p1_sw_top, &pl_sw_aux1, &p1_sw_aux2, &p2_sw_trig, &p2_sw_top, &p2_sw_aux1, &p2_sw_aux2};

it errors me saying

I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1105] symbol ‘pl_sw_aux1’ has not been defined
I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1101] lvalue required
I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1218] extraneous initializer values

Well I see you have a pl instead of a p1

I fixed that but it still says

I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routines.c:411:Error [1200] cannot reference the address of a bitfield

not a 100% but I think it may have something to do with the fact that the p1, p2 etc switches are defined to structures. They’re defined in the C preprocessor but they were never declared as variables anywhere else(atleast not anywhere I could find)

I’m thinking that you can’t do this with those variables…

The problem is what MPLAB says it is, you cannot reference (aka have a pointer to) a bitfield, relay outputs and, I assume, joystick switch states are stored in bitfields.

I know they are defined in ifi_aliases.h with the #define. So how do I get them out of bitfields? Do i need to “redeclare” them as ints?

When I was trying to write a generalized, modular library for FRC robots (something like WPIlib, but not as high level), I ran into this same issue, but with relay outputs. My solution was to use a structure for storing the values then, at the end of the program loop, call a function that assigned the values in the structure to the actual relays. I think you could do something similar in your case; for example, you could just assign the values of the switches to the various variables in your array at the beginning of every program cycle.

I don’t think you can redefine them to an INT since it’s using a structure.

Each of these names refers to a single bit, not a byte. Because each symbol is referring to a bit and not a byte, an address is insufficient to identify the symbol. The wikipedia article http://en.wikipedia.org/wiki/Bitfield explains the concept very well.

You must look to where the bit field is defined, and manipulate the struct. However, that seems somewhat counter to what you are attempting.

~Phil