如何修复代码使二维数组第二行元素显示正确?
问题:二维数组按对手分数排序后第二行元素全部显示为50
作业要求通过函数操作存储球队分数的二维数组,实现按对手分数(第一行元素)从小到大排序后打印所有分数,但运行代码后第二行所有元素均显示为50,代码如下:
#include <stdio.h> void arrangeScores(int array[][50], int team){ int low = array[0][0], tempArray[2][50], i, j = 0, instance = 1, flag, done = 0; while(done == 0){ //perform while list is being sorted for(i = 1; i < 50; ++i){ //checks for low value skipping flag number if(array[team][i] == -999) continue; else if(array[team][i] < low) low = array[0][i]; else ++instance; //handles duplicates } while(instance != 0){ //loads temp array tempArray[team][j] = low; for(i = 0; i < 50; ++i){ if(array[team][i] == low){ tempArray[team + 1][j] = array[team + 1][i]; array[team][i] = -999; } } ++j; --instance; } instance = 1; flag = 0; for(i = 0; i < 50; ++i){ //checks to see if list is all flags(empty) if(array[team][i] == -999) ++flag; else if(flag == 49) done = 1; } for(i = 0; i < 50; ++i) //updates low to new number if(array[team][i] != -999 && array[team][i] != low){ low = array[team][i]; break; } } for(i = 0; i < 50; ++i){ //reinitalizes origional array from sorted numbers array[team][i] = tempArray[team][i]; array[team + 1][i] = tempArray[team + 1][i]; } } int main(){ int array[2][50]; int j = 0; for(int i = 50; i > 0; --i){ array[0][j] = i; ++j; } for(int i = 0; i < 50; ++i){ array[1][i] = i; } arrangeScores(array, 0); for(int i = 0; i < 50; ++i) printf("%d %d\n", array[0][i], array[1][i]); return 0; }
错误分析
- 函数嵌套定义:
main函数被定义在arrangeScores函数内部,不符合C语言语法规范,会导致编译错误或运行异常。 - 最小值更新错误:寻找最小值时,
low = array[0][i];写死了第一行,逻辑错误,会导致后续最小值更新混乱。 - 重复值统计逻辑错误:
instance的统计方式是“元素不小于当前low则计数”,完全无法正确统计最小值的出现次数,导致tempArray填充逻辑混乱。 tempArray填充逻辑错误:填充tempArray[team+1][j]时,若存在多个相同low值,内层循环会多次覆盖同一个位置;当instance计数错误时,会出现未找到对应元素就填充的情况,产生垃圾值。- 循环结束判断错误:判断数组是否处理完成的逻辑有误,仅当恰好第50个元素不是-999时才触发
done=1,无法正确识别所有元素都已标记的情况。 - 局部数组未初始化:
tempArray是局部数组,未初始化的位置保留随机垃圾值,复制回原数组时会覆盖有效数据。
修复后的代码
改用简洁的选择排序逻辑,直接对二维数组的行进行配对排序,避免复杂的标记和临时数组填充:
#include <stdio.h> void arrangeScores(int array[][50], int team) { int i, j, minIdx; // 选择排序:按team行从小到大排序,同步交换team+1行的对应元素 for (i = 0; i < 49; ++i) { minIdx = i; // 找到当前未排序部分的最小值索引 for (j = i + 1; j < 50; ++j) { if (array[team][j] < array[team][minIdx]) { minIdx = j; } } // 交换team行元素 int temp = array[team][i]; array[team][i] = array[team][minIdx]; array[team][minIdx] = temp; // 同步交换team+1行对应元素 temp = array[team + 1][i]; array[team + 1][i] = array[team + 1][minIdx]; array[team + 1][minIdx] = temp; } } int main() { int array[2][50]; int j = 0; // 初始化第一行为50到1 for (int i = 50; i > 0; --i) { array[0][j] = i; ++j; } // 初始化第二行为0到49 for (int i = 0; i < 50; ++i) { array[1][i] = i; } arrangeScores(array, 0); // 打印排序后的结果 for (int i = 0; i < 50; ++i) { printf("%d %d\n", array[0][i], array[1][i]); } return 0; }
修复说明
- 采用选择排序,每次找到当前未排序部分的最小值索引,同步交换两行对应元素,保证分数与对应数据的配对关系。
- 移除了复杂的标记和临时数组逻辑,代码简洁易读,避免原逻辑中的各类错误。
- 修正了函数嵌套定义的问题,将
main函数移到全局作用域。
内容的提问来源于stack exchange,提问作者Elijah Carnley
相关产品推荐
相关产品推荐

