|
|
View previous topic :: View next topic |
Author |
Message |
freesat
Joined: 08 Feb 2011 Posts: 32
|
What is the best way to use associative array? ( SOLVED! ) |
Posted: Mon Feb 24, 2014 3:50 pm |
|
|
Hi guys... i need some help again.
my needs is map array based on char and integer like pseudo code:
Code: |
const int8 characters[4][*] = { { '0', 0x0 }, { '1', 0x1 }, {'H', 0x76}, { 'U', 0x3e } };
int8 search( char value ) {
result = characters[value];
}
|
i want to use like this:
Code: |
write7seg( search( characters('H') ); /* like pseudo code, i need to send 0x76 stead of 'H' to serial port */
|
what is the best way to do this?
PS. write7seg is not the problem, i already do that, my needs is map char vs integer.
i will appreciate any help.
thanks.
Last edited by freesat on Wed Feb 26, 2014 1:19 am; edited 1 time in total |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Mon Feb 24, 2014 4:47 pm |
|
|
vs
Code: |
result = characters[value]
|
are we a few brackets short of a happy meal index here ?
not to mention the newbie error in the alleged 'search'
function never RETURNing a value.........
BTW: and this has WHAT? to do with CCS PIC code ?? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19549
|
|
Posted: Tue Feb 25, 2014 2:36 am |
|
|
C does not support associative arrays directly. So you have to write the search yourself.
Doesn't make any real difference (especially for something as simple as single characters). Also, you don't actually need to be using the '*' constructor. This is for arrays that have variable sizes. All your entries are the same size. Just a single character, and what it is to be replaced with.
Now, several things are not made clear though in the question. The first 'key' one is what happens to characters that do not have an entry in the array?. The second, is whether the array is likely to get much larger?.
Now the point is that if the array was likely to get much larger, then it'd be much more efficient to code it as a simple single dimensional array, in order of the ASCII value, with each entry just being the character to output. Faster code by a huge margin, once you go beyond perhaps ten values.
If the array is not likely to get much larger, then all that is needed is a simple loop for the number of the number of lines, checking the first element against the character, and if it matches returning the second.
Code: |
const int8 characters[4][2] = { { '0', 0x0 }, { '1', 0x1 }, {'H', 0x76}, { 'U', 0x3e } };
int8 search(char val)
{
int8 line;
for (line=0;line<(sizeof(characters)/2);line++)
{
if (characters[line][0]==val)
return(characters[line][1]);
}
return val; //change this if you want to return an error code etc..
}
|
Now this requires the array to be fixed in size (so not the '*' form), with 2 bytes per line. Hence the function can 'know' how large the array is, by dividing the sizeof by 2. Without this, the number of lines in the array would have to be passed. Note also that this returns the original character, if there is not a match in the array.
A genuine 'associative array', is done by generating a hash value for the search item, and then using this as the index to the array. A lot of work. Ideal if there are hundreds of items, and you have an efficient hash algorithm designed that gives close to unique solutions, and an efficient 'clash' solution, however for a limited number of values, unbelievably inefficient.....
As a further update to this, if you look at the example EX_LED.C, this shows a simple single dimensional array being used for the digits. Then remember there is no reason why you can't use both approaches. Have the simple array like you show, with 'search', handling 'exception' characters (beyond simple numeric), like H, and U, if you want these, and then where the 'have not found the character' part is reached, do a look up in a simple table for the numbers.
Best Wishes |
|
|
freesat
Joined: 08 Feb 2011 Posts: 32
|
|
Posted: Tue Feb 25, 2014 1:53 pm |
|
|
Hi Ttelmah, i really want say thanks, your code really help me a lot, and your explanation is very professional and easy to understand.
Some comments: this code is for using with max7219 7segments display driver in mode nodecode for use with 7segs and matrix, so array length is very small, see below.
Code: | const int8 characters[26][2] = { { ' ', 0x00 }, { '0', 0x3f }, { '1', 0x06 },
{ '2', 0x5b }, { '3', 0x4f }, { '4', 0x66 },
{ '5', 0x6d }, { '6', 0x7d }, { '7', 0x07 },
{ '8', 0x7f }, { '9', 0x6f }, { 'A', 0x77 },
{ 'C', 0x39 }, { 'E', 0x79 }, { 'F', 0x71 },
{ 'H', 0x76 }, { 'L', 0x38 }, { 'P', 0x73 },
{ 'U', 0x3e }, { 'b', 0x7c }, { 'c', 0x58 },
{ 'd', 0x5e }, { 'n', 0x54 }, { 'o', 0x5c },
{ 'u', 0x1c }, { 'ยบ', 0x63 } };
/*
Space character is used to turn off all 7 segments of current digit
Add 0x80 to value if dot is needed
*/
|
If searching searching character does not exists, i believe space is best option to be returned in that case.
Why not use CODEB on max7219? i want to show float with decimal points, integers with zero left and characters not in codeb, also using it with led matrix.
PCM Programmer, i read that manual before, my mistake about length [*], now i know that is about variable characters length and not array length, thanks. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|