【问题标题】:access struct member with a variable or pointer in C在 C 中使用变量或指针访问结构成员
【发布时间】:2018-03-06 22:49:07
【问题描述】:

我有一个结构,并想使用归并排序对该结构的数组进行排序。 我需要将排序参数传递给合并函数并访问结构成员。 这可以在 C 中完成吗?

示例:

struct movie_imdb_data {
    char color[15];
    char director_name[100];
    int num_critic_for_reviews;
    int duration; /// in min not date and time 
    int director_facebook_likes;
    int actor_3_facebook_likes;
    char actor_2_name[100]; 
    int actor_1_facebook_likes;
    int gross;
};

main 函数中,我有:

    if (argc > 2) {
        column_sort = argv[2];
    }

现在我想打电话给merge_sort(<array of struct>, <column_sort *>)

我可以以array[0]->column_sort 的身份访问数组中的成员进行比较吗?

现在我想调用归并排序并通过

我想传递数组和排序参数(我需要对数组进行排序)我可以使用变量代替成员名称,即..

arr[1].column_sort   

而不是

arr[1].color

【问题讨论】:

  • now i want to call merge sort and pass the通过,什么?
  • *argv[]传递的“排序参数”是什么意思?
  • 也许您需要结构中给定成员的偏移量? C 的offsetof() 宏是stddef.h 中的ANSI C 库功能。它计算结构或联合类型中给定成员的偏移量(以字节为单位),作为 size_t 类型的表达式。
  • 我想传递数组和排序参数(我需要排序的数组)我可以使用变量代替成员名称,即.. arr[1].column_sort 而不是 arr [1].颜色

标签: c arrays sorting struct


【解决方案1】:

听起来您想使用命令行参数指定要排序的字段的名称,然后对该字段进行排序。

为此,请尝试以下代码:

#include <stdlib.h>
#include <string.h>

/* compare function for field 3: "num_critic_for_reviews" */    
int compField3(const void *a, const void *b)
{
    struct movie_imdb_data* aStruct = (struct movie_imdb_data*)a;
    struct movie_imdb_data* bStruct = (struct movie_imdb_data*)b;
    return (aStruct->num_critic_for_reviews < bStruct->num_critic_for_reviews)?
        -1: (aStruct->num_critic_for_reviews > bStruct->num_critic_for_reviews)?
            +1: 0;
}

/* also define other compare functions for each field */

int main()
{
    const char* columnName = argv[2];
    struct movie_imdb_data* parray;
    parray = your-array;
    int (*comp)(const void *, const void *, void *) = 0;

    /* map the column name to compare function for that column */
    if (strcmp(columnName, "num_critic_for_reviews") == 0)
    {
        comp = compField3;
    }
    /* map other names to compare function for column */
    else if (...) {...}
    else { exit(1); /* if not recognized column name */ }

    qsort(parray, numElementsOfArray, sizeof(struct movie_imdb_data), comp);
    ...
}

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    有不同的方法可以解决您的问题:

    • 您可以编写单独的函数来比较特定字段的结构。在main 中,您可以通过测试字段名称(或可能不是字段名称的通用名称)来选择适当的比较函数。然后将此比较函数传递给mergesort(或qsort...)。

    • 如果所有成员都具有相同的类型,您可以使用宏offsetof(type, member) 确定字段从结构开头的偏移量。没有通用的方法来计算这些偏移量,您需要编写一系列测试或使用表格。比较函数将使用强制转换来访问成员:

      size_t member_offset = offsetof(struct movie_imdb_data, duration);
      
      int comp_int_member(const void *a1, const void *a2) {
          const int *p1 = (const int *)((const unsigned char*)a1 + member_offset);
          const int *p2 = (const int *)((const unsigned char*)a2 + member_offset);
      
          return (*p1 > *p2) - (*p1 < *p2);
      }
      

      后一种方法的缺点是它只能处理给定类型的字段。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多