Wrap your head around this Array!
Spire_Jeff
Posts: 1,917
I was just doing a little more reading in my Java book and this was an interesting concept to me. In Java, because of the object oriented nature of it all, a multi-dimensional array does not require the same number of dimensions throughout the array. Take for example an array that describes the contents of 4 different CD Changers. The details of the 4 changers are as follows:
Changer 1 holds 400 CDs
Changer 2 holds 200 CDs
Changer 3 holds 200 CDs
Changer 4 holds 5 CDs.
In NetLinx, you would have to either declare a minimum of 3 different arrays to effectively use memory, or declare a single multidimensional array that wastes a bunch of memory as such:
Char sCdInfo[4][400][25]
This results in the following lengths:
sCdInfo[1] length is 400 - 400 slots are used
sCdInfo[2] length is 400 - 200 slots are used, 200 are wasted
sCdInfo[3] length is 400 - 200 slots are used, 200 are wasted
sCdInfo[4] length is 400 - 5 slots are used, 395 are wasted
In Java, you can declare the variable in a way that uses only the necessary length for each dimension.
First you would declare the pointer and start the array:
CdRecord[][] sCdInfo = new CdRecord[4][];
Then you would declare the length for each dimension:
sCdInfo[0] = new CdRecord[400];
sCdInfo[1] = new CdRecord[200];
sCdInfo[2] = new CdRecord[200];
sCdInfo[3] = new CdRecord[5];
And voila, you have everything contained in one multidimensional array without all the wasted space!
You could even take it further and say that there are 3 racks in the project, Rack 1 has (3) 400 disc changers, Rack 2 has (2) 5 disc changers and (4) 200 disc changers, and Rack 3 has a single 5 disc changer.
CdRecord[][][] sCdInfo = new CdRecord[3][][];
Now declare the number of changers per rack:
sCdInfo[0] = new CdRecord[3][];
sCdInfo[1] = new CdRecord[6][];
sCdInfo[2] = new CdRecord[1][];
Then you would declare the capacity for each changer:
sCdInfo[0][0] = new CdRecord[400];
sCdInfo[0][1] = new CdRecord[400];
sCdInfo[0][2] = new CdRecord[400];
sCdInfo[1][0] = new CdRecord[5];
sCdInfo[1][1] = new CdRecord[5];
sCdInfo[1][2] = new CdRecord[200];
sCdInfo[1][3] = new CdRecord[200];
sCdInfo[1][4] = new CdRecord[200];
sCdInfo[1][5] = new CdRecord[200];
sCdInfo[2][0] = new CdRecord[5];
Now, you can get the CD info for anything being played by plugging in the CurrentRack-1, CurrentChanger-1 and CurrentCD-1 (Remember that Java starts at 0 for indexes).
Can this be done effectively with switch cases and multiple variables in NetLinx, sure. I have just become so accustomed to the way NetLinx deals with arrays that it took me a second to accept what the Java book was saying. My first thoughts were (in no particular order): 1) That's stupid, why would you need that. 2) That makes no logical sense. 3) That is either a misprint, or I read it wrong!
That just proved to me how my instincts to resist change work. I had probably originally tried to use an array in just the way Java implements it, but over the years, I have conditioned myself to "KNOW" that it works the way NetLinx does it. (I actually learned it that way LONG before I started using NetLinx )
I was so impressed with this, I just had to share it with people that can at least understand what I'm talking about.... even if nobody else is amazed by this, at least you can understand what I am saying If I tried to tell this to the boss or the people that live with me, I would most likely just get a glazed over looked followed by an object flying in my general direction at a high rate of speed.
Jeff
Changer 1 holds 400 CDs
Changer 2 holds 200 CDs
Changer 3 holds 200 CDs
Changer 4 holds 5 CDs.
In NetLinx, you would have to either declare a minimum of 3 different arrays to effectively use memory, or declare a single multidimensional array that wastes a bunch of memory as such:
Char sCdInfo[4][400][25]
This results in the following lengths:
sCdInfo[1] length is 400 - 400 slots are used
sCdInfo[2] length is 400 - 200 slots are used, 200 are wasted
sCdInfo[3] length is 400 - 200 slots are used, 200 are wasted
sCdInfo[4] length is 400 - 5 slots are used, 395 are wasted
In Java, you can declare the variable in a way that uses only the necessary length for each dimension.
First you would declare the pointer and start the array:
CdRecord[][] sCdInfo = new CdRecord[4][];
Then you would declare the length for each dimension:
sCdInfo[0] = new CdRecord[400];
sCdInfo[1] = new CdRecord[200];
sCdInfo[2] = new CdRecord[200];
sCdInfo[3] = new CdRecord[5];
And voila, you have everything contained in one multidimensional array without all the wasted space!
You could even take it further and say that there are 3 racks in the project, Rack 1 has (3) 400 disc changers, Rack 2 has (2) 5 disc changers and (4) 200 disc changers, and Rack 3 has a single 5 disc changer.
CdRecord[][][] sCdInfo = new CdRecord[3][][];
Now declare the number of changers per rack:
sCdInfo[0] = new CdRecord[3][];
sCdInfo[1] = new CdRecord[6][];
sCdInfo[2] = new CdRecord[1][];
Then you would declare the capacity for each changer:
sCdInfo[0][0] = new CdRecord[400];
sCdInfo[0][1] = new CdRecord[400];
sCdInfo[0][2] = new CdRecord[400];
sCdInfo[1][0] = new CdRecord[5];
sCdInfo[1][1] = new CdRecord[5];
sCdInfo[1][2] = new CdRecord[200];
sCdInfo[1][3] = new CdRecord[200];
sCdInfo[1][4] = new CdRecord[200];
sCdInfo[1][5] = new CdRecord[200];
sCdInfo[2][0] = new CdRecord[5];
Now, you can get the CD info for anything being played by plugging in the CurrentRack-1, CurrentChanger-1 and CurrentCD-1 (Remember that Java starts at 0 for indexes).
Can this be done effectively with switch cases and multiple variables in NetLinx, sure. I have just become so accustomed to the way NetLinx deals with arrays that it took me a second to accept what the Java book was saying. My first thoughts were (in no particular order): 1) That's stupid, why would you need that. 2) That makes no logical sense. 3) That is either a misprint, or I read it wrong!
That just proved to me how my instincts to resist change work. I had probably originally tried to use an array in just the way Java implements it, but over the years, I have conditioned myself to "KNOW" that it works the way NetLinx does it. (I actually learned it that way LONG before I started using NetLinx )
I was so impressed with this, I just had to share it with people that can at least understand what I'm talking about.... even if nobody else is amazed by this, at least you can understand what I am saying If I tried to tell this to the boss or the people that live with me, I would most likely just get a glazed over looked followed by an object flying in my general direction at a high rate of speed.
Jeff
0
Comments
Paul
Rectangular arrays (again, the technical term) have the nice property of being able to store an array of NxM bytes in NxM bytes in memory. Dereferencing element n,m is as simple as looking in memory at the address base + n*M + m (or base + m*N + n, depending on layout). The downside, of course, is that they are rectangular, and the full NxM is allocated in memory whether you need all of the elements or not.
Jagged arrays, as you can guess from the way you initialize them, use an array of N pointers for the first dimension, each of which points to an array with a variable number of elements. Extra memory is required, and dereferencing a two-dimensional array is a two-step process (look up the pointer in the first array, add the offset and look up the element in a second array) Each dimension adds another step. The benefit, of course, is that you can save the memory for elements that you don't need.
I don't remember offhand how Java arrays work, but C# allows you to declare them as rectangular [i,j] or jagged [j] depending on what you need.
NetLinx seems to be based on a simplified version of C. Without pointers, it's not possible to create jagged arrays, but you also gain some "safety" by removing some of the ways for things to go wrong. Java and C# are much more mature languages, and do indeed have some very cool features. If you really want to blow your mind (and expand your programming abilities), try teaching yourself LISP or Scheme.
Oh I completely understand. I have thought things in the past were rather interesting...and my finacee continues to call me names
Ah, Scheme... I haven't looked at it for years. I agree that it really is mind-blowing. When I looked at it, it seemed too elegant to be true. Now if only there were some good RAD/GUI tools for Scheme... (Maybe there are - I haven't had the need to look.)
Roger McLean
Swinburne University
If you like Scheme try Prolog. Its been many years since I have written a Prolog program but its pretty cool because all you do is write rules, and the program comes up with the intelligent answer to your query. Once the rules are written, the program figures things out on its own based on those rules. It is similar to the way chess games are written since there is no way a program could be written that could know what to do in any chess situation. I have often thought that control systems are perfectly suited to being written in Prolog.
http://en.wikipedia.org/wiki/Prolog
Paul
For example, in Netlinx you would use the following to declare a pointer:
Where in Java you would use the following:
Now in Java, you declare that x is a pointer of some type (intObj in the example), then you have the freedom to either assign it a pointee (the new intObj) or else another pointer and therefore take on that pointer's pointee - for example, the following:
Netlinx, as far as I can tell, simply assumes this connection; a pointee is simply simultaneously generated with the introduction of the pointer, and the link between the two is implicitly made. I guess the alternative is that Netlinx simply has literally no concept of a pointer or pointee, but if its function were translated to, say Java, then it would operate as I'm describing... Does this make any sense? :P
Sorry - I'm into more flexible data structures and memory handling and all that - just don't feel the need to dive into them for control system programming. At least not yet...
- Chip
There are no pointers in Netlinx or Java, only references. In your Java example above, you are just changing the reference from x to y. A pointer is a variable that contains a memory address of another variable. Once you have the address of a variable you can do arithmetic on it, pass it to a function and do other useful things. In C, you can declare a variable x and then declare a pointer to x called y. These are two different things as one is a variable that contains a value the other is a variable that contains the memory address of that value. I guess you could call Netlinx variables constant pointers, but then its just a reference so why not just call it that?
Paul
I suppose, therefore my question is still conceptually valid, but terminologically incorrect. I realize, as well, that my question is practically pointless, but honestly I'm just trying to wrap my mind around it all.
Thanks Paul.
given: array[2][3][4]
rectanglular array model: array[x][y][5] is never legal.
given
array[1][2][4]
array[2][2][5]
jagged array model array[x][y][5] might sometimes be legan and others not.
In most compilers I've seen that allow jagged they do kind of a modification of both methods to increase procesing speed: they basically assign the smallest contiguous block of memory needed to get the array done(rectangular) and then use pointer(s) to work the jagged part in a reserved part of dyncamic memory set asside for such silliness.
so, when you're working in the main rectangle things move quite fast. Once you're accesing data outside the box, then the indexing/pointer(s) kick in.
creepy...