Reputation: 43
Not sure what is "good practice" or considered more "correct". I have an array, I want to access individual elements by names other than arrayname[]. I could use #defines or pointers, probably other ways also.
Example:
#define value1 myarray[1]
int myarray[SIZE];
value1 = 5;
or
int myarray[SIZE];
int *ptr;
ptr = &myarray[1];
*ptr = 5;
Seems to me the #define route is simpler and uses less memory, but could bring up a bunch of issues I am not aware of. Any insight would be great, I like to keep my code following the general accepted standards wherever possible.
*Edit:Maybe there is a better way altogether. My end goal is to get an array that will be sent out a peripheral port. However the data is comprised of very different data sets, and a single array name would not be representative of the data being assigned. My memory is quite limited so I would like to avoid double storing each value.
Upvotes: 4
Views: 2771
Reputation: 62333
The non-define method allow you a degree of type correctedness that is not available from the second.
Furthermore the actual code generated by any sane compiler will be identical for both.
All in I'd waaay prefer the 2nd as it is instantly obvious what is going on. The other bugger is that the #define could cause problems outside of the scope of the area you are actually dealing with.
Its much more sensible using the latter as it means it is less likely that someoen else will come along and mess it up at a later occasion ...
Upvotes: 0
Reputation: 275600
enum {SIZE = 100};
struct Mapping {
int unused1;
int value1;
int unused2;
};
Mapping& AsMapping( int(&array)[SIZE] ) {
return *reinterpret_cast<Mapping*>(&array);
}
int arr[SIZE];
AsMapping(arr).value1 = 5;
Mapping& values = AsMapping(arr);
values.value1 = 5;
This requires next to no memory, and optimizers should be able to erase everything. Meanwhile, it is reasonably maintainable.
Setting up the alignment on your struct
s may be a requirement that you have to be careful of.
Upvotes: 1
Reputation: 563
You could do something like this
typedef enum
{
foo = 0;
// ... more named values
bar = SIZE;
} Thing;
int value[SIZE];
value[foo] = 5;
Using an enum as an array index
Upvotes: 0
Reputation: 1889
union
s are another way to alias variables. But don't take this as a recommendation. They are dangerous (unportable) if you rely on the aliasing. You should only use them to optimize memory usage, for variables which you don't need at the same time.
Upvotes: 1
Reputation: 1215
I propose a third option, by example:
#define VALUE1_IDX 1
int myarray[SIZE];
myarray[VALUE1_IDX] = 5;
The advantage of this over #1 is that it's still obvious that you're making use of myarray, and the advantage over #2 is, like you said, avoiding pointers. I would suspect, but haven't verified, that with optimization there is going to be no extra memory usage with option #2, despite that it seems intuitive that it would.
I think the best solution will vary with the situation, and I think either of your two options could be defensible in the right context.
Edit: To echo Kevin's comment, it's also first worth checking if it's possible to avoid using an array when you're not handling the values collectively. I realize that there are certainly situations where this does not apply, such as if you read in a long message and want to simply pull out a couple of key values.
Upvotes: 5