C 获取对前向声明结构的访问

C 获取对前向声明结构的访问,c,C,我正在维护某人的代码。他们已经把事情真正锁定在不公开头文件中的结构方面。他们已经转发了这些数据结构。我不能更改任何这些,因为它会影响应用程序的其他部分 在我们的驱动程序文件中,我必须使用插入排序创建一个排序例程。这取决于票数。我只是发送我不得不修改的相关部分的代码片段 这是候选实现文件candidate.c gcc 4.5.1 c89 以下是候选头文件candidate.h: struct Candidates_t { int id; char *name; size_

我正在维护某人的代码。他们已经把事情真正锁定在不公开头文件中的结构方面。他们已经转发了这些数据结构。我不能更改任何这些,因为它会影响应用程序的其他部分

在我们的驱动程序文件中,我必须使用插入排序创建一个排序例程。这取决于票数。我只是发送我不得不修改的相关部分的代码片段

这是候选实现文件candidate.c

gcc 4.5.1 c89
以下是候选头文件candidate.h:

struct Candidates_t {
    int id;
    char *name;
    size_t votes;
};

int get_candidate_vote(const Candidates_t *candidates)
{
    return candidates->votes;
}
在驱动程序文件中,我包含了candidate.h文件。然后,我将创建的所有糖果存储到cand_数据结构中

typedef struct Candidates_t Candidates_t;
int get_candidate_vote(const Candidates_t *candidate);
typedef结构候选数据{
大小\u t候选\u数据\u id;
候选人(t)候选人;;
投票人数;
}候选数据;
候选者数据*cand_数据[候选者的数量]={0};
/*这在for循环中运行*/
cand_数据[i]=创建_候选_数据(候选,i);
对于(j=1;j<候选数量;j++){
temp_cand_data=cand_data[j];
k=j-1;
/*获得选票进行比较*/
投票临时=获得候选人投票(临时数据->候选人);
投票权=获得候选人投票权(投票权数据[k]->候选人);
而(k>=0&&vote\u temp候选人);
k=k-1;
}
cand_数据[k+1]=临时cand_数据;
}
然而,为了让上面的排序例程正常工作,我必须创建getter函数来比较每个投票

我希望创建更多的抽象,并将数组传递给candidate.c文件中的排序例程,以返回排序后的数组。但是,候选.c文件不知道driver.c文件中的结构

我只是想知道是否有任何方法可以使这项工作做得更好?还是我应该带着我所做的离开


非常感谢您的建议,

您可以创建定义结构并由需要它的源文件共享的
“candidate\u internal.h”

通常的方法是导出比较两个
候选
的比较函数,而不是直接导出“getter”。在
candidate.c
中:

typedef struct Candidate_data_t {
    size_t candidate_data_id;
    Candidates_t *candidate;
    size_t votes;
} Candidate_data;

Candidate_data *cand_data[NUMBER_OF_CANDIDATES] = {0};
/* This runs in a for loop */
cand_data[i] = create_candidate_data(candidate, i);

for(j = 1; j < NUMBER_OF_CANDIDATES; j++) {
    temp_cand_data = cand_data[j];
    k = j - 1;

    /* Get the votes to compare */
    vote_temp = get_candidate_vote(temp_cand_data->candidate);
    vote_cand = get_candidate_vote(cand_data[k]->candidate);

    while(k >= 0 && vote_temp < vote_cand) {
        cand_data[k + 1] = cand_data[k];
        vote_cand = get_candidate_vote(cand_data[k]->candidate);
        k = k - 1;
    }
    cand_data[k + 1] = temp_cand_data;
}
然后在驱动程序文件中:

/* Returns 1 if `a` is greater than `b`, otherwise 0 */
int compare_candidates(const Candidates_t *a, const Candidates_t *b)
{
    return a->votes > b->votes;
}
for(j=1;j<候选数量;j++){
temp_cand_data=cand_data[j];
k=j-1;
而(k>=0&&compare_候选者(cand_data[k]>candidate,temp_-cand_data->candidate)){
cand_数据[k+1]=cand_数据[k];
k=k-1;
}
cand_数据[k+1]=临时cand_数据;
}
请注意,“驱动程序”文件现在不必知道任何关于“候选文件”内部的信息——它只是一种通用的插入排序,它们的排序顺序完全由
candidate.c
文件定义


作为进一步的改进,您应该考虑使用C库的内置排序函数,
qsort()

如果候选人确实需要封装其内容,您的解决方案实际上听起来是正确的。同意@lijie。这是一个很好的干净方法,您或其他人以后可能会发现
get\u candidate\u vote
的更多用途。您可能会考虑一个小的更改:在数组中找到插入位置并使用
memmove
一次,而不是一次只移动一个结构。@lije。也许,你是对的。我想知道其他的想法。我想再等一段时间,以防有人提出我没有想到的事情@aschelper,我不太清楚如何使用memmove,你能举个简单的例子吗。谢谢。无论如何,你为什么有一个
候选者数据\u t
结构?
投票
id
成员是否与指向的
候选人
中包含的日期冗余?你为什么要使用一种特殊的排序算法呢?@Karl。嗯,我只是在维护离开公司的人的代码,所以才刚刚完成他们开始的工作。但是,删除候选数据会导致源代码出现意外问题,因为它们是使用它的其他部分。谢谢。是的,我已经在我的另一个解决方案中这样做了。我称之为候选者_private.h。谢谢。谢谢,咖啡馆,这就是我想要的建议。我可以永远信任你。谢谢
for(j = 1; j < NUMBER_OF_CANDIDATES; j++) {
    temp_cand_data = cand_data[j];
    k = j - 1;

    while(k >= 0 && compare_candidates(cand_data[k]->candidate, temp_cand_data->candidate)) {
        cand_data[k + 1] = cand_data[k];
        k = k - 1;
    }
    cand_data[k + 1] = temp_cand_data;
}