关于C typedef结构

时间:2013-06-25 21:36:07

标签: c struct

我有多个typedef结构框的实例,所以框box1,box box2等。 结构的成员是长度,宽度,高度等。

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

box box1;
box box2;

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

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

在函数内?

5 个答案:

答案 0 :(得分: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;

答案 1 :(得分:1)

在typedef(或结构)中没有可以附加指针的字段width。该字段仅存在于该类型的具体对象中。因此,您不能指向结构的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);
在调用

时,

会将box1box2box3的宽度设置为42

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

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

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

答案 2 :(得分:0)

您似乎要求指向成员的指针,但这些是C ++功能(尽管您可能遇到严格的别名问题,但可以使用offsetof进行模拟)。除非您要求.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; } 在那种情况下,没有答案。这看起来像这样:

offsetof

邪恶的C // 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; } 变体:

{{1}}

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

答案 3 :(得分:0)

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

另一种选择是使用宏。这也许是一个坏主意,但这是如何:

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

并像这样使用它:

assign(width, 5);

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

答案 4 :(得分:0)

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

  

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

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

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
    ...
  }
}