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
相关产品推荐
相关产品推荐

