Reputation: 7435
This is regarding C
programming language.
I have a large number of 2D arrays (sizes are not fixed
). Consider following example.
bool sym_a[][]={{...},{...},...}; //consider these are initialized properly
bool sym_b[][]={{...},{...},...};
...
bool sym_z[][]={{...},{...},...};
bool sym_0[][]={{...},{...},...};
bool sym_1[][]={{...},{...},...};
...
bool sym_9[][]={{...},{...},...};
...
Note the naming convention, all the names are alike. Only the last character of the array name changes (better if it can be more than one character, but that's not important).
Alright, now I have a function. It selects one of those 2D arrays according its passed argument. Then do some task with the selected array. Note that task is a common one, only the selected array gets changed.
For example, according to what I can currently think of, yeah switch-case, I can implement the function as below.
void doStuff(char letter){
switch(letter){
case 'a':
sym_a[0][0]=1; //just for demonstration :D
break;
case 'b':
sym_b[0][0]=1; //same thing, only the character 'a' changed to 'b'
break;
...
case 'z':
sym_z[0][0]=1;
break;
case '0':
sym_0[0][0]=1;
break;
case '1':
sym_1[0][0]=1;
break;
...
...
}
}
But there must be a better way. If i have 1000 such arrays, then do I have to write 1000 such cases?? For all the cases, content is exactly the same. Only one character of a variable name gets changed.
It would be nice if there's something like string concatenation.
#define conc(a,b) a ## b
Then conc(sym_,a)
will represent sym_a
. But that can't be directly applied here. Because i can't pass the exact letter to the right side argument of conc(a,b)
, only the variable which contain the desired letter can be passed.
void doStuff(char letter){
conc(sym_,letter)[0][0]=1;
}
conc(sym_,letter)
gives sym_letter
. But i need to concatenate sym_
with the content of the character variable letter
.
For example, if i call doStuff('b');
them sym_b
should be given, instead of sym_letter
.
Hope my requirement clear. This thing seems pretty simple but I can't think of way to get rid of this. Note that the sizes (number of rows/columns) of the 2D arrays are not fixed. Otherwise i could have used a 3D array.
Any thought is appreciated.
Upvotes: 2
Views: 196
Reputation: 606
Allocate an large int array and partition it for your other variables.
eg.
int data[2600];
will have first 100 integers for sym_a next 100 for sym_b and so on. You will be able to store 8 * 100* 4 boolean values in these arrays.
now to access sym_p[x][y] you will say is you have total R rows and C columns:
int * start = data + (ASCIValue(p) - ASCIValue(a)) * 100;
You wud have to read/write bit number (C * x + y) from start.
Upvotes: 1
Reputation: 6834
Does something like this help? [ Apologies if there's some C++ here. ]
bool** sym_a;
bool** sym_b ;
bool** sym_z;
bool** sym_0;
bool** sym_1;
bool** sym_9 ;
unsigned lowestEntry = 'a';
unsigned highestEntry = '9';
const unsigned numEntries = highestEntry - lowestEntry;
size_t size = sizeof(bool**)* numEntries;
bool*** lookup = (bool***)malloc(size);
#define conc(a,b) a ## b
#define index(a) #a[0]-'a'
#define add(a) lookup[index(a)] = conc(sym_,a)
void init()
{
memset(lookup, 0, size);
add(a);
add(b);
add(z);
add(9);
add(k); // does not compile, sym_k not defined.
}
bool** findSymbolTable(char val)
{
return lookup[val - lowestEntry];
}
Upvotes: 1
Reputation: 15756
You have a large number of static arrays, so it' probably a natural extension that you'll end up having a large number of conditionals to access them.
You could define an additional static array that maps the character code to an array.
static const struct {
char* lookup_code;
bool **array;
} char_code_lookup[] = {
{ .lookup_code = "a", sym_a },
{ .lookup_code = "b", sym_b },
/* ... */
{ .lookup_code = NULL, NULL }, /* Terminator */
};
Your doStuff
function could then scan the array looking for the appropriate lookup code to match with the statically defined array.
With a bit of macro magic, you could generate both the static arrays, and the static lookup array together to reduce duplication, but the approach listed above is probably easier to read.
Alternatively, you could allocate your arrays dynamically using malloc
, and at the same time associate a lookup code at the time the array is created at run time.
Upvotes: 2