0

我有多个 typedef struct box 实例,例如 box box1、box box2 等。结构的成员是长度、宽度、高度等。

typedef struct 
{
    int width;
    int height;
} box;

box box1;
box box2;

如何创建一个对每个框实例的所有宽度成员进行操作的函数?我的困惑是如何将指针传递给适用于所有 box 实例的 typedef 结构成员。我知道如何将指针传递给 box1.width 等特定实例成员,但如何传递 .width 然后执行

box1.width=value;
box2.width=value;
box3.width=value;

函数内?

4

5 回答 5

3

您可能需要考虑使用数组而不是大量单独的实例,例如

typedef struct 
{
    int width;
    int height;
} Box;

Box boxes[3];                   // array of 3 boxes

for (b = 0; b < 3; b++)         // set `width` field of all boxes to `value`
    boxes[b].width = value;

或者,如果您确实出于某种原因确实想要迭代许多不同的框变量,那么您可以初始化一个指针数组,例如

 Box box1;  // 3 separate Box variables
 Box box2;
 Box box3;

 Box *boxes[3] = { &box1, &box2, &box3 };
                                 // array of pointers to box1, box2, box3

 for (b = 0; b < 3; b++)         // set `width` field of all boxes to `value`
    boxes[b]->width = value;
于 2013-06-25T21:38:44.110 回答
1

widthtypedef(或结构)中没有可以附加指针的字段之类的东西。该场仅在物理上存在于该类型的具体对象中。所以,你不能有一个指向结构的指针width。您只能拥有指向 的指针box1.widthbox2.width依此类推。

不可能以某种方式编写一个会改变width所有现有对象的函数。更准确地说,不可能编写一个函数以某种方式神奇地枚举该类型的所有现有对象并更改width其中的字段。您有责任告诉您的函数您想要更改哪些对象。

无论如何,你想做什么?


如果您正在尝试编写一个“setter”函数,该函数将使用要设置的特定字段进行运行时参数化,如果可以通过偏移量在 C 中完成。例如

void set_value(box *box, size_t offset, int value) {
  *(int *) ((char *) box + offset) = value;
}

box box1;
box box2;
box box3;

void set_values(size_t offset, int value)
{
   set_value(&box1, offset, value);
   set_value(&box2, offset, value);
   set_value(&box3, offset, value);
}

现在打电话

set_values(offset_of(box, width), 42);

box1将在,box2box3to中设置宽度42,同时调用

set_values(offset_of(box, height), -5);

将这些对象的高度设置为-5.

但是,同样,您有责任确保函数知道它必须更改哪些对象。在上面的示例中,我只是将它们声明为文件范围变量。在现实生活中,这通常是不可能的。

于 2013-06-25T21:44:38.867 回答
0

您不能将width字段本身传递给函数。但是,您可以在结构内传递它的偏移量。这是一个“肮脏”的技巧,有时用于低级编程,但我不建议您在没有充分理由的情况下使用它。

另一种选择是使用宏。这也可能是个坏主意,但方法如下:

#define assign(field, value) \
    do { \
        box1.field = value; \
        box2.field = value; \
        box3.field = value; \
    } while (0) 

并像这样使用它:

assign(width, 5);

如果您事先不知道这些框是什么,您可以将其与此处建议的阵列解决方案结合使用。

于 2013-06-25T21:52:13.927 回答
0

您似乎在要求指向成员的指针,但是这些是 C++ 功能(offsetof尽管您可能会遇到严格的别名问题,但可以模拟它们)。除非您要求 a.width影响的所有实例box,而没有指定特定实例。在这种情况下,没有答案。这看起来像这样:

// C++ ahead

struct box
{
    int width;
    int height;
};

box boxes[3];

void setGlobalBoxesValue(int value, int box::*member)
{
    for(unsigned int i = 0; i < sizeof(boxes)/sizeof(boxes[0]); ++i)
        boxes[i].*member = value;
}

int main(int, char**)
{
    setGlobalBoxesValue(4, &box::width);
    setGlobalBoxesValue(3, &box::height);
    return 0;
}

邪恶的 Coffsetof变种:

// C emulation (not typesafe)

#include <stddef.h>
#include <string.h>

typedef struct
{
    int width;
    int height;
} box;

box boxes[3];

void setGlobalBoxesValue(int value, size_t memberOffset)
{
    for(unsigned int i = 0; i < sizeof(boxes)/sizeof(boxes[0]); ++i)
        memcpy((char*)(boxes+i) + memberOffset, &value, sizeof(value));
}

int main(int, char**)
{
    setGlobalBoxesValue(4, offsetof(box, width));
    setGlobalBoxesValue(3, offsetof(box, height));
    return 0;
}

如果您只想对 box 的多个实例应用相同的操作,请将它们放在一个数组中并在数组上循环(如果它们分布在内存中,则为指针数组)。

于 2013-06-25T21:39:26.780 回答
0

我不确定我是否理解你的问题,但是

如何创建一个对每个框实例的所有宽度成员进行操作的函数?我的困惑是如何将指针传递给适用于所有 box 实例的 typedef 结构成员。我知道如何将指针传递给 box1.width 等特定实例成员,但如何传递 .width 然后执行

通过创建一个以 typedef 作为参数的函数,您可以访问结构的宽度

void foo(box* p)
{
  p->width  .. do something
...
} 

或者如果你的意思是传递一个盒子数组

void foo(box* p, int count)
{ 
  for (int i = 0; i < count; ++i)
  {
     p[i]->width .. do something
    ...
  }
}
于 2013-06-25T21:58:07.173 回答