You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CS50 plurality程序报错:'candidate[9]'非结构体/联合体成员引用

CS50第3周计票程序:第65行结构/联合体引用错误修复

错误详情

编译时触发以下错误:

plurality.c:65:25: error: member reference base type 'candidate[9]' is not a structure or union

错误出现在调用mergesort(candidates.votes, 0, MAX-1, candidates.name);语句时。

问题根源

candidates是candidate类型的数组,不是单个结构体实例。.成员访问符仅适用于单个结构体/联合体变量,数组必须通过下标(如candidates[i].votes)访问单个元素的成员。此外,拆分结构体数组的votes和name单独排序会导致两者对应关系错乱——票数与名字无法匹配。

修复步骤

1. 重构排序函数,直接操作结构体数组

修改mergesort和merge的参数,让它们接收candidate数组,基于votes字段排序,同时维护名字与票数的关联:

  • 更新函数原型:
    void merge(candidate arr[], int low, int mid, int high);
    void mergesort(candidate arr[], int low, int high);
    
  • 调整mergesort递归实现:
    void mergesort(candidate arr[], int low, int high)
    {
        int mid;
        if(low < high)
        {
            mid = (low + high) / 2;
            mergesort(arr, low, mid);
            mergesort(arr, mid+1, high);
            merge(arr, low, mid, high);
        }
    }
    
  • 修改merge函数,按票数降序排序并复制完整结构体:
    void merge(candidate arr[], int low, int mid, int high)
    {
        int i = low, j = mid + 1, k = low;
        candidate temp[MAX];
    
        while(i <= mid && j <= high)
        {
            if(arr[i].votes >= arr[j].votes)
            {
                temp[k++] = arr[i++];
            }
            else
            {
                temp[k++] = arr[j++];
            }
        }
    
        while(i <= mid)
            temp[k++] = arr[i++];
        while(j <= high)
            temp[k++] = arr[j++];
    
        for(i = low; i <= high; i++)
            arr[i] = temp[i];
    }
    

2. 修正mergesort调用语句

将错误的调用改为:

mergesort(candidates, 0, candidate_count - 1);

用candidate_count - 1代替MAX-1,避免排序未初始化的候选位置。

3. 修复vote函数的字符串比较错误

CS50的string本质是char*,直接用==比较的是指针地址而非字符串内容,必须用strcmp:

bool vote(string name)
{
    for(int i = 0; i < candidate_count; i++)
    {
        if(strcmp(candidates[i].name, name) == 0)
        {
            candidates[i].votes++;
            return true;
        }
    }
    return false;
}

同时将循环上限从MAX改为candidate_count,避免遍历无效候选位置。

4. 修复print_winner函数的语法与逻辑错误

  • 修正语法错误(缺少分号、错误的成员访问)
  • 调整逻辑:先确定最高票数,再输出所有得票等于最高票数的候选人:
void print_winner(void)
{
    int max_votes = candidates[0].votes;
    for(int i = 1; i < candidate_count; i++)
    {
        if(candidates[i].votes > max_votes)
        {
            max_votes = candidates[i].votes;
        }
    }

    for(int i = 0; i < candidate_count; i++)
    {
        if(candidates[i].votes == max_votes)
        {
            printf("%s\n", candidates[i].name);
        }
    }
}

修改后的完整代码

#include <cs50.h>
#include <stdio.h>
#include <string.h>

void merge(candidate arr[], int low, int mid, int high);
void mergesort(candidate arr[], int low, int high);

// Max number of candidates
#define MAX 9

// Candidates have name and vote count
typedef struct
{
    string name;
    int votes;
}
candidate;

// Array of candidates
candidate candidates[MAX];

// Number of candidates
int candidate_count;

// Function prototypes
bool vote(string name);
void print_winner(void);

int main(int argc, string argv[])
{
    // Check for invalid usage
    if (argc < 2)
    {
        printf("Usage: plurality [candidate ...]\n");
        return 1;
    }

    // Populate array of candidates
    candidate_count = argc - 1;
    if (candidate_count > MAX)
    {
        printf("Maximum number of candidates is %i\n", MAX);
        return 2;
    }
    for (int i = 0; i < candidate_count; i++)
    {
        candidates[i].name = argv[i + 1];
        candidates[i].votes = 0;
    }

    int voter_count = get_int("Number of voters: ");

    // Loop over all voters
    for (int i = 0; i < voter_count; i++)
    {
        string name = get_string("Vote: ");

        // Check for invalid vote
        if (!vote(name))
        {
            printf("Invalid vote.\n");
        }
    }

    mergesort(candidates, 0, candidate_count - 1);

    // Display winner of election
    print_winner();
}

// Update vote totals given a new vote
bool vote(string name)
{
    for(int i = 0; i < candidate_count; i++)
    {
        if(strcmp(candidates[i].name, name) == 0)
        {
            candidates[i].votes++;
            return true;
        }
    }
    return false;
}

// Print the winner (or winners) of the election
void print_winner(void)
{
    int max_votes = candidates[0].votes;
    for(int i = 1; i < candidate_count; i++)
    {
        if(candidates[i].votes > max_votes)
        {
            max_votes = candidates[i].votes;
        }
    }

    for(int i = 0; i < candidate_count; i++)
    {
        if(candidates[i].votes == max_votes)
        {
            printf("%s\n", candidates[i].name);
        }
    }
}

void mergesort(candidate arr[], int low, int high)
{
    int mid;
    if(low < high)
    {
        mid = (low + high) / 2;
        mergesort(arr, low, mid);
        mergesort(arr, mid+1, high);
        merge(arr, low, mid, high);
    }
}

void merge(candidate arr[], int low, int mid, int high)
{
    int i = low, j = mid + 1, k = low;
    candidate temp[MAX];

    while(i <= mid && j <= high)
    {
        if(arr[i].votes >= arr[j].votes)
        {
            temp[k++] = arr[i++];
        }
        else
        {
            temp[k++] = arr[j++];
        }
    }

    while(i <= mid)
        temp[k++] = arr[i++];
    while(j <= high)
        temp[k++] = arr[j++];

    for(i = low; i <= high; i++)
        arr[i] = temp[i];
}

内容的提问来源于stack exchange,提问作者Khurram Qaseem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 07:15:34