处理函数中结构数组的成员

时间:2013-04-15 18:13:26

标签: c arrays structure member

假设我有

struct my_type_t {
    int x;
    int y;
    int z;
};

struct my_array_t {
    struct my_type_t test;
    int otherstuff;
};

int main(void) {
    struct my_array_t arrayofstructs[200];
    somefunction(arrayofstructs);

    return 0;
}

void somefunction(struct my_array_t *arrayofstructs, somevariable) {
    for (int i; i < 200; i++) {
        //Do stuff to 
        arrayofstructs->test[i].somevariable;
    }
}

如何传递somevariable以告诉函数处理结构数组的成员(x,y或z)?

谢谢!

4 个答案:

答案 0 :(得分:1)

事实一:您应该通过arrayofstructs而不是&arraystructs

处理问题的方法是这样的:

void someFn(data_type *var , int somevar) {
  ...
  ...
  ...
  switch(somevar) {

  case <some_value>:
  some_task;
  break;

  ...
  ...
  ...
  } //End switch

  }

即,传递与每个成员相关的标识符,并根据输入标识符使用选择性结构执行某些任务。

举一个简单的例子,somevar可以是整数,你必须知道整数中的值对应于什么。

修改

或者您可以执行以下操作

struct mystr{
  int mem[3];
}

void someFn(struct mystr a, int somevar){ 

  //now access those with a[i].mem[somevar]
}

这有助于清除冗余:)

答案 1 :(得分:1)

使用开关盒的其他答案可能更干净但如果有一些黑客可以,你可以使用这样的东西:

#define GET_STRUCT_OFFSET(st, m) ((size_t) ( (char *)&((st *)(0))->m - (char *)0 ))

(见Why does this implementation of offsetof() work?

要访问结构的成员,您可以执行以下操作:

int main(void) {
    struct my_array_t arrayofstructs[200];
    somefunction(arrayofstructs, GET_STRUCT_OFFSET(struct my_type_t, x));

   return 0;
}

void somefunction(struct my_array_t *arrayofstructs, int offset)
{
    for (int i; i < 200; i++) {
        //Do stuff to 
        (((void*)&arrayofstructs[i].test) + offset);
    }
}

再次非常hacky,但事实上它确实是一个简单的测试:http://ideone.com/zwvTY1

编辑:

<stddef.h>中有一个offsetof宏,使用该代码完成相同的代码:http://ideone.com/9aDo2c

答案 2 :(得分:0)

enum FieldTypes
{
   FIELD_X,
   FIELD_Y,
   FIELD_Z
};

int main(void)
{
    struct my_array_t arrayofstructs[200];
    somefunction(arrayofstructs,FIELD_X);

    return 0;
}

void somefunction(struct my_array_t *arrayofstructs, FieldTypes somevariable) 
{
    switch( somevariable )
    {
        case FIELD_X:

           for (int i; i < 200; i++) 
           {
               //Do stuff to arrayofstructs->test[i].x; 
           }
           break;

        case FIELD_Y:

           for (int i; i < 200; i++) 
           {
               //Do stuff to arrayofstructs->test[i].y; 
           }
           break;

        case FIELD_Z:

           for (int i; i < 200; i++) 
           {
               //Do stuff to arrayofstructs->test[i].z;
           }
           break;
    }
}

如果目的是始终执行相同的操作,而只是根据传递的值在结构的不同元素上执行,那么您可以这样做...

void somefunction(struct my_array_t *arrayofstructs, FieldTypes somevariable) 
{
    for (int i; i < 200; i++) 
    {
        int* workingValue;

        switch( somevariable )
        {
            case FIELD_X: workingValue = &arrayofstructs->test[i].x;  break;
            case FIELD_Y: workingValue = &arrayofstructs->test[i].y;  break;
            case FIELD_Z: workingValue = &arrayofstructs->test[i].z;  break;
        }

        // do stuff to *workingValue -- no redundant code here
    }
}

答案 3 :(得分:0)

只需使用一些不同的值即可让您的功能区分它们。您可以使用enum,某些#definechar,如下所示:

void somefunction(struct my_array_t *arrayofstructs, char whichVar) {
    for (int i; i < 200; i++) {
        //Do stuff to 
        switch(whichVar){
            case 'x': arrayofstructs->test[i].x; break;
            case 'y': arrayofstructs->test[i].y; break;
            case 'z': arrayofstructs->test[i].z; break;
        }
    }
}

请注意,使用#defineenum通常被视为更好的做法,因为您可以为您的值赋予有意义的名称。这里的char用法只是一个例子。

另见What is a magic number, and why is it bad?