指向结构的数组的属性的数组指针

Array pointer to the attribute of an array of struct

本文关键字:数组 属性 指针 结构      更新时间:2023-10-16

我有以下结构和主函数:

struct myStruct{
    string name;
    int id;
    int group;
};
int main(){
    myStruct student[5]; // The struct student has an array of 5 elements
    search(student, 1, 33);  // We pass the struct student with all the 5 elements
}

我想把一个结构传递给函数搜索,然后制作一个数组指针,存储某个属性的值,但存储该结构的所有数组的值。

*e指向学生,所有数组(5),所以如果类型等于1,指针将指向结构e 的每个数组的属性的所有值

void search(myStruct *e, int type, int value){
    if (type == 1)  int *ptr[] = e[0]->id;   //An int pointer because the id is an int
    if (type == 2)  int *ptr[] = e[0]->group;
    for (int i = 0; i < 5; i++){
        if(*ptr[i] == value){
           cout << e[i]->name << endl;
           cout << e[i]->id << endl;
           cout << e[i]->group << endl;
        }
    }
}

我希望*ptr[]根据传入类型的参数指向属性的每个数组。例如:

if ( type == 1 )

ptr[0] = e[0].id;
ptr[1] = e[1].id;
ptr[2] = e[2].id;
ptr[3] = e[3].id;
ptr[4] = e[4].id;

^注意这只是id

if ( type == 2 )

ptr[0] = e[0].group;
ptr[1] = e[1].group;
ptr[2] = e[2].group;
ptr[3] = e[3].group;
ptr[4] = e[4].group;

^请注意,这只是一组

问题是我找不到这样做的方法,我的程序中真正的结构不止有三个属性,实际上它有八个,所以如果我为每个属性做一个case,那将是浪费代码。谢谢你的帮助。

实现这一点的一种方法是创建一个"指向成员的指针"。注意:这不是一个指针数组,而是一个只能与类的对象一起使用的指针。

还要注意:这是相当先进的,所以你可能想先把正常的指针直接记在脑子里。

void search(myStruct *e, int type, int value) {
    int myStruct::*ptr;   // ptr is a pointer to a member variable of an object
    if (type == 1)  ptr = &myStruct::id;
    if (type == 2)  ptr = &myStruct::group;
    for (int i = 0; i < 5; i++){
        if (e[i].*ptr == value){          // access the value of the current object using ptr.
            cout << e[i].name << endl;    // Note that you had these accesses wrong.
            cout << e[i].id << endl;
            cout << e[i].group << endl;
        }
    }
}

一种非常破解的方法,它有点低级,只适用于属性相同类型(例如int)并连续存储的POD结构类型。

假设你的结构是这样的:

struct myStruct {
  string name;
  int attr1;
  int attr2;
  ...
  int attr8;
}

你可以把你的搜索功能写如下:

void search(myStruct *e, int type, int value) {
  int *ptr[5];
  for (int i = 0; i < 5; ++i) {
    int *base = &e[i].attr1; // treat attr1...attr8 as an int array
    ptr[i] = &base[type - 1];
    if (*ptr[i] == value) {
      cout << e[i].name << endl;
      for (int j = 0; j < 8; ++j) {
        cout << base[j] << endl;
      }
    }
  }
}