Reputation: 47
I have a structure that I've set up, and a pointer to the structure, that is basically an array. I want to create a function that modifies specific values within the structure but can't seem to figure out how to pass in the structure pointer as a parameter.
struct deviations {
int switch;
int x;
int y;
};
struct deviations *pdevs = malloc(24 * sizeof(int));
for(int i = 0; i < 8; i++) {
(pdevs + i)->switchez = 1;
(pdevs + i)->x = 0;
(pdevs + i)->y = 0;
}
int top[3] = {0, 1, 2};
int bottom[3] = {5, 6, 7};
int left[3] = {0, 3 ,5};
int right[3] = {2, 4, 7};
for(int i = 0; i < 3; i++) {
(pdevs + top[i])->y = -1;
}
I have multiple (8) for loops
like above and in each of them the basic structure is the same, except the array ("top"), lvalue ('y') and rvalue ('-1') change in each. I can't figure out how to declare a function with the structure/pointer to structure properly.
I currently have it around 26 lines of (8 for loops repeating) code and am pretty sure I can compress it down to a tidy little function if I can figure out how to pass in the pointer to the structure. Any help would be much appreciated!
This snippet is part of a larger function/program that determines whether or not to check the surrounding items (3 up top, 3 at bottom, one on each side). I have set up a structure with an on/off switch based on the position of the base item, and an x/y offset. I am trying to shift each individual cell by a certain amount +1/-1/ or 0 in the x or y position. And I am trying to flip the switch on or off depending on certain conditions about the x or y of the original cell. Malloc is probably unnecessary, but am unsure whether or not this array of structs will be used again later, if not, I will remove the call to malloc.
Thanks!
Upvotes: 0
Views: 90
Reputation: 63481
This answer serves purely to challenge your thinking about your current approach.
Personally, unless there's some special logic involved, I would just ditch the loops completely and initialize your struct like this.
const struct deviations devs[8] = {
{ 1, -1, -1 }, // top-left
{ 1, 0, -1 }, // top
{ 1, 1, -1 }, // top-right
{ 1, -1, 0 }, // left
{ 1, 1, 0 }, // right
{ 1, -1, 1 }, // bottom-left
{ 1, 0, 1 }, // bottom
{ 1, 1, 1 } // bottom-right
};
If you then decide that you really need to allocate that dynamically then you could just copy it:
struct deviations *pdevs = malloc(sizeof(devs));
if (pdevs) memcpy(pdevs, devs, sizeof(devs));
But if you really wanted to generate this stuff in a loop, why not something like this?
int ii = 0;
for(int y = -1; y <= 1; ++y) {
for(int x = -1; x <= 1; ++x) {
if (x == 0 && y == 0) continue;
pdevs[ii].switch = 1;
pdevs[ii].x = x;
pdevs[ii].y = y;
++ii;
}
}
Upvotes: 1
Reputation: 782509
So you want a generic function that can take an array of 3 indexes, the structure member to fill in, and the value.
The array and value are simple. To handle a structure member generically, you can use the offsetof()
macro.
void fill_structs(struct deviations *pdevs, size_t offset, int indexes[3], int value) {
for (int i = 0; i < 3; i++) {
*((int *)((char *)&pdevs[indexes[i]] + offset)) = value;
}
}
Then you call it like:
fill_structs(pdevs, offsetof(struct deviations, y), top, -1);
offsetof()
returns the offset in bytes of a structure member from the base of the structure. So in the function you have to convert the address of the array element to char *
so you can add the offset to it, then convert it to int *
so you can dereference it and assign to the int
member there.
BTW, you should get out of the habit of using things like
(pdevs + i) -> x
If you're using a pointer as the base of an array, use array syntax:
pdevs[i].x
It's much easier to tell that i
is an array index this way.
Upvotes: 1