View Full Version : How to manipulate a variable value using an array?
amateurrobotguy
12-12-2007, 22:03
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.
amateurrobotguy
12-12-2007, 22:14
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
Phil Mack
12-12-2007, 23:03
how can a store variable names within an array
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\n",myVar);
Good luck,
~Phil
Tom Bottiglieri
12-12-2007, 23:38
Or use a macro.
#define MYVAR array[1]
print(MYVAR);
amateurrobotguy
13-12-2007, 00:11
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
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\n",myVar);
Which would print out '2'.
amateurrobotguy
13-12-2007, 01:44
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.
Tom Bottiglieri
13-12-2007, 01:51
Why bother with the int *ptr declaration when it has to be used again in the b= part? This is the example from 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.
amateurrobotguy
13-12-2007, 01:54
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
}
Tom Bottiglieri
13-12-2007, 02:23
I don't get some of your example:
void idouble(int * input){ Input the address and convert it to the data "input"
*input *= 2 ; 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?
amateurrobotguy
13-12-2007, 02:27
Oh you sly bastard ;) You are basically bypassing the whole naming system of variables with input and directly puting data to addresses. I like this :) 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?
amateurrobotguy
13-12-2007, 20:13
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_routine s.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routine s.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routine s.c:411:Error [1105] symbol 'pl_sw_aux1' has not been defined
I:\Robot\2007\MPLAB\Current\2007_2005\user_routine s.c:411:Error [1101] lvalue required
I:\Robot\2007\MPLAB\Current\2007_2005\user_routine s.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routine s.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routine s.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routine s.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routine s.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routine s.c:411:Error [1218] extraneous initializer values
kevin.li.rit
13-12-2007, 20:31
Well I see you have a pl instead of a p1
amateurrobotguy
13-12-2007, 20:48
I fixed that but it still says
I:\Robot\2007\MPLAB\Current\2007_2005\user_routine s.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routine s.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routine s.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routine s.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routine s.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routine s.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routine s.c:411:Error [1200] cannot reference the address of a bitfield
I:\Robot\2007\MPLAB\Current\2007_2005\user_routine s.c:411:Error [1200] cannot reference the address of a bitfield
kevin.li.rit
13-12-2007, 21:04
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...
lukevanoort
13-12-2007, 21:25
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.
amateurrobotguy
13-12-2007, 21:28
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?
lukevanoort
13-12-2007, 21:44
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.
kevin.li.rit
13-12-2007, 22:54
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?
I don't think you can redefine them to an INT since it's using a structure.
Phil Mack
13-12-2007, 23:29
cannot reference the address of a bitfield
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.
So how do I get them out of bitfields?
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
amateurrobotguy
14-12-2007, 00:17
So much for elegant coding...
But i think lukevanoort's workaround will work, just as long as I put it all in a separate function. My goal with this was just to clean up a billion if-thens into a for loop but i guess a if-then function will make the code easier to read anyways.
vBulletin® v3.6.4, Copyright ©2000-2017, Jelsoft Enterprises Ltd.